X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc-isv%2Fdoc%2Fbinding.mediawiki;fp=bundles%2Forg.simantics.databoard%2Fsrc-isv%2Fdoc%2Fbinding.mediawiki;h=157935b2e9b8ea1ddae5130a224ef4c43eeea729;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.databoard/src-isv/doc/binding.mediawiki b/bundles/org.simantics.databoard/src-isv/doc/binding.mediawiki new file mode 100644 index 000000000..157935b2e --- /dev/null +++ b/bundles/org.simantics.databoard/src-isv/doc/binding.mediawiki @@ -0,0 +1,382 @@ +=Binding= +Binding is a mechanism for mapping a Java Class to a Datatype. +For example, take a java.lang.Double. The instance is a container (private final double value;) for the data and its Binding (DoubleBinding) is a way to access the data (.valueOf(), .getDouble()). + Java Object + Binding = Databoard Value + +Bindings have the exact same composition tree structure as its respective Datatype - structural types have structural Bindings, and primitive types a single binding. To acquire a binding, the developer can use a utility that creates one using Java reflection functions. +
+    Binding binding = Binding.getBinding( Double.class );
+
+ +Sometimes classes cannot bound using automatic tool, for instance when using 3rd party classes which cannot be modified. The developer must then write binding self by sub-classing on of the 13 base binding classes (There is a base binding class for each Datatype). +
+    Binding binding = new RecordBinding() { ... };
+
+ +'''[../javadoc/org/simantics/databoard/binding|org.simantics.databoard.binding]'''. +{| style="background-color: #f9f9f9; border: 1px solid #aaaaaa; " +|- style="background-color: #e9e9e9; " | +| '''Class''' || '''Description''' +|- +| [../javadoc/org/simantics/databoard/binding/DataBinding.html|DataBinding] +| Base class for all data Bindings +|- +| [../javadoc/org/simantics/databoard/binding/RecordBinding.html|RecordBinding] +| Record +|- +| [../javadoc/org/simantics/databoard/binding/ArrayBinding.html|ArrayBinding] +| Array - an ordered sequence of elements of one value. +|- +| [../javadoc/org/simantics/databoard/binding/MapBinding.html|MapBinding] +| Map - an ''ordered'' map of keys to values. +|- +| [../javadoc/org/simantics/databoard/binding/UnionBinding.html|UnionBinding] +| Union +|- +| [../javadoc/org/simantics/databoard/binding/BooleanBinding.html|BooleanBinding],[../javadoc/org/simantics/databoard/binding/IntBinding.html|IntBinding],[../javadoc/org/simantics/databoard/binding/LongBinding.html|LongBinding],[../javadoc/org/simantics/databoard/binding/FloatBinding.html|FloatBinding],[../javadoc/org/simantics/databoard/binding/DoubleBinding.html|DoubleBinding] +| Primitive and numeric Bindings +|- +| [../javadoc/org/simantics/databoard/binding/StringBinding.html|StringBinding] +| String +|- +| [../javadoc/org/simantics/databoard/binding/OptionalBinding.html|OptionalBinding] +| Optional value +|- +| [../javadoc/org/simantics/databoard/binding/VariantBinding.html|VariantBinding] +| Variant value +|} + + +Binding can be acquired or created using one of the following methods: +* Constructor +* Constant +* Reflection-Read from a Class +* Created using [../javadoc/org/simantics/databoard/bindingscheme/BindingScheme.html|BindingScheme] +
+    Binding binding = new DoubleBinding( doubleType );
+    Binding binding = new RecordBinding() { ... };
+    Binding binding = Bindings.DOUBLE;
+    Binding binding = Binding.getBinding( Double.class );
+    Binding binding = Binding.getBinding( Datatypes.DOUBLE );
+
+ +==Reflection== +'''Data Type and Binding can be read automatically from a Class by utility.''' +
+    Datatype type = Datatypes.getDatatype( Foo.class );
+    Binding binding = Bindings.getBinding( Foo.class );
+
+ +Bindings for generics classes can be created by passing arguments. +
+    Binding e = Bindings.getBinding(List.class, String.class);
+    List list = (List) e.createRandom(5);
+
+    Binding binding = Bindings.getBinding( Map.class, Integer.class, Integer.class );
+    Map value = (Map) binding.createDefault();
+
+ +Even cascading generics... +
+    Binding e = Bindings.getBinding(List.class, List.class, String.class);
+    List> listList = (List>) e.createRandom(5);
+
+ +'''Classes are RecordTypes''' +
+    class Foo {
+        public int x, y, z;
+    }
+
+Is a binding to the following Datatype +
+    type Foo = { x : Integer, y : Integer, z : Integer }
+
+ +'''There are three types of classes supported, and therefore three ways how objects are constructed.''' +If you create binding for your class with Bindings#getBinding( clazz ), the class must adhere one of these format. You may have to add annotations such as @Recursive, @Optional, @Arguments. + +''Record-like classes:'' +
+    class Foo {
+        public String name;
+        public Object value;
+    }
+
+ +''Immutable classes:'' +
+    class Foo {
+        private String name;
+        private Object value;
+        
+        public Foo(String name, Object value) {
+            this.name = name;
+            this.value = value;
+        }
+        
+        public String getName() {
+            return name;
+        }
+        
+        public Object getValue() {
+            return value;
+        }
+        
+    }
+
+ +''Bean-like classes:'' +
+    class Foo {
+        private String name;
+        private Object value;
+        
+        public void setName(String name) {
+            this.name = name;
+        }
+        
+        public void setValue(Object value) {
+            this.value = value;
+        }
+        
+        public String getName() {
+            return name;
+        }
+        
+        public Object getValue() {
+            return value;
+        }
+        
+    }
+
+    static final long serialVersionUID = -3387516993124229943L;
+    transient int hashCode;
+
+ +'''Enumerations are Union Types''' +
+    enum Cars { Ferrari, Porche, Lamborghini, Jaguar }
+
+is interpreted as union type + type Cars = | Ferrari | Porche | Lamborghini | Jaguar + +If you cannot modify the class, you have to create binding for it by subclassing base binding classes, eg. RecordBinding. + +'''Other exceptions:''' +*java.lang.Object is Variant. +*java.lang.Set is Map(T, {}). +*java.lang.TreeSet is Map(T, {}). +*java.lang.HashSet is Map(T, {}). (Note HashSet binding has very low performance.) +*java.lang.Map is Map(K, V). +*java.lang.TreeMap is Map(K, V). +*java.lang.HashMap is Map(K, V). (Note HashMap binding has very low performance.) +*java.lang.List is Array(T). +*java.lang.ArrayList is Array(T). +*java.lang.LinkedList is Array(T). +*void is {}. +*The stacktrace of Exception.class is omited. + +===Annotations=== +Java Classes / Fields can be annotated with the following annotations ('''[../javadoc/org/simantics/databoard/annotations/|org.simantics.databoard.annotations]]'''). + + +'''UnionTypes are abstract classes or interfaces with @Union annotation.''' +
+    @Union({A.class, B.class}) interface Union1 {		
+    }
+    
+    class A implements Union1 {
+        public int value;
+    }
+    
+    class B implements Union1 {
+        public String name;
+    }
+
+ +'''@Referable denotes that the class has recursion and is a referable record.''' +
+    public @Referable class Node {
+        public Node[] children;
+    }
+
+ +'''Fields that can have null value have @Optional annotation.''' +
+    @Optional String name;
+
+ +'''String valid values are set with @Pattern as regular expression. ([http://en.wikipedia.org/wiki/Regular_expression])''' +
+    String @Pattern("(19|20)\\d\\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])") date;
+    
+    type Date = String( Pattern = "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" )
+
+ +'''String content type is set with a @MIMEType. ([http://en.wikipedia.org/wiki/Mime_type MIME Type])''' +
+    @MIMEType("text/xml") String document;
+
+ +'''Array size restricted with @Length.''' +
+    @Length("[0..10]") int[] array;
+    @Length({"[320]", "[240]"}) int[][] image;
+
+ +'''Valid numeric range is set with @Range.''' +
+    @Range("[0..100]") double alpha;
+    @Range("[0..]" double length;
+
+ +'''Range and Length notation:''' +*Exact Value "0" +*Exclude all "()" +*Unlimited "[..]" +*Inclusive range "[0..100]" +*Exclusive range "(0..100)" +*Inclusive lower bound and exclusive upper bound "[0..100)" + + +'''Engineering unit type is given with @Unit.''' +
+    @Unit("km/h") double maxVelocity;
+
+ +'''The serializer generated with reflection can be overriden with @SpecializedSerializer''' +
+    @SpecializedSerializer(MySerializer.class) 
+    public class MyRecord {
+        ...
+    }
+
+ +== Mapping Scheme == +A ''binding scheme'' associates some data types with a unique binding. The mapping of types to bindings is bijective, there is one binding for each type and vice-versa. + +DefaultBindingScheme is a scheme that converts any datatype to a binding. It prefers java.lang.X primitives. +The Class mapping for each type is listed below. +{| style="background-color: #f9f9f9; border: 1px solid #aaaaaa; " +|- style="background-color: #e9e9e9; +| '''Type''' || '''Class''' +|- +| BooleanType || Boolean.class +|- +| ByteType || Byte.class +|- +| FloatType || Float.class +|- +| DoubleType || eDouble.class +|- +| IntegerType || Integer.class +|- +| LongType || Long.class +|- +| StringType || String.class +|- +| UnionType || TaggedObject.class +|- +| OptionType || ValueContainer.class +|- +| RecordType || Object[].class +|- +| ArrayType || ArrayList.class +|- +| Array(Byte) || byte[].class +|- +| MapType || TreeMap.class +|- +| VariantType || Variant.class +|} + +MutableBindingScheme is a scheme that provides a fully implementing mutable binding for all data types. +The Class mapping for each type is listed below. + +{| style="background-color: #f9f9f9; border: 1px solid #aaaaaa; " +|- style="background-color: #e9e9e9; " | +| '''Type''' || '''Class''' +|- +| BooleanType || MutableBoolean.class +|- +| ByteType || MutableByte.class +|- +| FloatType || MutableFloat.class +|- +| DoubleType || MutableDouble.class +|- +| IntegerType || MutableInt.class +|- +| LongType || MutableLong.class +|- +| StringType || MutableString.class +|- +| UnionType || TaggedObject.class +|- +| OptionType || ValueContainer.class +|- +| RecordType || Object[].class +|- +| ArrayType || ArrayList.class +|- +| MapType || TreeMap.class +|- +| VariantType || Variant.class +|} + + +===Serialization=== +[../javadoc/org/simantics/databoard/serialization/binary/Serializer.html|Serializer] is a class that serializes Values into and from binary serialization format. It follows the Databoard [Databoard_Specification#Binary_File_Format|Binary File Format]. +
+    Binding binding = Bindings.DOUBLE;
+    Serializer serializer = Bindings.getSerializer( binding );
+    byte[] data = serializer.serialize( new Double( 100.0 ) );
+    
+    Double value = (Double) serializer.deserialize( data );
+
+ +Files can be partially accessed using BinaryAccessor, see [accessor|Accessors]. This is useful when handling larger than memory files. + +===Validation=== +'''Value''' can be ''well-formed'' or ''valid''. +The domain of valid values are defined with restrictions in data types, and @Length, @Range, @Pattern and @MIMEType Annotations in Classes + +Validation mechanism in Binding asserts that the instance is a valid value of the respective Data Type. +
+    try {
+        Binding.assertInstaceIsValid( object );
+    } catch( BindingException e ) {
+        // In-valid object
+    }
+
+ +===Other Notes=== +*Binding is a Comparator, all data values are comparable, the order is defined in [[Databoard_Specification#Comparison|Specification]]. +*Binding#createDefault() creates a valid instance of the Datatype. +*Binding#createRandom(int) creates a valid instance with random values. Useful for unit tests. +*Binding#clone(Object) creates a new instance with same content. +*Binding#readFrom(Object, Binding, Binding) copies contents from another object of same type. + +===Parsing & Printing=== + +Data values are printed and parsed of the [[Databoard_Specification|Text notation]] with the following Binding methods: +
+    String text = binding.printValue( value, true );
+    
+    Object value = binding.parseValue( text );
+
+And also to value definitions ''name : type = value'' + +
+    StringBuilder sb = new StringBuilder();
+    DataValueRepository repo = new DataValueRepository();
+    repo.put( "temp", binding, value );
+    binding.printValue( value, sb, repo, true );
+    String text = sb.toString();
+    
+    Object value = binding.parseValueDefinition( text );
+
\ No newline at end of file