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