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