]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/DefaultSerializerFactory.java
Streaming serialization of values, debugger for corrupted values
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / serialization / DefaultSerializerFactory.java
1 package org.simantics.databoard.serialization;
2
3 import java.util.Map;
4
5 import org.simantics.databoard.binding.ArrayBinding;
6 import org.simantics.databoard.binding.Binding;
7 import org.simantics.databoard.binding.BooleanBinding;
8 import org.simantics.databoard.binding.ByteBinding;
9 import org.simantics.databoard.binding.DoubleBinding;
10 import org.simantics.databoard.binding.FloatBinding;
11 import org.simantics.databoard.binding.IntegerBinding;
12 import org.simantics.databoard.binding.LongBinding;
13 import org.simantics.databoard.binding.MapBinding;
14 import org.simantics.databoard.binding.OptionalBinding;
15 import org.simantics.databoard.binding.RecordBinding;
16 import org.simantics.databoard.binding.StringBinding;
17 import org.simantics.databoard.binding.UnionBinding;
18 import org.simantics.databoard.binding.VariantBinding;
19 import org.simantics.databoard.binding.impl.BooleanArrayBinding;
20 import org.simantics.databoard.binding.impl.ByteArrayBinding;
21 import org.simantics.databoard.binding.impl.DoubleArrayBinding;
22 import org.simantics.databoard.binding.impl.FloatArrayBinding;
23 import org.simantics.databoard.binding.impl.IntArrayBinding;
24 import org.simantics.databoard.binding.impl.LongArrayBinding;
25 import org.simantics.databoard.serialization.impl.ArraySerializer;
26 import org.simantics.databoard.serialization.impl.BooleanArraySerializer;
27 import org.simantics.databoard.serialization.impl.BooleanSerializer;
28 import org.simantics.databoard.serialization.impl.ByteArraySerializer;
29 import org.simantics.databoard.serialization.impl.ByteSerializer;
30 import org.simantics.databoard.serialization.impl.DoubleArraySerializer;
31 import org.simantics.databoard.serialization.impl.DoubleSerializer;
32 import org.simantics.databoard.serialization.impl.FloatArraySerializer;
33 import org.simantics.databoard.serialization.impl.FloatSerializer;
34 import org.simantics.databoard.serialization.impl.GenericRecordSerializer;
35 import org.simantics.databoard.serialization.impl.IntArraySerializer;
36 import org.simantics.databoard.serialization.impl.IntSerializer;
37 import org.simantics.databoard.serialization.impl.LongArraySerializer;
38 import org.simantics.databoard.serialization.impl.LongSerializer;
39 import org.simantics.databoard.serialization.impl.MapSerializer;
40 import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer;
41 import org.simantics.databoard.serialization.impl.MutableVariantSerializer;
42 import org.simantics.databoard.serialization.impl.OptionalSerializer;
43 import org.simantics.databoard.serialization.impl.ReferableRecordSerializer;
44 import org.simantics.databoard.serialization.impl.UnionSerializer;
45 import org.simantics.databoard.serialization.impl.VariantSerializer;
46 import org.simantics.databoard.type.ArrayType;
47 import org.simantics.databoard.type.BooleanType;
48 import org.simantics.databoard.type.ByteType;
49 import org.simantics.databoard.type.DoubleType;
50 import org.simantics.databoard.type.FloatType;
51 import org.simantics.databoard.type.IntegerType;
52 import org.simantics.databoard.type.LongType;
53
54 /**
55  * Default serializer factory creates serializers that follow databoard serialization
56  * specification.
57  * 
58  * <a href="http://dev.simantics.org/index.php/Org.simantics.datatype_Manual#Binary_Serialization">Binary Serialization format</a>
59  *
60  * 
61  * @author Toni Kalajainen
62  */
63 public class DefaultSerializerFactory extends SerializerFactory {
64
65         /**
66          * Construct a new serializer.
67          */
68         public DefaultSerializerFactory() {
69                 super();
70         }
71         
72         /**
73          * Construct a new serializer factory that places constructed serializers
74          * into user given repository.
75          * 
76          * @param repository
77          */
78         public DefaultSerializerFactory(Map<Binding, Serializer> repository) {
79                 super(repository);
80         }       
81
82         @Override
83         protected Serializer doConstruct(Binding binding)
84                         throws SerializerConstructionException {
85             
86             // Specialized serializers
87             if(binding instanceof SpecializedSerializerProvider) {
88                 Serializer specializedSerializer = 
89                     ((SpecializedSerializerProvider)binding).getSpecializedSerializer();
90                 if(specializedSerializer != null)
91                     return specializedSerializer;
92             }
93                 
94                 // Primitives
95                 if (binding instanceof BooleanBinding) return new BooleanSerializer( (BooleanBinding) binding );
96                 if (binding instanceof ByteBinding) return new ByteSerializer( (ByteBinding) binding );
97                 if (binding instanceof IntegerBinding) return new IntSerializer( (IntegerBinding) binding );
98                 if (binding instanceof LongBinding) return new LongSerializer( (LongBinding) binding );
99                 if (binding instanceof FloatBinding) return new FloatSerializer( (FloatBinding) binding );
100                 if (binding instanceof DoubleBinding) return new DoubleSerializer( (DoubleBinding) binding );
101                 if (binding instanceof StringBinding) return new ModifiedUTF8StringSerializer( (StringBinding) binding );
102
103                 // Record
104                 if (binding instanceof RecordBinding) {
105                         RecordBinding b = (RecordBinding) binding;
106                         Binding[] componentBindings = b.getComponentBindings();
107                         int count = b.getComponentCount();
108                         
109                         if ( b.type().isReferable() ) {
110                                 ReferableRecordSerializer result = new ReferableRecordSerializer(b, null);
111                                 inprogress.put(binding, result);                                
112                                 result.componentSerializers = new Serializer[count];
113                                 for (int i=0; i<count; i++) {
114                                         result.componentSerializers[i] = construct( componentBindings[i] );
115                                 }                               
116                                 result.finalizeConstruction();
117                                 inprogress.remove(binding);
118                                 return result;
119                         } else {
120                                 GenericRecordSerializer result = new GenericRecordSerializer(b, null);
121                                 inprogress.put(binding, result);                                
122                                 result.componentSerializers = new Serializer[count];
123                                 for (int i=0; i<count; i++) {
124                                         result.componentSerializers[i] = construct( componentBindings[i] );
125                                 }                               
126                                 result.finalizeConstruction();
127                                 inprogress.remove(binding);
128                                 return result;                                  
129                         }
130                 }               
131                 
132                 // Union
133                 if (binding instanceof UnionBinding) {
134                         UnionBinding b = (UnionBinding) binding;
135                         Binding[] componentBindings = b.getComponentBindings();
136                         int count = b.getComponentCount();
137                         
138                         UnionSerializer result = new UnionSerializer(b, null);
139                         inprogress.put(binding, result);                                
140                         result.componentSerializers = new Serializer[count];
141                         for (int i=0; i<count; i++) {
142                                 result.componentSerializers[i] = construct( componentBindings[i] );
143                         }                               
144                         result.finalizeConstruction();
145                         inprogress.remove(binding);
146                         return result;
147                 }                       
148                 
149                 // Optional
150                 if (binding instanceof OptionalBinding) {
151                         OptionalBinding b = (OptionalBinding) binding;
152                         OptionalSerializer result = new OptionalSerializer(b, null);
153                         inprogress.put(binding, result);
154                         result.componentSerializer = construct( b.getComponentBinding() );
155                         inprogress.remove(binding);
156                         return result;                  
157                 }               
158                 
159                 // Array
160                 if (binding instanceof ArrayBinding) {
161                         ArrayBinding b = (ArrayBinding) binding;
162                         ArrayType type = (ArrayType) b.type();
163                         
164                         if( b instanceof FloatArrayBinding && type.componentType instanceof FloatType )
165                                 return new FloatArraySerializer(b);
166                         if(b instanceof DoubleArrayBinding && type.componentType instanceof DoubleType )
167                                 return new DoubleArraySerializer(b);
168                         if(b instanceof IntArrayBinding && type.componentType instanceof IntegerType )
169                                 return new IntArraySerializer(b);
170                         if(b instanceof ByteArrayBinding && type.componentType instanceof ByteType )
171                                 return new ByteArraySerializer(b);
172                         if(b instanceof BooleanArrayBinding && type.componentType instanceof BooleanType )
173                                 return new BooleanArraySerializer(b);
174                         if(b instanceof LongArrayBinding && type.componentType instanceof LongType )
175                                 return new LongArraySerializer(b);
176                         
177                         ArraySerializer result = new ArraySerializer(b, null);
178                         inprogress.put(binding, result);
179                         result.componentSerializer = construct( b.getComponentBinding() );
180                         result.finalizeConstruction();
181                         inprogress.remove(binding);
182                         return result;                  
183                 }
184                 
185                 // Map
186                 if (binding instanceof MapBinding) {
187                         MapBinding b = (MapBinding) binding;                    
188                         MapSerializer result = new MapSerializer(b, null, null);
189                         inprogress.put(binding, result);
190                         result.keySerializer = construct( b.getKeyBinding() );
191                         result.valueSerializer = construct( b.getValueBinding() );
192                         result.finalizeConstruction();
193                         inprogress.remove(binding);
194                         return result;                  
195                 }               
196                 
197                 // Variant
198                 if (binding instanceof VariantBinding) {
199                         VariantSerializer result = binding.isImmutable() ? new VariantSerializer((VariantBinding)binding, this)
200                                                                          : new MutableVariantSerializer((VariantBinding)binding, this );
201                         result.finalizeConstruction();
202                         return result;
203                 }
204                 
205                 throw new SerializerConstructionException("Cannot serialize "+binding.getClass().getName());
206         }
207
208         @Override
209         public boolean supportsBinding(Binding binding) {
210                 return true;
211         }
212         
213 }