]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/mutable/MutableVariant.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / mutable / MutableVariant.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/mutable/MutableVariant.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/mutable/MutableVariant.java
new file mode 100644 (file)
index 0000000..0d6b6f1
--- /dev/null
@@ -0,0 +1,148 @@
+/*******************************************************************************\r
+ *  Copyright (c) 2010 Association for Decentralized Information Management in\r
+ *  Industry THTH ry.\r
+ *  All rights reserved. This program and the accompanying materials\r
+ *  are made available under the terms of the Eclipse Public License v1.0\r
+ *  which accompanies this distribution, and is available at\r
+ *  http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ *  Contributors:\r
+ *      VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.databoard.binding.mutable;
+
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.InvalidObjectException;\r
+import java.io.ObjectStreamException;\r
+import java.io.Serializable;\r
+\r
+import org.simantics.databoard.Accessors;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
+import org.simantics.databoard.accessor.error.AccessorException;\r
+import org.simantics.databoard.accessor.java.JavaObject;\r
+import org.simantics.databoard.accessor.reference.ChildReference;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.reflection.VoidBinding;\r
+import org.simantics.databoard.type.Datatype;\r
+
+/**
+ * MutableVariant is a container to a data value of any type. 
+ * The value and type can be changed. 
+ *
+ * MutableVariant is hash-equals-comparable, even variants of bindings (and types). 
+ * The hash function and comparison rules are defined in the manual.   
+ *\r
+ * @see MutableVariantBinding is binding for Variant-class
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
+ */
+public class MutableVariant extends Variant implements Serializable, Cloneable {
+       
+       private static final long serialVersionUID = 1L;
+       \r
+       public static MutableVariant ofInstance(Object instance) {\r
+               Binding binding = Bindings.getBindingUnchecked( instance.getClass() );\r
+               return new MutableVariant(binding, instance);\r
+       }\r
+       \r
+       /**\r
+        * Constract a variant with a default value of empty record {}\r
+        */
+       public MutableVariant() {\r
+               binding = VoidBinding.VOID_BINDING;\r
+               value = null;\r
+       }\r
+       
+       public MutableVariant(Variant v) {\r
+//             assert(isValid(binding, value));\r
+               this.binding = v.getBinding();\r
+               this.value = v.getValue();\r
+       }       \r
+       
+       public MutableVariant(Binding binding, Object value) {
+//             assert(isValid(binding, value));
+               this.binding = binding;
+               this.value = value;
+       }
+       \r
+       /**\r
+        * Set value and binding from a variant. This method takes the references, \r
+        * and does not clone the value.\r
+        * \r
+        * @param v source variant\r
+        */
+       public void setValue(Variant v) {\r
+               this.binding = v.getBinding();\r
+               this.value = v.getValue();\r
+       }\r
+       
+       public void setValue(Binding binding, Object newValue) {
+//             assert(isValid(binding, newValue));
+               this.binding = binding;
+               this.value = newValue;
+       }\r
+       \r
+       public void readFrom(Binding binding, Object newValue) throws BindingException {\r
+               if (binding.isImmutable()) {\r
+                       this.binding = binding;\r
+                       this.value = newValue;\r
+                       return;\r
+               }\r
+                               \r
+               if (this.binding == binding) {\r
+                       binding.readFrom(binding, newValue, this.value);\r
+               } else {\r
+                       try {\r
+                               this.value = binding.clone( newValue );\r
+                               this.binding = binding;\r
+                       } catch (AdaptException e) {\r
+                               throw new BindingException( e );\r
+                       }\r
+               }\r
+       }
+\r
+       public MutableVariant clone() {\r
+               if (binding.isImmutable()) return new MutableVariant(binding, value);\r
+               Object newValue = Bindings.cloneUnchecked(value, binding, binding);\r
+               return new MutableVariant(binding, newValue);\r
+       }\r
+       
+       private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+               Binding dataTypeBinding = Bindings.getBindingUnchecked( Datatype.class );
+               Bindings.getSerializerUnchecked( dataTypeBinding ).serialize(type());
+               Bindings.getSerializerUnchecked( binding ).serialize(value, out);
+       }
+       
+       private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+               Binding dataTypeBinding = Bindings.getBindingUnchecked( Datatype.class );
+               Datatype type = (Datatype) Bindings.getSerializerUnchecked( dataTypeBinding ).deserialize((InputStream)in);
+               Binding binding = Bindings.getMutableBinding(type);
+               Object value = Bindings.getSerializerUnchecked( binding ).deserialize((InputStream)in);
+               this.binding = binding;
+               this.value = value;
+       }
+       
+       @SuppressWarnings("unused")
+       private void readObjectNoData() throws ObjectStreamException {
+               throw new InvalidObjectException("Don't know how to instantiate "+type()+" with no data");              
+       }
+       
+       public MutableVariant getComponent(ChildReference ref) throws AccessorConstructionException {\r
+               if ( ref == null ) return this;\r
+               JavaObject jo = (JavaObject) Accessors.getAccessor(this, ref);\r
+               return new MutableVariant( jo.getBinding(), jo.getObject() );\r
+       }\r
+       \r
+       public void setComponent(ChildReference ref, Binding binding, Object value) throws AccessorException, AccessorConstructionException {\r
+        if ( ref == null ) {\r
+            setValue( binding, value );\r
+        }\r
+        else {\r
+            JavaObject jo = (JavaObject) Accessors.getAccessor(this, ref);\r
+            jo.setValue( ref, binding, value );\r
+        }\r
+       }\r
+}