--- /dev/null
+package org.simantics.databoard.serialization;\r
+\r
+import java.util.Map;\r
+\r
+import org.simantics.databoard.binding.ArrayBinding;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.BooleanBinding;\r
+import org.simantics.databoard.binding.ByteBinding;\r
+import org.simantics.databoard.binding.DoubleBinding;\r
+import org.simantics.databoard.binding.FloatBinding;\r
+import org.simantics.databoard.binding.IntegerBinding;\r
+import org.simantics.databoard.binding.LongBinding;\r
+import org.simantics.databoard.binding.MapBinding;\r
+import org.simantics.databoard.binding.OptionalBinding;\r
+import org.simantics.databoard.binding.RecordBinding;\r
+import org.simantics.databoard.binding.StringBinding;\r
+import org.simantics.databoard.binding.UnionBinding;\r
+import org.simantics.databoard.binding.VariantBinding;\r
+import org.simantics.databoard.binding.impl.BooleanArrayBinding;\r
+import org.simantics.databoard.binding.impl.ByteArrayBinding;\r
+import org.simantics.databoard.binding.impl.DoubleArrayBinding;\r
+import org.simantics.databoard.binding.impl.FloatArrayBinding;\r
+import org.simantics.databoard.binding.impl.IntArrayBinding;\r
+import org.simantics.databoard.binding.impl.LongArrayBinding;\r
+import org.simantics.databoard.serialization.impl.ArraySerializer;\r
+import org.simantics.databoard.serialization.impl.BooleanArraySerializer;\r
+import org.simantics.databoard.serialization.impl.BooleanSerializer;\r
+import org.simantics.databoard.serialization.impl.ByteArraySerializer;\r
+import org.simantics.databoard.serialization.impl.ByteSerializer;\r
+import org.simantics.databoard.serialization.impl.DoubleArraySerializer;\r
+import org.simantics.databoard.serialization.impl.DoubleSerializer;\r
+import org.simantics.databoard.serialization.impl.FloatArraySerializer;\r
+import org.simantics.databoard.serialization.impl.FloatSerializer;\r
+import org.simantics.databoard.serialization.impl.GenericRecordSerializer;\r
+import org.simantics.databoard.serialization.impl.IntArraySerializer;\r
+import org.simantics.databoard.serialization.impl.IntSerializer;\r
+import org.simantics.databoard.serialization.impl.LongArraySerializer;\r
+import org.simantics.databoard.serialization.impl.LongSerializer;\r
+import org.simantics.databoard.serialization.impl.MapSerializer;\r
+import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer;\r
+import org.simantics.databoard.serialization.impl.MutableVariantSerializer;\r
+import org.simantics.databoard.serialization.impl.OptionalSerializer;\r
+import org.simantics.databoard.serialization.impl.ReferableRecordSerializer;\r
+import org.simantics.databoard.serialization.impl.UnionSerializer;\r
+import org.simantics.databoard.serialization.impl.VariantSerializer;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.BooleanType;\r
+import org.simantics.databoard.type.ByteType;\r
+import org.simantics.databoard.type.DoubleType;\r
+import org.simantics.databoard.type.FloatType;\r
+import org.simantics.databoard.type.IntegerType;\r
+import org.simantics.databoard.type.LongType;\r
+\r
+/**\r
+ * Default serializer factory creates serializers that follow databoard serialization\r
+ * specification.\r
+ * \r
+ * <a href="http://dev.simantics.org/index.php/Org.simantics.datatype_Manual#Binary_Serialization">Binary Serialization format</a>\r
+ *\r
+ * \r
+ * @author Toni Kalajainen\r
+ */\r
+public class DefaultSerializerFactory extends SerializerFactory {\r
+\r
+ /**\r
+ * Construct a new serializer.\r
+ */\r
+ public DefaultSerializerFactory() {\r
+ super();\r
+ }\r
+ \r
+ /**\r
+ * Construct a new serializer factory that places constructed serializers\r
+ * into user given repository.\r
+ * \r
+ * @param repository\r
+ */\r
+ public DefaultSerializerFactory(Map<Binding, Serializer> repository) {\r
+ super(repository);\r
+ } \r
+\r
+ @Override\r
+ protected Serializer doConstruct(Binding binding)\r
+ throws SerializerConstructionException {\r
+ \r
+ // Specialized serializers\r
+ if(binding instanceof SpecializedSerializerProvider) {\r
+ Serializer specializedSerializer = \r
+ ((SpecializedSerializerProvider)binding).getSpecializedSerializer();\r
+ if(specializedSerializer != null)\r
+ return specializedSerializer;\r
+ }\r
+ \r
+ // Primitives\r
+ if (binding instanceof BooleanBinding) return new BooleanSerializer( (BooleanBinding) binding );\r
+ if (binding instanceof ByteBinding) return new ByteSerializer( (ByteBinding) binding );\r
+ if (binding instanceof IntegerBinding) return new IntSerializer( (IntegerBinding) binding );\r
+ if (binding instanceof LongBinding) return new LongSerializer( (LongBinding) binding );\r
+ if (binding instanceof FloatBinding) return new FloatSerializer( (FloatBinding) binding );\r
+ if (binding instanceof DoubleBinding) return new DoubleSerializer( (DoubleBinding) binding );\r
+ if (binding instanceof StringBinding) return new ModifiedUTF8StringSerializer( (StringBinding) binding );\r
+\r
+ // Record\r
+ if (binding instanceof RecordBinding) {\r
+ RecordBinding b = (RecordBinding) binding;\r
+ Binding[] componentBindings = b.getComponentBindings();\r
+ int count = b.getComponentCount();\r
+ \r
+ if ( b.type().isReferable() ) {\r
+ ReferableRecordSerializer result = new ReferableRecordSerializer(b, null);\r
+ inprogress.put(binding, result); \r
+ result.componentSerializers = new Serializer[count];\r
+ for (int i=0; i<count; i++) {\r
+ result.componentSerializers[i] = construct( componentBindings[i] );\r
+ } \r
+ result.finalizeConstruction();\r
+ inprogress.remove(binding);\r
+ return result;\r
+ } else {\r
+ GenericRecordSerializer result = new GenericRecordSerializer(b, null);\r
+ inprogress.put(binding, result); \r
+ result.componentSerializers = new Serializer[count];\r
+ for (int i=0; i<count; i++) {\r
+ result.componentSerializers[i] = construct( componentBindings[i] );\r
+ } \r
+ result.finalizeConstruction();\r
+ inprogress.remove(binding);\r
+ return result; \r
+ }\r
+ } \r
+ \r
+ // Union\r
+ if (binding instanceof UnionBinding) {\r
+ UnionBinding b = (UnionBinding) binding;\r
+ Binding[] componentBindings = b.getComponentBindings();\r
+ int count = b.getComponentCount();\r
+ \r
+ UnionSerializer result = new UnionSerializer(b, null);\r
+ inprogress.put(binding, result); \r
+ result.componentSerializers = new Serializer[count];\r
+ for (int i=0; i<count; i++) {\r
+ result.componentSerializers[i] = construct( componentBindings[i] );\r
+ } \r
+ result.finalizeConstruction();\r
+ inprogress.remove(binding);\r
+ return result;\r
+ } \r
+ \r
+ // Optional\r
+ if (binding instanceof OptionalBinding) {\r
+ OptionalBinding b = (OptionalBinding) binding;\r
+ OptionalSerializer result = new OptionalSerializer(b, null);\r
+ inprogress.put(binding, result);\r
+ result.componentSerializer = construct( b.getComponentBinding() );\r
+ inprogress.remove(binding);\r
+ return result; \r
+ } \r
+ \r
+ // Array\r
+ if (binding instanceof ArrayBinding) {\r
+ ArrayBinding b = (ArrayBinding) binding;\r
+ ArrayType type = (ArrayType) b.type();\r
+ \r
+ if( b instanceof FloatArrayBinding && type.componentType instanceof FloatType )\r
+ return new FloatArraySerializer(b);\r
+ if(b instanceof DoubleArrayBinding && type.componentType instanceof DoubleType )\r
+ return new DoubleArraySerializer(b);\r
+ if(b instanceof IntArrayBinding && type.componentType instanceof IntegerType )\r
+ return new IntArraySerializer(b);\r
+ if(b instanceof ByteArrayBinding && type.componentType instanceof ByteType )\r
+ return new ByteArraySerializer(b);\r
+ if(b instanceof BooleanArrayBinding && type.componentType instanceof BooleanType )\r
+ return new BooleanArraySerializer(b);\r
+ if(b instanceof LongArrayBinding && type.componentType instanceof LongType )\r
+ return new LongArraySerializer(b);\r
+ \r
+ ArraySerializer result = new ArraySerializer(b, null);\r
+ inprogress.put(binding, result);\r
+ result.componentSerializer = construct( b.getComponentBinding() );\r
+ result.finalizeConstruction();\r
+ inprogress.remove(binding);\r
+ return result; \r
+ }\r
+ \r
+ // Map\r
+ if (binding instanceof MapBinding) {\r
+ MapBinding b = (MapBinding) binding; \r
+ MapSerializer result = new MapSerializer(b, null, null);\r
+ inprogress.put(binding, result);\r
+ result.keySerializer = construct( b.getKeyBinding() );\r
+ result.valueSerializer = construct( b.getValueBinding() );\r
+ result.finalizeConstruction();\r
+ inprogress.remove(binding);\r
+ return result; \r
+ } \r
+ \r
+ // Variant\r
+ if (binding instanceof VariantBinding) {\r
+ VariantSerializer result = binding.isImmutable() ? new VariantSerializer((VariantBinding)binding, this)\r
+ : new MutableVariantSerializer((VariantBinding)binding, this );\r
+ result.finalizeConstruction();\r
+ return result;\r
+ }\r
+ \r
+ throw new SerializerConstructionException("Cannot serialize "+binding.getClass().getName());\r
+ }\r
+\r
+ @Override\r
+ public boolean supportsBinding(Binding binding) {\r
+ return true;\r
+ }\r
+ \r
+}\r