1 package org.simantics.databoard.serialization.impl;
\r
3 import gnu.trove.map.hash.TObjectIntHashMap;
\r
5 import java.io.DataInput;
\r
6 import java.io.DataOutput;
\r
7 import java.io.IOException;
\r
8 import java.util.List;
\r
10 import org.simantics.databoard.binding.OptionalBinding;
\r
11 import org.simantics.databoard.binding.error.BindingException;
\r
12 import org.simantics.databoard.binding.util.IsReferableQuery;
\r
13 import org.simantics.databoard.binding.util.Result;
\r
14 import org.simantics.databoard.serialization.SerializationException;
\r
15 import org.simantics.databoard.serialization.Serializer;
\r
16 import org.simantics.databoard.serialization.Serializer.CompositeSerializer;
\r
18 public class OptionalSerializer extends CompositeSerializer {
\r
20 OptionalBinding binding;
\r
21 public Serializer componentSerializer;
\r
22 boolean componentImmutable;
\r
26 * Create optional serializer
\r
29 * @param componentSerializer (optional), can be set after
\r
31 public OptionalSerializer(OptionalBinding binding, Serializer componentSerializer) {
\r
32 super( IsReferableQuery.isReferable( binding.type() ) != Result.No );
\r
33 this.componentSerializer = componentSerializer;
\r
34 this.binding = binding;
\r
35 this.componentImmutable = binding.getComponentBinding().isImmutable();
\r
39 public void finalizeConstruction() {
\r
40 Integer fixedSizeOfComponent = componentSerializer.getConstantSize();
\r
41 if (fixedSizeOfComponent!=null && fixedSizeOfComponent==0) {
\r
42 fixedSize = fixedSizeOfComponent + 1;
\r
47 public Object deserialize(DataInput in, List<Object> identities) throws IOException {
\r
49 byte x = in.readByte();
\r
50 if (x == 0) return binding.createNoValue();
\r
52 Object componentValue = componentSerializer.deserialize(in, identities);
\r
53 return binding.createValue(componentValue);
\r
55 else throw new SerializationException("Unexpected marker for option "+x+" 0 or 1 expected.");
\r
56 } catch (BindingException e) {
\r
57 throw new IOException( e );
\r
62 public void deserializeTo(DataInput in, List<Object> identities,
\r
63 Object obj) throws IOException {
\r
65 byte x = in.readByte();
\r
67 if (binding.hasValue(obj)) binding.setNoValue(obj);
\r
68 } else if (x == 1) {
\r
69 if (componentImmutable) {
\r
70 Object component = componentSerializer.deserialize(in, identities);
\r
71 binding.setValue(obj, component);
\r
73 Object component = binding.hasValue(obj) ? binding.getValue(obj) : binding.componentBinding.createDefault();
\r
74 component = componentSerializer.deserializeToTry(in, identities, component);
\r
75 binding.setValue(obj, component);
\r
79 else throw new SerializationException("Unexpected marker for option "+x+" 0 or 1 expected.");
\r
80 } catch (BindingException e) {
\r
81 throw new IOException( e );
\r
86 public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {
\r
87 int x = in.readByte();
\r
88 if (x==1) componentSerializer.skip(in, identities);
\r
92 public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {
\r
94 if (!binding.hasValue(obj)) {
\r
98 Object componentValue = binding.getValue(obj);
\r
99 componentSerializer.serialize(out, identities, componentValue);
\r
101 } catch (BindingException e) {
\r
102 throw new IOException( e );
\r
108 public Integer getConstantSize() {
\r
113 public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {
\r
115 if (fixedSize!=null) return fixedSize;
\r
116 if (!binding.hasValue(obj)) return 1;
\r
117 Object componentValue = binding.getValue(obj);
\r
118 return 1 + componentSerializer.getSize(componentValue, identities);
\r
119 } catch (BindingException e) {
\r
120 throw new IOException( e );
\r
125 public int getMinSize() {
\r