X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Fserialization%2FSerializerFactory.java;fp=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Fserialization%2FSerializerFactory.java;h=51250279aa9f9054c91962f70e8052b57603e73b;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/SerializerFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/SerializerFactory.java new file mode 100644 index 000000000..51250279a --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/SerializerFactory.java @@ -0,0 +1,107 @@ +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); + } + } + + +}