]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src-isv/doc/binding.mediawiki
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src-isv / doc / binding.mediawiki
1 =Binding=
2 Binding is a mechanism for mapping a Java Class to a Datatype.
3 For example, take a java.lang.Double. The instance is a container (<code>private final double value;</code>) for the data and its Binding (DoubleBinding) is a way to access the data (<code>.valueOf()</code>, <code>.getDouble()</code>). 
4     Java Object + Binding = Databoard Value
5
6 Bindings have the exact same composition tree structure as its respective <code>Datatype</code> - 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.
7 <pre class="code">
8     Binding binding = Binding.getBinding( Double.class );
9 </pre>
10
11 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). 
12 <pre class="code">
13     Binding binding = new RecordBinding() { ... };
14 </pre>
15
16 '''[../javadoc/org/simantics/databoard/binding|org.simantics.databoard.binding]'''.
17 {| style="background-color: #f9f9f9; border: 1px solid #aaaaaa; "
18 |- style="background-color: #e9e9e9; " |
19 | '''Class''' || '''Description'''
20 |- 
21 | [../javadoc/org/simantics/databoard/binding/DataBinding.html|DataBinding]
22 | Base class for all data Bindings
23 |- 
24 | [../javadoc/org/simantics/databoard/binding/RecordBinding.html|RecordBinding]
25 | Record 
26 |- 
27 | [../javadoc/org/simantics/databoard/binding/ArrayBinding.html|ArrayBinding]
28 | Array - an ordered sequence of elements of one value.
29 |- 
30 | [../javadoc/org/simantics/databoard/binding/MapBinding.html|MapBinding]
31 | Map - an ''ordered'' map of keys to values. 
32 |- 
33 | [../javadoc/org/simantics/databoard/binding/UnionBinding.html|UnionBinding]
34 | Union
35 |- 
36 | [../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]
37 | Primitive and numeric Bindings
38 |- 
39 | [../javadoc/org/simantics/databoard/binding/StringBinding.html|StringBinding]
40 | String 
41 |- 
42 | [../javadoc/org/simantics/databoard/binding/OptionalBinding.html|OptionalBinding]
43 | Optional value
44 |- 
45 | [../javadoc/org/simantics/databoard/binding/VariantBinding.html|VariantBinding]
46 | Variant value
47 |}
48
49
50 Binding can be acquired or created using one of the following methods:
51 * Constructor 
52 * Constant
53 * Reflection-Read from a Class 
54 * Created using [../javadoc/org/simantics/databoard/bindingscheme/BindingScheme.html|BindingScheme]
55 <pre class="code">
56     Binding binding = new DoubleBinding( doubleType );
57     Binding binding = new RecordBinding() { ... };
58     Binding binding = Bindings.DOUBLE;
59     Binding binding = Binding.getBinding( Double.class );
60     Binding binding = Binding.getBinding( Datatypes.DOUBLE );
61 </pre>
62
63 ==Reflection==
64 '''Data Type and Binding can be read automatically from a Class by utility.'''
65 <pre class="code">
66     Datatype type = Datatypes.getDatatype( Foo.class );
67     Binding binding = Bindings.getBinding( Foo.class );
68 </pre>
69
70 Bindings for generics classes can be created by passing arguments.
71 <pre class="code">
72     Binding e = Bindings.getBinding(List.class, String.class);
73     List<String> list = (List<String>) e.createRandom(5);
74
75     Binding binding = Bindings.getBinding( Map.class, Integer.class, Integer.class );
76     Map<Integer, Integer> value = (Map<Integer, Integer>) binding.createDefault();
77 </pre>
78
79 Even cascading generics...
80 <pre class="code">
81     Binding e = Bindings.getBinding(List.class, List.class, String.class);
82     List<List<String>> listList = (List<List<String>>) e.createRandom(5);
83 </pre>
84
85 '''Classes are RecordTypes'''
86 <pre class="code">
87     class Foo {
88         public int x, y, z;
89     }
90 </pre>
91 Is a binding to the following Datatype
92 <pre class="code">
93     type Foo = { x : Integer, y : Integer, z : Integer }
94 </pre>
95
96 '''There are three types of classes supported, and therefore three ways how objects are constructed.'''
97 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. 
98
99 ''Record-like classes:''
100 <pre class="code">
101     class Foo {
102         public String name;
103         public Object value;
104     }
105 </pre>
106
107 ''Immutable classes:''
108 <pre class="code">
109     class Foo {
110         private String name;
111         private Object value;
112         
113         public Foo(String name, Object value) {
114             this.name = name;
115             this.value = value;
116         }
117         
118         public String getName() {
119             return name;
120         }
121         
122         public Object getValue() {
123             return value;
124         }
125         
126     }
127 </pre>
128
129 ''Bean-like classes:''
130 <pre class="code">
131     class Foo {
132         private String name;
133         private Object value;
134         
135         public void setName(String name) {
136             this.name = name;
137         }
138         
139         public void setValue(Object value) {
140             this.value = value;
141         }
142         
143         public String getName() {
144             return name;
145         }
146         
147         public Object getValue() {
148             return value;
149         }
150         
151     }
152 </pre<
153
154 '''Static and transient fields are omited:'''
155 <pre class="code">
156     static final long serialVersionUID = -3387516993124229943L;
157     transient int hashCode;
158 </pre>
159
160 '''Enumerations are Union Types'''
161 <pre class="code">
162     enum Cars { Ferrari, Porche, Lamborghini, Jaguar }
163 </pre>    
164 is interpreted as union type
165     type Cars = | Ferrari | Porche | Lamborghini | Jaguar
166
167 If you cannot modify the class, you have to create binding for it by subclassing base binding classes, eg. RecordBinding.
168
169 '''Other exceptions:'''
170 *<code>java.lang.Object</code> is <tt>Variant</tt>.
171 *<code>java.lang.Set<T></code> is <tt>Map(T, {})</tt>.
172 *<code>java.lang.TreeSet<T></code> is <tt>Map(T, {})</tt>.
173 *<code>java.lang.HashSet<T></code> is <tt>Map(T, {})</tt>. (Note HashSet binding has very low performance.)
174 *<code>java.lang.Map<K, V></code> is <tt>Map(K, V)</tt>.
175 *<code>java.lang.TreeMap<K, V></code> is <tt>Map(K, V)</tt>.
176 *<code>java.lang.HashMap<K, V></code> is <tt>Map(K, V)</tt>. (Note HashMap binding has very low performance.)
177 *<code>java.lang.List<T></code> is <tt>Array(T)</tt>.
178 *<code>java.lang.ArrayList<T></code> is <tt>Array(T)</tt>.
179 *<code>java.lang.LinkedList<T></code> is <tt>Array(T)</tt>.
180 *<code>void</code> is <tt>{}</tt>.
181 *The stacktrace of <code>Exception.class</code> is omited.
182
183 ===Annotations===
184 Java Classes / Fields can be annotated with the following annotations ('''[../javadoc/org/simantics/databoard/annotations/|org.simantics.databoard.annotations]]''').
185
186
187 '''UnionTypes are abstract classes or interfaces with <code>@Union</code> annotation.'''
188 <pre class="code">
189     @Union({A.class, B.class}) interface Union1 {               
190     }
191     
192     class A implements Union1 {
193         public int value;
194     }
195     
196     class B implements Union1 {
197         public String name;
198     }
199 </pre>
200
201 '''<code>@Referable</code> denotes that the class has recursion and is a referable record.'''
202 <pre class="code">
203     public @Referable class Node {
204         public Node[] children;
205     }
206 </pre>
207
208 '''Fields that can have <tt>null</tt> value have <code>@Optional</code> annotation.'''
209 <pre class="code">
210     @Optional String name;
211 </pre>
212
213 '''String valid values are set with <code>@Pattern</code> as regular expression. ([http://en.wikipedia.org/wiki/Regular_expression])'''
214 <pre class="code">
215     String @Pattern("(19|20)\\d\\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])") date;
216     
217     type Date = String( Pattern = "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" )
218 </pre>
219
220 '''String content type is set with a <code>@MIMEType</code>. ([http://en.wikipedia.org/wiki/Mime_type MIME Type])'''
221 <pre class="code">
222     @MIMEType("text/xml") String document;
223 </pre>
224
225 '''Array size restricted with @Length.'''
226 <pre class="code">
227     @Length("[0..10]") int[] array;
228     @Length({"[320]", "[240]"}) int[][] image;
229 </pre>
230
231 '''Valid numeric range is set with @Range.'''
232 <pre class="code">
233     @Range("[0..100]") double alpha;
234     @Range("[0..]" double length;
235 </pre>
236
237 '''<tt>Range</tt> and <tt>Length</tt> notation:'''
238 *Exact Value "0"
239 *Exclude all "()"
240 *Unlimited "[..]"
241 *Inclusive range "[0..100]"
242 *Exclusive range "(0..100)"
243 *Inclusive lower bound and exclusive upper bound "[0..100)"
244
245
246 '''Engineering unit type is given with @Unit.'''
247 <pre class="code">
248     @Unit("km/h") double maxVelocity;
249 </pre>
250
251 '''The serializer generated with reflection can be overriden with @SpecializedSerializer'''
252 <pre class="code">
253     @SpecializedSerializer(MySerializer.class) 
254     public class MyRecord {
255         ...
256     }
257 </pre>
258
259 == Mapping Scheme ==
260 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.
261
262 <code>DefaultBindingScheme</code> is a scheme that converts any datatype to a binding. It prefers java.lang.X primitives.
263 The Class mapping for each type is listed below.
264 {| style="background-color: #f9f9f9; border: 1px solid #aaaaaa; "
265 |- style="background-color: #e9e9e9;
266 | '''Type''' || '''Class'''
267 |- 
268 | <code>BooleanType</code> || <code>Boolean.class</code>
269 |- 
270 | <code>ByteType</code> || <code>Byte.class</code>
271 |- 
272 | <code>FloatType</code> || <code>Float.class</code>
273 |- 
274 | <code>DoubleType</code> || <code>eDouble.class</code>
275 |- 
276 | <code>IntegerType</code> || <code>Integer.class</code>
277 |- 
278 | <code>LongType</code> || <code>Long.class</code>
279 |- 
280 | <code>StringType</code> || <code>String.class</code>
281 |- 
282 | <code>UnionType</code> || <code>TaggedObject.class</code>
283 |- 
284 | <code>OptionType</code> || <code>ValueContainer.class</code>
285 |- 
286 | <code>RecordType</code> || <code>Object[].class</code>
287 |- 
288 | <code>ArrayType</code> || <code>ArrayList.class</code>
289 |- 
290 | <code>Array(Byte)</code> || <code>byte[].class</code>
291 |- 
292 | <code>MapType</code> || <code>TreeMap.class</code>
293 |- 
294 | <code>VariantType</code> || <code>Variant.class</code>
295 |}
296
297 <code>MutableBindingScheme</code> is a scheme that provides a fully implementing mutable binding for all data types. 
298 The Class mapping for each type is listed below.
299
300 {| style="background-color: #f9f9f9; border: 1px solid #aaaaaa; "
301 |- style="background-color: #e9e9e9; " |
302 | '''Type''' || '''Class'''
303 |- 
304 | <code>BooleanType</code> || <code>MutableBoolean.class</code>
305 |- 
306 | <code>ByteType</code> || <code>MutableByte.class</code>
307 |- 
308 | <code>FloatType</code> || <code>MutableFloat.class</code>
309 |- 
310 | <code>DoubleType</code> || <code>MutableDouble.class</code>
311 |- 
312 | <code>IntegerType</code> || <code>MutableInt.class</code>
313 |- 
314 | <code>LongType</code> || <code>MutableLong.class</code>
315 |- 
316 | <code>StringType</code> || <code>MutableString.class</code>
317 |- 
318 | <code>UnionType</code> || <code>TaggedObject.class</code>
319 |- 
320 | <code>OptionType</code> || <code>ValueContainer.class</code>
321 |- 
322 | <code>RecordType</code> || <code>Object[].class</code>
323 |- 
324 | <code>ArrayType</code> || <code>ArrayList.class</code>
325 |- 
326 | <code>MapType</code> || <code>TreeMap.class</code>
327 |- 
328 | <code>VariantType</code> || <code>Variant.class</code>
329 |}
330
331
332 ===Serialization===
333 [../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].
334 <pre class="code">
335     Binding binding = Bindings.DOUBLE;
336     Serializer serializer = Bindings.getSerializer( binding );
337     byte[] data = serializer.serialize( new Double( 100.0 ) );
338     
339     Double value = (Double) serializer.deserialize( data );
340 </pre>
341
342 Files can be partially accessed using BinaryAccessor, see [accessor|Accessors]. This is useful when handling larger than memory files.
343
344 ===Validation===
345 '''Value''' can be ''well-formed'' or ''valid''. 
346 The domain of valid values are defined with restrictions in data types, and <code>@Length</code>, <code>@Range</code>, <code>@Pattern</code> and <code>@MIMEType</code> Annotations in Classes
347
348 Validation mechanism in Binding asserts that the instance is a valid value of the respective Data Type.
349 <pre class="code">
350     try {
351         Binding.assertInstaceIsValid( object );
352     } catch( BindingException e ) {
353         // In-valid object
354     }
355 </pre>
356
357 ===Other Notes===
358 *<tt>Binding</tt> is a <tt>Comparator</tt>, all data values are comparable, the order is defined in [[Databoard_Specification#Comparison|Specification]].
359 *<tt>Binding#createDefault()</tt> creates a valid instance of the Datatype.
360 *<tt>Binding#createRandom(int)</tt> creates a valid instance with random values. Useful for unit tests.
361 *<tt>Binding#clone(Object)</tt> creates a new instance with same content.
362 *<tt>Binding#readFrom(Object, Binding, Binding)</tt> copies contents from another object of same type.
363
364 ===Parsing & Printing===
365
366 Data values are printed and parsed of the [[Databoard_Specification|Text notation]] with the following <code>Binding</code> methods:
367 <pre class="code">
368     String text = binding.printValue( value, true );
369     
370     Object value = binding.parseValue( text );
371 </pre>
372 And also to value definitions <tt>''name : type = value''</tt>
373
374 <pre class="code">
375     StringBuilder sb = new StringBuilder();
376     DataValueRepository repo = new DataValueRepository();
377     repo.put( "temp", binding, value );
378     binding.printValue( value, sb, repo, true );
379     String text = sb.toString();
380     
381     Object value = binding.parseValueDefinition( text );
382 </pre>