1 center>'''Databoard 0.6.1 Developer Manual'''</center>
\r
4 In Databoard all values have a type representation, [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/Datatype.java|Datatype.java]].
\r
5 It is the base abstract class for all concrete type classes (See table below).
\r
6 There is a facade class utility ([[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Datatypes.java|Datatypes]]) that provides functions to most of the Datatype library's features.
\r
8 '''[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type|org.simantics.databoard.type]]'''.
\r
9 {| style="background-color: #e9e9e9; border: 1px solid #aaaaaa; "
\r
12 |- style="background-color: #f9f9f9; " |
\r
13 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/Datatype.java|Datatype]]
\r
14 | Base class for all data types
\r
15 |- style="background-color: #f9f9f9; " |
\r
16 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/RecordType.java|RecordType]]
\r
18 |- style="background-color: #f9f9f9; " |
\r
19 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/ArrayType.java|ArrayType]]
\r
20 | Array - an ordered sequence of elements of one type.
\r
21 |- style="background-color: #f9f9f9; " |
\r
22 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/MapType.java|MapType]]
\r
23 | Map - an ordered map of keys to values.
\r
24 |- style="background-color: #f9f9f9; " |
\r
25 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/UnionType.java|UnionType]]
\r
27 |- style="background-color: #f9f9f9; " |
\r
28 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/BooleanType.java|BooleanType]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/IntType.java|IntType]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/LongType.java|LongType]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/FloatType.java|FloatType]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/DoubleType.java|DoubleType]]
\r
29 | Primitive and numeric types
\r
30 |- style="background-color: #f9f9f9; " |
\r
31 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/StringType.java|StringType]]
\r
33 |- style="background-color: #f9f9f9; " |
\r
34 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/OptionalType.java|OptionalType]]
\r
36 |- style="background-color: #f9f9f9; " |
\r
37 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/type/VariantType.java|VariantType]]
\r
42 Datatype can be acquired or created using one of the following methods:
\r
45 * [[#Reflection|Reflection]]-Read from a Class
\r
46 * Read from string of [[Databoard_Specification|the text notation]].
\r
47 Datatype type = new DoubleType();
\r
48 Datatype type = Datatypes.DOUBLE;
\r
49 Datatype type = Datatypes.getDatatype( Double.class );
\r
51 Datatypes.addDefinition("type Node = { id : String; children : Node[] }");
\r
52 Datatype type = Datatypes.getDatatype("Node");
\r
56 Datatypes are parsed using <code>Datatypes.DatatypeRepository</code>.
\r
57 Datatypes.addDefinition("type Node = { id : String; children : Node[] }");
\r
58 Datatype type = Datatypes.getDatatype("Node");
\r
60 Types are printed to types and definitions with
\r
61 String type = type.toString();
\r
63 DatatypeRepository repo = new DatatypeRepository();
\r
64 repo.add("temp1", type);
\r
65 String typeDef = repo.toString();
\r
67 ==Structure Example==
\r
68 A node is a recursive type. With databoard typesystem it could be stated as
\r
71 displayNames : LocalizedTexts;
\r
73 value : Optional(Variant);
\r
76 [[Image:NodeType.png|Type presented as tree]]
\r
79 A couple of instances with Databoard value notation:
\r
82 displayNames = map{
\93en
\94 =
\93Instrument
\93 }
\r
86 displayNames = map{
\93en
\94 =
\93Child
\94} },
\r
90 value =
\93<root>
\94 : String
\r
93 [[Image:NodeInstance.png|Node values preseted as tree]]
\r
96 There is a [[Databoard_Specification#Datatypes|type system]], and when developing with java, platform neutral data values can be read from and written to objects. This is the role of a binding, a map from a Java Class to a Datatype.
\r
98 For instance, take a java.lang.Double. Its instance is the container (<code>private final double value;</code>) of the data and its Binding (DoubleBinding) is the access (<code>.valueOf()</code>, <code>.getDouble()</code>) to the data.
\r
99 Java Object + Binding = Databoard Value
\r
101 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.
\r
102 Binding binding = Binding.getBinding( Double.class );
\r
104 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).
\r
105 Binding binding = new RecordBinding() { ... };
\r
108 '''[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding|org.simantics.databoard.binding]]'''.
\r
109 {| style="background-color: #e9e9e9; border: 1px solid #aaaaaa; "
\r
111 | '''Description'''
\r
112 |- style="background-color: #f9f9f9; " |
\r
113 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/DataBinding.java|DataBinding]]
\r
114 | Base class for all data Bindings
\r
115 |- style="background-color: #f9f9f9; " |
\r
116 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/RecordBinding.java|RecordBinding]]
\r
118 |- style="background-color: #f9f9f9; " |
\r
119 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/ArrayBinding.java|ArrayBinding]]
\r
120 | Array - an ordered sequence of elements of one value.
\r
121 |- style="background-color: #f9f9f9; " |
\r
122 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/MapBinding.java|MapBinding]]
\r
123 | Map - an ''ordered'' map of keys to values.
\r
124 |- style="background-color: #f9f9f9; " |
\r
125 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/UnionBinding.java|UnionBinding]]
\r
127 |- style="background-color: #f9f9f9; " |
\r
128 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/BooleanBinding.java|BooleanBinding]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/IntBinding.java|IntBinding]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/LongBinding.java|LongBinding]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/FloatBinding.java|FloatBinding]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/DoubleBinding.java|DoubleBinding]]
\r
129 | Primitive and numeric Bindings
\r
130 |- style="background-color: #f9f9f9; " |
\r
131 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/StringBinding.java|StringBinding]]
\r
133 |- style="background-color: #f9f9f9; " |
\r
134 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/OptionalBinding.java|OptionalBinding]]
\r
136 |- style="background-color: #f9f9f9; " |
\r
137 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/binding/VariantBinding.java|VariantBinding]]
\r
142 Binding can be acquired or created using one of the following methods:
\r
145 * Reflection-Read from a Class
\r
146 * Created using [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/bindingscheme/BindingScheme.java|BindingScheme]]
\r
147 Binding binding = new DoubleBinding( doubleType );
\r
148 Binding binding = new RecordBinding() { ... };
\r
149 Binding binding = Bindings.DOUBLE;
\r
150 Binding binding = Binding.getBinding( Double.class );
\r
151 Binding binding = Binding.getBinding( Datatypes.DOUBLE );
\r
154 '''Data Type and Binding can be read automatically from a Class by utility.'''
\r
155 Datatype type = Datatypes.getDatatype( Foo.class );
\r
156 Binding binding = Bindings.getBinding( Foo.class );
\r
158 Bindings for generics classes can be created by passing arguments.
\r
159 Binding e = Bindings.getBinding(List.class, String.class);
\r
160 List<String> list = (List<String>) e.createRandom(5);
\r
162 Binding binding = Bindings.getBinding( Map.class, Integer.class, Integer.class );
\r
163 Map<Integer, Integer> value = (Map<Integer, Integer>) binding.createDefault();
\r
165 Even cascading generics...
\r
166 Binding e = Bindings.getBinding(List.class, List.class, String.class);
\r
167 List<List<String>> listList = (List<List<String>>) e.createRandom(5);
\r
170 '''Classes are RecordTypes'''
\r
172 public int x, y, z;
\r
174 Is a binding to the following Datatype
\r
175 type Foo = { x : Integer, y : Integer, z : Integer }
\r
177 '''There are three types of classes supported, and therefore three ways how objects are constructed.'''
\r
178 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.
\r
180 ''Record-like classes:''
\r
182 public String name;
\r
183 public Object value;
\r
186 ''Immutable classes:''
\r
188 private String name;
\r
189 private Object value;
\r
191 public Foo(String name, Object value) {
\r
193 this.value = value;
\r
196 public String getName() {
\r
200 public Object getValue() {
\r
206 ''Bean-like classes:''
\r
208 private String name;
\r
209 private Object value;
\r
211 public void setName(String name) {
\r
215 public void setValue(Object value) {
\r
216 this.value = value;
\r
219 public String getName() {
\r
223 public Object getValue() {
\r
229 '''Static and transient fields are omited:'''
\r
230 static final long serialVersionUID = -3387516993124229943L;
\r
231 transient int hashCode;
\r
233 '''Enumerations are Union Types'''
\r
234 enum Cars { Ferrari, Porche, Lamborghini, Jaguar }
\r
235 is interpreted as union type
\r
236 type Cars = | Ferrari | Porche | Lamborghini | Jaguar
\r
238 If you cannot modify the class, you have to create binding for it by subclassing base binding classes, eg. RecordBinding.
\r
240 '''Other exceptions:'''
\r
241 *<code>java.lang.Object</code> is <tt>Variant</tt>.
\r
242 *<code>java.lang.Set<T></code> is <tt>Map(T, {})</tt>.
\r
243 *<code>java.lang.TreeSet<T></code> is <tt>Map(T, {})</tt>.
\r
244 *<code>java.lang.HashSet<T></code> is <tt>Map(T, {})</tt>. (Note HashSet binding has very low performance.)
\r
245 *<code>java.lang.Map<K, V></code> is <tt>Map(K, V)</tt>.
\r
246 *<code>java.lang.TreeMap<K, V></code> is <tt>Map(K, V)</tt>.
\r
247 *<code>java.lang.HashMap<K, V></code> is <tt>Map(K, V)</tt>. (Note HashMap binding has very low performance.)
\r
248 *<code>java.lang.List<T></code> is <tt>Array(T)</tt>.
\r
249 *<code>java.lang.ArrayList<T></code> is <tt>Array(T)</tt>.
\r
250 *<code>java.lang.LinkedList<T></code> is <tt>Array(T)</tt>.
\r
251 *<code>void</code> is <tt>{}</tt>.
\r
252 *The stacktrace of <code>Exception.class</code> is omited.
\r
255 Java Classes / Fields can be annotated with the following annotations ('''[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/annotations/|org.simantics.databoard.annotations]]''').
\r
258 '''UnionTypes are abstract classes or interfaces with <code>@Union</code> annotation.'''
\r
259 @Union({A.class, B.class}) interface Union1 {
\r
262 class A implements Union1 {
\r
266 class B implements Union1 {
\r
267 public String name;
\r
271 '''<code>@Referable</code> denotes that the class has recursion and is a referable record.'''
\r
272 public @Referable class Node {
\r
273 public Node[] children;
\r
277 '''Fields that can have <tt>null</tt> value have <code>@Optional</code> annotation.'''
\r
278 @Optional String name;
\r
281 '''String valid values are set with <code>@Pattern</code> as regular expression. ([http://en.wikipedia.org/wiki/Regular_expression])'''
\r
282 String @Pattern("(19|20)\\d\\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])") date;
\r
284 type Date = String( Pattern = "(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" )
\r
287 '''String content type is set with a <code>@MIMEType</code>. ([http://en.wikipedia.org/wiki/Mime_type MIME Type])'''
\r
288 @MIMEType("text/xml") String document;
\r
291 '''Array size restricted with @Length.'''
\r
292 @Length("[0..10]") int[] array;
\r
293 @Length({"[320]", "[240]"}) int[][] image;
\r
296 '''Valid numeric range is set with @Range.'''
\r
297 @Range("[0..100]") double alpha;
\r
298 @Range("[0..]" double length;
\r
301 '''<tt>Range</tt> and <tt>Length</tt> notation:'''
\r
305 *Inclusive range "[0..100]"
\r
306 *Exclusive range "(0..100)"
\r
307 *Inclusive lower bound and exclusive upper bound "[0..100)"
\r
310 '''Engineering unit type is given with @Unit.'''
\r
311 @Unit("km/h") double maxVelocity;
\r
313 '''The serializer generated with reflection can be overriden with @SpecializedSerializer'''
\r
314 @SpecializedSerializer(MySerializer.class)
\r
315 public class MyRecord {
\r
319 == Mapping Scheme ==
\r
320 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.
\r
322 <code>DefaultBindingScheme</code> is a scheme that converts any datatype to a binding. It prefers java.lang.X primitives.
\r
323 The Class mapping for each type is listed below.
\r
324 {| style="background-color: #e9e9e9; border: 1px solid #aaaaaa; "
\r
327 |- style="background-color: #f9f9f9; " |
\r
328 | <code>BooleanType</code>
\r
329 | <code>Boolean.class</code>
\r
330 |- style="background-color: #f9f9f9; " |
\r
331 | <code>ByteType</code>
\r
332 | <code>Byte.class</code>
\r
333 |- style="background-color: #f9f9f9; " |
\r
334 | <code>FloatType</code>
\r
335 | <code>Float.class</code>
\r
336 |- style="background-color: #f9f9f9; " |
\r
337 | <code>DoubleType</code>
\r
338 | <code>eDouble.class</code>
\r
339 |- style="background-color: #f9f9f9; " |
\r
340 | <code>IntegerType</code>
\r
341 | <code>Integer.class</code>
\r
342 |- style="background-color: #f9f9f9; " |
\r
343 | <code>LongType</code>
\r
344 | <code>Long.class</code>
\r
345 |- style="background-color: #f9f9f9; " |
\r
346 | <code>StringType</code>
\r
347 | <code>String.class</code>
\r
348 |- style="background-color: #f9f9f9; " |
\r
349 | <code>UnionType</code>
\r
350 | <code>TaggedObject.class</code>
\r
351 |- style="background-color: #f9f9f9; " |
\r
352 | <code>OptionType</code>
\r
353 | <code>ValueContainer.class</code>
\r
354 |- style="background-color: #f9f9f9; " |
\r
355 | <code>RecordType</code>
\r
356 | <code>Object[].class</code>
\r
357 |- style="background-color: #f9f9f9; " |
\r
358 | <code>ArrayType</code>
\r
359 | <code>ArrayList.class</code>
\r
360 |- style="background-color: #f9f9f9; " |
\r
361 | <code>Array(Byte)</code>
\r
362 | <code>byte[].class</code>
\r
363 |- style="background-color: #f9f9f9; " |
\r
364 | <code>MapType</code>
\r
365 | <code>TreeMap.class</code>
\r
366 |- style="background-color: #f9f9f9; " |
\r
367 | <code>VariantType</code>
\r
368 | <code>Variant.class</code>
\r
371 <code>MutableBindingScheme</code> is a scheme that provides a fully implementing mutable binding for all data types.
\r
372 The Class mapping for each type is listed below.
\r
374 {| style="background-color: #e9e9e9; border: 1px solid #aaaaaa; "
\r
377 |- style="background-color: #f9f9f9; " |
\r
378 | <code>BooleanType</code>
\r
379 | <code>MutableBoolean.class</code>
\r
380 |- style="background-color: #f9f9f9; " |
\r
381 | <code>ByteType</code>
\r
382 | <code>MutableByte.class</code>
\r
383 |- style="background-color: #f9f9f9; " |
\r
384 | <code>FloatType</code>
\r
385 | <code>MutableFloat.class</code>
\r
386 |- style="background-color: #f9f9f9; " |
\r
387 | <code>DoubleType</code>
\r
388 | <code>MutableDouble.class</code>
\r
389 |- style="background-color: #f9f9f9; " |
\r
390 | <code>IntegerType</code>
\r
391 | <code>MutableInt.class</code>
\r
392 |- style="background-color: #f9f9f9; " |
\r
393 | <code>LongType</code>
\r
394 | <code>MutableLong.class</code>
\r
395 |- style="background-color: #f9f9f9; " |
\r
396 | <code>StringType</code>
\r
397 | <code>MutableString.class</code>
\r
398 |- style="background-color: #f9f9f9; " |
\r
399 | <code>UnionType</code>
\r
400 | <code>TaggedObject.class</code>
\r
401 |- style="background-color: #f9f9f9; " |
\r
402 | <code>OptionType</code>
\r
403 | <code>ValueContainer.class</code>
\r
404 |- style="background-color: #f9f9f9; " |
\r
405 | <code>RecordType</code>
\r
406 | <code>Object[].class</code>
\r
407 |- style="background-color: #f9f9f9; " |
\r
408 | <code>ArrayType</code>
\r
409 | <code>ArrayList.class</code>
\r
410 |- style="background-color: #f9f9f9; " |
\r
411 | <code>MapType</code>
\r
412 | <code>TreeMap.class</code>
\r
413 |- style="background-color: #f9f9f9; " |
\r
414 | <code>VariantType</code>
\r
415 | <code>Variant.class</code>
\r
419 ===Serialization===
\r
420 [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/serialization/binary/Serializer.java|Serializer.java]] is a class that serializes Values into and from binary serialization format. It follows the Databoard [[Databoard_Specification#Binary_File_Format|Binary File Format]].
\r
422 Binding binding = Bindings.DOUBLE;
\r
423 Serializer serializer = Bindings.getSerializer( binding );
\r
424 byte[] data = serializer.serialize( new Double( 100.0 ) );
\r
426 Double value = (Double) serializer.deserialize( data );
\r
428 Files can be partially accessed using BinaryAccessor, see [[#Accessors|Accessors]]. This is useful when handling larger than memory files.
\r
431 '''Value''' can be ''well-formed'' or ''valid''.
\r
432 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
\r
434 Validation mechanism in Binding asserts that the instance is a valid value of the respective Data Type.
\r
436 Binding.assertInstaceIsValid( object );
\r
437 } catch( BindingException e ) {
\r
442 *<tt>Binding</tt> is a <tt>Comparator</tt>, all data values are comparable, the order is defined in [[Databoard_Specification#Comparison|Specification]].
\r
443 *<tt>Binding#createDefault()</tt> creates a valid instance of the Datatype.
\r
444 *<tt>Binding#createRandom(int)</tt> creates a valid instance with random values. Useful for unit tests.
\r
445 *<tt>Binding#clone(Object)</tt> creates a new instance with same content.
\r
446 *<tt>Binding#readFrom(Object, Binding, Binding)</tt> copies contents from another object of same type.
\r
448 ===Parsing & Printing===
\r
450 Data values are printed and parsed of the [[Databoard_Specification|Text notation]] with the following <code>Binding</code> methods:
\r
452 String text = binding.printValue( value, true );
\r
454 Object value = binding.parseValue( text );
\r
456 And also to value definitions <tt>''name : type = value''</tt>
\r
457 StringBuilder sb = new StringBuilder();
\r
458 DataValueRepository repo = new DataValueRepository();
\r
459 repo.put( "temp", binding, value );
\r
460 binding.printValue( value, sb, repo, true );
\r
461 String text = sb.toString();
\r
463 Object value = binding.parseValueDefinition( text );
\r
466 There can be different Java Class Bindings for a single data type. For example, <code>Double</code> type can be have bindings <code>DoubleJavaBinding</code> and <code>MutableDoubleBinding</code> to two respective classes <code>java.lang.Double</code> and <code>MutableDouble</code>. Instance of one binding can be adapted to instance of another with an <code>[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/adapter/Adapter.java|Adapter]]</code>.
\r
468 Adapter can be created automatically or implemented self.
\r
469 Adapter adapter = new Adapter() { ... };
\r
470 Adapter adapter = Bindings.getAdapter( domainBinding, rangeBinding );
\r
473 Adapter adapter = Bindings.getAdapter(Bindings.MUTABLE_DOUBLE, Bindings.DOUBLE);
\r
474 java.lang.Double double = adapter.adapt( new MutableDouble(5.0) );
\r
476 There is also convenience.
\r
477 java.lang.Double double = Bindings.adapt( new MutableDouble(5.0), Bindings.MUTABLE_DOUBLE, Bindings.DOUBLE );
\r
479 The argument given to <code>Adapter#adapt(Object)</code> may be re-used in the result unless the adapter is a cloning adapter which guarantees a clone. Note, even wih cloning adapters immutable classes, (eg java.lang.Integer) are never cloned.
\r
480 Adapter cloner = Bindings.adapterCache.getAdapter(domain, range, false, true);
\r
481 cloner.adapt( ... );
\r
483 Rectangle2D rect2 = Bindings.clone( rect1, rectBinding, rectBinding );
\r
485 ===Type Conversion===
\r
486 In some cases different types may be are type-conversion compatible. An instance of one type is convertible to instance of another.
\r
488 '''Engineering Units of same quantity are convertible.'''
\r
491 @Unit("km/h") double maxVelocity;
\r
492 @Unit("kg") double mass;
\r
493 @Unit("cm") double length;
\r
494 @Unit("kW") double power;
\r
499 @Unit("mph") float maxVelocity;
\r
500 @Unit("lbs") float mass;
\r
501 @Unit("ft") float length;
\r
502 @Unit("hp(M)") float power;
\r
505 Adapter si2imAdapter = Bindings.getTypeAdapter(
\r
506 Bindings.getBinding(CarSI.class),
\r
507 Bindings.getBinding(CarIm.class) );
\r
509 CarIm americanCarInfo = si2imAdapter.adapt( europeanCarInfo );
\r
512 '''Primitive Types.''' Note, primitive adapter throws an exception at runtime if values are not adaptable.
\r
513 Adapter adapter = getTypeAdapter( integerBinding, doubleBinding );
\r
514 Double double = adapter.adapt( new Integer( 5 ) );
\r
517 '''Records are matched by field names.'''
\r
524 Adapter adapter = getTypeAdapter( fooBinding, barBinding );
\r
527 '''Subtype to supertype:''' Note, this conversion cannot be not symmetric, supertypes cannot be converted to subtypes.
\r
531 class ValueNode extends Node {
\r
534 Adapter adapter = getTypeAdapter( valueNodeBinding, nodeBinding );
\r
536 '''Non-existing fields to Optional fields'''
\r
540 class NominalNode {
\r
542 @Optional String name;
\r
544 Adapter adapter = getTypeAdapter( nodeBinding, nominalNodeBinding );
\r
548 enum Cars { Audio, BMW, Mercedes, Honda, Mazda, Toyota, Ford, Mitsubishi, Nissan, GM }
\r
549 enum JapaneseCars { Honda, Mazda, Toyota, Nissan, Mitsubishi }
\r
551 Binding carsBinding = Bindings.getBinding( Cars.class );
\r
552 Binding japaneseCarsBinding = Bindings.getBinding( JapaneseCars.class );
\r
553 Adapter adapter = Bindings.adapterCache.getAdapter(japaneseCarsBinding, carsBinding, true, false);
\r
556 Say, you have several gigabytes of data in a file. The whole object doesn't need to be serialized at once. You can read and write the value partially using [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/|Accessor]] interface. The actual container can be a file, memory byte[]/ByteBuffer or a Java Object. The content is structured as tree using Databoard's type system. All but referable records are supported (=no recursion in accessors).
\r
558 '''[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor|org.simantics.databoard.accessor]] interfaces'''.
\r
559 {| style="background-color: #e9e9e9; border: 1px solid #aaaaaa; "
\r
561 | '''Description'''
\r
562 |- style="background-color: #f9f9f9; " |
\r
563 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/Accessor.java|Accessor]]
\r
564 | Base class for all data Accessors
\r
565 |- style="background-color: #f9f9f9; " |
\r
566 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/RecordAccessor.java|RecordAccessor]]
\r
568 |- style="background-color: #f9f9f9; " |
\r
569 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/ArrayAccessor.java|ArrayAccessor]]
\r
570 | Array - an ordered sequence of elements of one value.
\r
571 |- style="background-color: #f9f9f9; " |
\r
572 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/MapAccessor.java|MapAccessor]]
\r
573 | Map - an ''ordered'' map of keys to values.
\r
574 |- style="background-color: #f9f9f9; " |
\r
575 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/UnionAccessor.java|UnionAccessor]]
\r
577 |- style="background-color: #f9f9f9; " |
\r
578 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/BooleanAccessor.java|BooleanAccessor]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/IntAccessor.java|IntAccessor]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/LongAccessor.java|LongAccessor]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/FloatAccessor.java|FloatAccessor]],[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/DoubleAccessor.java|DoubleAccessor]]
\r
579 | Primitive and numeric Accessors
\r
580 |- style="background-color: #f9f9f9; " |
\r
581 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/StringAccessor.java|StringAccessor]]
\r
583 |- style="background-color: #f9f9f9; " |
\r
584 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/OptionalAccessor.java|OptionalAccessor]]
\r
586 |- style="background-color: #f9f9f9; " |
\r
587 | [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/VariantAccessor.java|VariantAccessor]]
\r
591 [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Accessors.java|Accessors]] and [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Files.java|Files]] are facade classes that contains utilities for instantiating and handling Accessors.
\r
593 <code>[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/binary/|Binary Accessor]]</code> is an access to a value in binary format (<tt>byte[]</tt> or <tt>ByteBuffer</tt>).
\r
595 '''Example:''' Binary accessor
\r
596 <div style="background-color:#fffff7; border: 1px dashed #cccccc; padding: 2ex; margin-left:2em; margin-right:2em; margin-top: 1em; margin-bottom:1em;"><syntaxhighlight lang="java">
\r
597 Datatype type = Datatypes.getDatatype( Rectangle2D.Double.class );
\r
598 Binding binding = Bindings.getBinding( Rectangle2D.Double.class );
\r
599 Serializer s = Binding.getSerializer( binding );
\r
601 // Serialize rectangle
\r
602 Rectangle2D rect = new Rectangle2D.Double(0,0, 10, 10);
\r
603 byte[] data = s.serialize(rect);
\r
605 // Open accessor to byte data and modify first field in the byte data
\r
606 RecordAccessor ra = Accessors.getAccessor(data, type);
\r
607 ra.setFieldValue(0, Bindings.DOUBLE, 5.0);
\r
609 // Deserialize values from the byte data back to the rectangle object
\r
610 s.deserialize(data, rect);
\r
611 System.out.println(rect.getX());
\r
612 </syntaxhighlight></div>
\r
614 '''Example:''' File accessor, create
\r
615 <div style="background-color:#fffff7; border: 1px dashed #cccccc; padding: 2ex; margin-left:2em; margin-right:2em; margin-top: 1em; margin-bottom:1em;"><syntaxhighlight lang="java">
\r
616 RecordType type = Datatypes.getDatatype( Rectangle2D.Double.class );
\r
617 // Create a new file and initialize it with rectangle type, and open file accessor
\r
618 FileRecordAccessor fa = Accessors.createFile( file, type );
\r
620 // Write the first field (x)
\r
621 fa.setFieldValue(0, Bindings.DOUBLE, 5.0);
\r
623 </syntaxhighlight></div>
\r
625 '''Example:''' File accessor, open
\r
626 <div style="background-color:#fffff7; border: 1px dashed #cccccc; padding: 2ex; margin-left:2em; margin-right:2em; margin-top: 1em; margin-bottom:1em;"><syntaxhighlight lang="java">
\r
627 // Open an accessor to an existing binary file
\r
628 FileVariantAccessor fa = Accessors.openAccessor(file);
\r
629 RecordAccessor ra = fa.getContentAccessor();
\r
631 // Read the first field (x)
\r
632 Double x = (Double) ra.getFieldValue(0, Bindings.DOUBLE);
\r
634 </syntaxhighlight></div>
\r
636 '''Example:''' Java Accessor
\r
637 <div style="background-color:#fffff7; border: 1px dashed #cccccc; padding: 2ex; margin-left:2em; margin-right:2em; margin-top: 1em; margin-bottom:1em;"><syntaxhighlight lang="java">
\r
638 Binding binding = Bindings.getBinding(Rectangle2D.Double.class);
\r
639 Rectangle2D rect = new Rectangle2D.Double(0,0, 10, 10);
\r
641 // Open accessor to rectangle
\r
642 RecordAccessor ra = Accessors.getAccessor(binding, rect);
\r
644 // Set rectangle's first field (x) to 5.0
\r
645 ra.setFieldValue(0, Bindings.DOUBLE, 5.0);
\r
646 System.out.println( rect.getX() );
\r
647 </syntaxhighlight></div>
\r
650 ==Accessor Reference==
\r
651 Accessors can be opened to a sub-nodes with AccessorReference or by calling getAccessor. AccessorReference is a string of instances, either accessor type specific of LabelReferences.
\r
652 ChildReference ref = ChildReference.compile(
\r
653 new NameReference("node"),
\r
654 new ComponentReference()
\r
656 Accessor child = accessor.getComponent( ref );
\r
658 ChildReference ref = ChildReference.compile(
\r
659 new LabelReference("node"),
\r
660 new LabelReference("v")
\r
662 Accessor child = accessor.getComponent( ref );
\r
664 ChildReference ref = ChildReference.create("n-node/v");
\r
665 Accessor child = accessor.getComponent( ref );
\r
667 ChildReference ref = ChildReference.create("node/v");
\r
668 Accessor child = accessor.getComponent( ref );
\r
670 VariantAccessor va = recordAccessor.getFieldAccessor("node");
\r
671 Accessor child = va.getValueAccessor();
\r
673 ==Listening mechanism==
\r
674 Accessor offers a monitoring mechanism for the data model.
\r
675 There is an <code>[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/interestset/InterestSet.java|InterestSet]]</code> that is a description of a sub-tree that is to be monitored of the data model.
\r
676 <code>[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/event/Event.java|Events]]</code> are objects that spawned on changes to the data model. Each event object is annotated with [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/accessor/reference/|reference path]] that is in relation to the node where the listener was placed.
\r
678 Accessor Listeners use [[EventThread Pattern]] pattern.
\r
682 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Datatypes.java|Datatypes]] is a facade class that has functions for handling Datatypes.
\r
683 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Bindings.java|Bindings]] is a facade class that has functions for handling Bindings.
\r
684 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Accessors.java|Accessors]] is a facade class that has functions for handling Accessors.
\r
685 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Files.java|Files]] has Read, Write and accessor functions.
\r
686 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Units.java|Units]] is a facade class that has functions for handling Engineering Units.
\r
687 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/Methods.java|Methods]] has Methods, Interfaces and RPC utility functions.
\r
689 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/util/binary/RandomAccessBinary.java|RandomAccessBinary]] is a interface for byte handling operations. In addition to basic primitive reading & writing, there are methods for grow, shrink, insert and remove.
\r
690 **[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/util/binary/BinaryFile.java|BinaryFile]] and [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/util/binary/BinaryMemory.java|BinaryMemory]] are corresponding file and memory implementations.
\r
691 **[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/util/binary/Blob.java|Blob]] is an implementation that represents a sub-region of a RandomAccessBinary.
\r
693 ==Interface Types==
\r
694 There are interfaces, method types and method type definitions.
\r
695 Interface type describes a software interface. It is a collection of methods type definitions.
\r
696 Method type is an unnamed function with the following properties : Response Type, Request Type and ErrorType; where Response Type is any Data Type, Request Type is a Record and Error Type is an Union.
\r
697 Method type definition is nominal method description.
\r
699 The respective Java classes are:
\r
700 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/method/Interface.java|Interface.java]]
\r
701 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/method/MethodTypeDefinition.java|MethodTypeDefinition.java]]
\r
702 *[[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/method/MethodType.java|MethodType.java]]
\r
704 In java InterfaceType description can be created with one of the following methods:
\r
705 * Implementing InterfaceType
\r
706 * Reading an Java Interface Class using reflection
\r
707 Interface it = new Interface( ... methodDefinitions );
\r
708 Interface it = getInterface( MyInterface.class );
\r
710 [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/method/MethodInterface.java|MethodInterface.java]] is a binding of an
\r
711 Java Instance and an Interface Type. It decouples the method invocation from the object.
\r
713 MethodInterface can be created with the following methods:
\r
716 MethodInterface mi = new MethodInterface() {...}
\r
717 MethodInterface mi = Datatypes.bindInterface( MyInterface.class, myObject );
\r
719 Utilities <code>Datatypes.createProxy()</code> and <code>Datatypes.bindInterface()</code> adapt between MethodInterface and Java Instance.
\r
720 MethodInterface mi = Datatypes.bindInterface( MyInterface.class, myObject );
\r
721 MyInterface myObject = Datatypes.createProxy( MyInterface.class, mi );
\r
723 ==Remote Procedure Call==
\r
724 Utilities [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/method/Server.java|Server.java]] and [[svn:foundation/databoard/trunk/org.simantics.databoard/src/org/simantics/databoard/method/Client.java|Client.java]] put MethodInterface over TCP Socket.
\r
725 Server myServer = new Server(8192, mi);
\r
726 MethodInterface mi = new Client("localhost", 8192);
\r
728 MethodInterface with Server and Client together forms a Remote Procedure Call (RPC) mechanism.
\r
729 public interface MyInterface { String helloWorld(String msg); }
\r
732 MethodInterface mi = Methods.bindInterface( MyInterface.class, myObject );
\r
733 Server myServer = new Server(8192, mi);
\r
736 MethodInterface mi = new Client("localhost", 8192);
\r
737 MyInterface myObject = Methods.createProxy( MyInterface.class, mi );
\r
739 [[Category: Data management & Experiment Control]]
\r