package org.simantics.databoard.serialization; import java.util.HashMap; import java.util.Map; import org.simantics.databoard.binding.Binding; /** * * * @author Toni Kalajainen */ public abstract class SerializerFactory implements SerializerScheme { /** * Map of failed constructions. */ protected Map failures = new HashMap(); /** * Repository where serializers are placed. */ Map repository; /** * Map that contains in incomplete constructions. */ Map inprogress = new HashMap(); /** * Construct a new serializer. */ public SerializerFactory() { this.repository = new HashMap(); } /** * Construct a new serializer factory that places constructed serializers * into user given repository. * * @param repository */ public SerializerFactory(Map repository) { this.repository = repository; } public Map getRepository() { return repository; } /** * Constructs a serilizer for a binding. Implement this. * It should use the inprogress -map for construction of * serializers that have component types. * * e.g. * inprogress.put(binding, notCompletelyConstructedSerializer); * Serializer componentSerializer = construct( componentBinding ); * notCompletelyConstructedSerializer.setComponent( componentSerializer ); * inprogress.remove(binding); * * try-finally is not needed. * * @param request * @return * @throws SerializerConstructionException */ protected abstract Serializer doConstruct(Binding request) throws SerializerConstructionException; public Serializer construct(Binding request) throws SerializerConstructionException { // Optimization: if binding provides a cached serializer, just return it. { Serializer ser = request.cachedSerializer(); if (ser != null) return ser; } { Serializer ser = repository.get(request); if(ser != null) return ser; } { Serializer ser = inprogress.get(request); if(ser != null) return ser; } { SerializerConstructionException e = failures.get(request); if(e != null) throw e; } // Start construction try { Serializer binding = doConstruct(request); repository.put(request, binding); request.cacheSerializer(binding); return binding; } catch (SerializerConstructionException e) { inprogress.remove( request ); failures.put(request, e); throw e; } } @Override public Serializer getSerializer(Binding binding) throws SerializerConstructionException { return construct(binding); } public Serializer getSerializerUnchecked(Binding binding) throws RuntimeSerializerConstructionException { try { return construct(binding); } catch (SerializerConstructionException e) { throw new RuntimeSerializerConstructionException(e); } } }