]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/VariantSerializer.java
isImmutable can NPE
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / serialization / impl / VariantSerializer.java
1 package org.simantics.databoard.serialization.impl;
2
3 import gnu.trove.map.hash.TObjectIntHashMap;
4
5 import java.io.DataInput;
6 import java.io.DataOutput;
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.List;
10
11 import org.simantics.databoard.Bindings;
12 import org.simantics.databoard.binding.Binding;
13 import org.simantics.databoard.binding.VariantBinding;
14 import org.simantics.databoard.binding.error.BindingException;
15 import org.simantics.databoard.serialization.Serializer;
16 import org.simantics.databoard.serialization.Serializer.RecursiveSerializer;
17 import org.simantics.databoard.serialization.SerializerScheme;
18 import org.simantics.databoard.type.Datatype;
19
20 /**
21  * Serializes Variant instances using bindings from Bindings.getBinding for
22  * deserialization. These are assumed to be immutable bindings.
23  * 
24  * @author Toni Kalajainen
25  */
26 public class VariantSerializer extends RecursiveSerializer {
27         
28         VariantBinding binding;
29         Serializer datatypeSerializer;          
30         SerializerScheme scheme;
31         
32         public VariantSerializer(VariantBinding binding, SerializerScheme scheme) {                     
33                 this.binding = binding;                 
34                 this.scheme = scheme;
35         }
36         
37         @Override
38         public void finalizeConstruction() {
39                 Binding dataTypeBinding = Bindings.getBindingUnchecked( Datatype.class );
40                 this.datatypeSerializer = scheme.getSerializerUnchecked(dataTypeBinding);
41         }
42
43         @Override
44         public Object deserialize(DataInput in, List<Object> identities) throws IOException {                   
45                 try {
46                         List<Object> typeIdentities = new ArrayList<Object>(1);
47                         Datatype type = (Datatype) datatypeSerializer.deserialize(in, typeIdentities);
48                         Binding valueBinding = Bindings.getBinding(type);
49                         Serializer valueSerializer = scheme.getSerializerUnchecked(valueBinding);
50                         assertRemainingBytes(in, valueSerializer.getMinSize());
51                         Object value = valueSerializer.deserialize(in, identities);
52                         return binding.create(valueBinding, value);
53                 } catch (BindingException e) {
54                         throw new IOException( e ); 
55                 }
56         }
57         
58         @Override
59         public void deserializeTo(DataInput in, List<Object> identities, Object obj) throws IOException {
60                 try {
61                         List<Object> typeIdentities = new ArrayList<Object>(1);                         
62                         Datatype type = (Datatype) datatypeSerializer.deserialize(in, typeIdentities);
63                         Datatype oldType = binding.getContentType(obj);
64                 
65                         if (type.equals(oldType)) {
66                                 Binding valueBinding = binding.getContentBinding(obj);
67                                 Serializer valueSerializer = scheme.getSerializerUnchecked(valueBinding);
68                                 Object component = binding.getContent(obj);
69 //                              assertRemainingBytes(in, valueSerializer.getMinSize());
70                                 component = valueSerializer.deserializeToTry(in, identities, component);
71                                 binding.setContent(obj, valueBinding, component);
72                         } else {
73                                 Binding valueBinding = Bindings.getBinding(type);
74                                 Serializer valueSerializer = scheme.getSerializerUnchecked(valueBinding);
75 //                              assertRemainingBytes(in, valueSerializer.getMinSize());
76                                 Object component = valueSerializer.deserialize(in, identities);
77                                 binding.setContent(obj, valueBinding, component);
78                         }
79                 } catch (BindingException e) {
80                         throw new IOException( e ); 
81                 }
82         }
83
84         @Override
85         public void skip(DataInput in, List<Object> identities) throws IOException {
86                 List<Object> typeIdentities = new ArrayList<Object>(1);                         
87                 Datatype type = (Datatype) datatypeSerializer.deserialize(in, typeIdentities);                          
88                 Binding valueBinding = Bindings.getBinding(type);
89                 Serializer valueSerializer = scheme.getSerializerUnchecked(valueBinding);
90                 valueSerializer.skip(in, identities);
91         }               
92         
93         @Override
94         public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object variant) throws IOException {
95                 try {
96                         TObjectIntHashMap<Object> typeIdentities = new TObjectIntHashMap<Object>(1);
97                         Datatype type = binding.getContentType(variant);
98                         datatypeSerializer.serialize(out, typeIdentities, type);                                
99                                 
100                         Binding valueBinding = binding.getContentBinding(variant);
101                         Object value = binding.getContent(variant, valueBinding);
102                                 
103                         Serializer valueSerializer = scheme.getSerializerUnchecked(valueBinding);
104                         valueSerializer.serialize(out, identities, value);
105                 } catch (BindingException e) {
106                         throw new IOException( e ); 
107                 }
108         }
109
110         @Override
111         public Integer getConstantSize() {                      
112                 return null;
113         }
114
115         @Override
116         public int getSize(Object variant, TObjectIntHashMap<Object> identities) throws IOException 
117         {
118                 try {
119                         TObjectIntHashMap<Object> typeIdentities = new TObjectIntHashMap<Object>(1);
120                         Datatype type = binding.getContentType(variant);
121                         int size = datatypeSerializer.getSize(type, typeIdentities);
122                                 
123                         Binding valueBinding = binding.getContentBinding(variant);
124                         Object value = binding.getContent(variant, valueBinding);
125                                 
126                         Serializer valueSerializer = scheme.getSerializerUnchecked(valueBinding);
127                         size += valueSerializer.getSize(value, identities);
128                         return size;
129                 } catch (BindingException e) {
130                         throw new IOException( e ); 
131                 }
132         }
133         
134         @Override
135         public int getMinSize() {
136                 return datatypeSerializer.getMinSize();
137         }
138         
139 }