X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2FBindings.java;h=b1f53d0b611bb542197cdf7bb299b60a3438149b;hp=3776a6b6fa8559d0dd021bed74035f041309bb5e;hb=95bce3521a3c97f463c3d533a36a606c7ae6f0aa;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java index 3776a6b6f..b1f53d0b6 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java @@ -1,166 +1,168 @@ -/******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - gitlab #313 + *******************************************************************************/ package org.simantics.databoard; -import java.io.IOException; -import java.util.Comparator; -import java.util.Map; - -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.databoard.adapter.Adapter; -import org.simantics.databoard.adapter.AdapterConstructionException; -import org.simantics.databoard.adapter.AdapterFactory; -import org.simantics.databoard.adapter.RuntimeAdaptException; -import org.simantics.databoard.adapter.RuntimeAdapterConstructionException; -import org.simantics.databoard.annotations.ArgumentImpl; -import org.simantics.databoard.annotations.Arguments; -import org.simantics.databoard.binding.ArrayBinding; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.BooleanBinding; -import org.simantics.databoard.binding.ByteBinding; -import org.simantics.databoard.binding.DoubleBinding; -import org.simantics.databoard.binding.FloatBinding; -import org.simantics.databoard.binding.IntegerBinding; -import org.simantics.databoard.binding.LongBinding; -import org.simantics.databoard.binding.StringBinding; -import org.simantics.databoard.binding.VariantBinding; -import org.simantics.databoard.binding.classfactory.TypeClassFactory; -import org.simantics.databoard.binding.error.BindingConstructionException; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; -import org.simantics.databoard.binding.factory.BindingRepository; -import org.simantics.databoard.binding.factory.TypeBindingFactory; -import org.simantics.databoard.binding.impl.BooleanArrayBinding; -import org.simantics.databoard.binding.impl.BooleanBindingDefault; -import org.simantics.databoard.binding.impl.ByteArrayBinding; -import org.simantics.databoard.binding.impl.ByteBindingDefault; -import org.simantics.databoard.binding.impl.DoubleArrayBinding; -import org.simantics.databoard.binding.impl.DoubleBindingDefault; -import org.simantics.databoard.binding.impl.FloatArrayBinding; -import org.simantics.databoard.binding.impl.FloatBindingDefault; -import org.simantics.databoard.binding.impl.IntArrayBinding; -import org.simantics.databoard.binding.impl.IntegerBindingDefault; -import org.simantics.databoard.binding.impl.LongArrayBinding; -import org.simantics.databoard.binding.impl.LongBindingDefault; -import org.simantics.databoard.binding.impl.StringArrayBinding; -import org.simantics.databoard.binding.impl.StringBindingDefault; -import org.simantics.databoard.binding.impl.UnsignedByteBinding; -import org.simantics.databoard.binding.impl.UnsignedIntegerBinding; -import org.simantics.databoard.binding.impl.UnsignedLongBinding; -import org.simantics.databoard.binding.mutable.MutableBooleanBinding; -import org.simantics.databoard.binding.mutable.MutableByteBinding; -import org.simantics.databoard.binding.mutable.MutableDoubleBinding; -import org.simantics.databoard.binding.mutable.MutableFloatBinding; -import org.simantics.databoard.binding.mutable.MutableIntegerBinding; -import org.simantics.databoard.binding.mutable.MutableLongBinding; -import org.simantics.databoard.binding.mutable.MutableStringBinding; -import org.simantics.databoard.binding.mutable.MutableVariantBinding; -import org.simantics.databoard.binding.reflection.BindingProvider; -import org.simantics.databoard.binding.reflection.BindingRequest; -import org.simantics.databoard.binding.reflection.ClassBindingFactory; -import org.simantics.databoard.binding.reflection.VoidBinding; -import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; -import org.simantics.databoard.serialization.Serializer; -import org.simantics.databoard.serialization.SerializerConstructionException; -import org.simantics.databoard.serialization.SerializerFactory; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.util.DataValueUtil; +import java.io.IOException; +import java.util.Comparator; +import java.util.Map; + +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.adapter.Adapter; +import org.simantics.databoard.adapter.AdapterConstructionException; +import org.simantics.databoard.adapter.AdapterFactory; +import org.simantics.databoard.adapter.RuntimeAdaptException; +import org.simantics.databoard.adapter.RuntimeAdapterConstructionException; +import org.simantics.databoard.annotations.ArgumentImpl; +import org.simantics.databoard.annotations.Arguments; +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.BooleanBinding; +import org.simantics.databoard.binding.ByteBinding; +import org.simantics.databoard.binding.DoubleBinding; +import org.simantics.databoard.binding.FloatBinding; +import org.simantics.databoard.binding.IntegerBinding; +import org.simantics.databoard.binding.LongBinding; +import org.simantics.databoard.binding.StringBinding; +import org.simantics.databoard.binding.VariantBinding; +import org.simantics.databoard.binding.classfactory.TypeClassFactory; +import org.simantics.databoard.binding.error.BindingConstructionException; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.databoard.binding.factory.BindingRepository; +import org.simantics.databoard.binding.factory.TypeBindingFactory; +import org.simantics.databoard.binding.impl.BooleanArrayBinding; +import org.simantics.databoard.binding.impl.BooleanBindingDefault; +import org.simantics.databoard.binding.impl.ByteArrayBinding; +import org.simantics.databoard.binding.impl.ByteBindingDefault; +import org.simantics.databoard.binding.impl.DoubleArrayBinding; +import org.simantics.databoard.binding.impl.DoubleBindingDefault; +import org.simantics.databoard.binding.impl.FloatArrayBinding; +import org.simantics.databoard.binding.impl.FloatBindingDefault; +import org.simantics.databoard.binding.impl.IntArrayBinding; +import org.simantics.databoard.binding.impl.IntegerBindingDefault; +import org.simantics.databoard.binding.impl.LongArrayBinding; +import org.simantics.databoard.binding.impl.LongBindingDefault; +import org.simantics.databoard.binding.impl.StringArrayBinding; +import org.simantics.databoard.binding.impl.StringBindingDefault; +import org.simantics.databoard.binding.impl.UnsignedByteBinding; +import org.simantics.databoard.binding.impl.UnsignedIntegerBinding; +import org.simantics.databoard.binding.impl.UnsignedLongBinding; +import org.simantics.databoard.binding.mutable.MutableBooleanBinding; +import org.simantics.databoard.binding.mutable.MutableByteBinding; +import org.simantics.databoard.binding.mutable.MutableDoubleBinding; +import org.simantics.databoard.binding.mutable.MutableFloatBinding; +import org.simantics.databoard.binding.mutable.MutableIntegerBinding; +import org.simantics.databoard.binding.mutable.MutableLongBinding; +import org.simantics.databoard.binding.mutable.MutableStringBinding; +import org.simantics.databoard.binding.mutable.MutableVariantBinding; +import org.simantics.databoard.binding.reflection.BindingProvider; +import org.simantics.databoard.binding.reflection.BindingRequest; +import org.simantics.databoard.binding.reflection.ClassBindingFactory; +import org.simantics.databoard.binding.reflection.VoidBinding; +import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; +import org.simantics.databoard.serialization.Serializer; +import org.simantics.databoard.serialization.SerializerConstructionException; +import org.simantics.databoard.serialization.SerializerScheme; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.util.DataValueUtil; /** * This ia a facade class for the binding services. * * @author Toni Kalajainen */ -public class Bindings { - +public class Bindings { + public static final Databoard databoard; - - // Repositories - - /** Repository of mutable bindings */ - public static final Map mutableBindingRepository; - - /** Repository of default bindings */ - public static final Map defaultBindingRepository; - - /** Repository of class Bindings */ - public static final BindingRepository bindingRepository; - - /** Repository of serializers */ - public static final Map serializerRepository; - - - // Factories - + + // Repositories + + /** Repository of mutable bindings */ + public static final Map mutableBindingRepository; + + /** Repository of default bindings */ + public static final Map defaultBindingRepository; + + /** Repository of class Bindings */ + public static final BindingRepository bindingRepository; + + /** Repository of serializers */ + public static final Map serializerRepository; + + + // Factories + /** Mutable Bindings Factory */ - public static final TypeBindingFactory mutableBindingFactory; - - /** Default Bindings Factory */ - public static final TypeBindingFactory defaultBindingFactory; - - /** Reflection based Binding Factory, create binding to class */ - public static final ClassBindingFactory classBindingFactory; - - /** Serializer Factory */ - public static final SerializerFactory serializationFactory; - - /** Adapter Factory */ - public static final AdapterFactory adapterFactory; - - /** Class Factory */ - public static final TypeClassFactory typeClassFactory; - - - // Bindings to various primitives - public static final StringBinding STRING; // java.lang.String - public static final IntegerBinding INTEGER; // java.lang.Integer - public static final BooleanBinding BOOLEAN; // java.lang.Boolean - public static final ByteBinding BYTE; // java.lang.Byte - public static final LongBinding LONG; // java.lang.Long - public static final DoubleBinding DOUBLE; // java.lang.Double - public static final FloatBinding FLOAT; // java.lang.Float - public static final VariantBinding VARIANT; // Variant - public static final VariantBinding OBJECT; // java.lang.Object ( as variant ) - public static final VariantBinding STR_VARIANT; // java.lang.String ( as variant ) - - public static final Binding VOID; // void ( as {} ) - public static final Binding BEAN; // Bean ( as variant ) - - public static final ArrayBinding BOOLEAN_ARRAY; // boolean[] - public static final ArrayBinding BYTE_ARRAY; // byte[] - public static final ArrayBinding INT_ARRAY; // int[] - public static final ArrayBinding LONG_ARRAY; // long[] - public static final ArrayBinding FLOAT_ARRAY; // float[] - public static final ArrayBinding DOUBLE_ARRAY; // double[] - public static final ArrayBinding STRING_ARRAY; // String[] - - public static final StringBinding MUTABLE_STRING; // MutableString - public static final IntegerBinding MUTABLE_INTEGER; // MutableInteger - public static final BooleanBinding MUTABLE_BOOLEAN; // MutableBoolean - public static final ByteBinding MUTABLE_BYTE; // MutableByte - public static final LongBinding MUTABLE_LONG; // MutableLong - public static final FloatBinding MUTABLE_FLOAT; // MutableFloat - public static final DoubleBinding MUTABLE_DOUBLE; // MutableDouble - public static final VariantBinding MUTABLE_VARIANT; // MutableVariant - - public static final IntegerBinding UNSIGNED_INTEGER; // UnsignedInteger.Immutable - public static final ByteBinding UNSIGNED_BYTE; // UnsignedByte.Immutable - public static final LongBinding UNSIGNED_LONG; // UnsignedLong.Immutable - - public static final IntegerBinding MUTABLE_UNSIGNED_INTEGER; // UnsignedInteger.Mutable - public static final ByteBinding MUTABLE_UNSIGNED_BYTE; // UnsignedByte.Mutable - public static final LongBinding MUTABLE_UNSIGNED_LONG; // UnsignedLong.Mutable - + public static final TypeBindingFactory mutableBindingFactory; + + /** Default Bindings Factory */ + public static final TypeBindingFactory defaultBindingFactory; + + /** Reflection based Binding Factory, create binding to class */ + public static final ClassBindingFactory classBindingFactory; + + /** Serializer Factory */ + public static final SerializerScheme serializationFactory; + + /** Adapter Factory */ + public static final AdapterFactory adapterFactory; + + /** Class Factory */ + public static final TypeClassFactory typeClassFactory; + + + // Bindings to various primitives + public static final StringBinding STRING; // java.lang.String + public static final IntegerBinding INTEGER; // java.lang.Integer + public static final BooleanBinding BOOLEAN; // java.lang.Boolean + public static final ByteBinding BYTE; // java.lang.Byte + public static final LongBinding LONG; // java.lang.Long + public static final DoubleBinding DOUBLE; // java.lang.Double + public static final FloatBinding FLOAT; // java.lang.Float + public static final VariantBinding VARIANT; // Variant + public static final VariantBinding OBJECT; // java.lang.Object ( as variant ) + public static final VariantBinding STR_VARIANT; // java.lang.String ( as variant ) + + public static final Binding VOID; // void ( as {} ) + public static final Binding BEAN; // Bean ( as variant ) + public static final Binding DATATYPE; // org.simantics.databoard.type.Datatype + + public static final ArrayBinding BOOLEAN_ARRAY; // boolean[] + public static final ArrayBinding BYTE_ARRAY; // byte[] + public static final ArrayBinding INT_ARRAY; // int[] + public static final ArrayBinding LONG_ARRAY; // long[] + public static final ArrayBinding FLOAT_ARRAY; // float[] + public static final ArrayBinding DOUBLE_ARRAY; // double[] + public static final ArrayBinding STRING_ARRAY; // String[] + + public static final StringBinding MUTABLE_STRING; // MutableString + public static final IntegerBinding MUTABLE_INTEGER; // MutableInteger + public static final BooleanBinding MUTABLE_BOOLEAN; // MutableBoolean + public static final ByteBinding MUTABLE_BYTE; // MutableByte + public static final LongBinding MUTABLE_LONG; // MutableLong + public static final FloatBinding MUTABLE_FLOAT; // MutableFloat + public static final DoubleBinding MUTABLE_DOUBLE; // MutableDouble + public static final VariantBinding MUTABLE_VARIANT; // MutableVariant + + public static final IntegerBinding UNSIGNED_INTEGER; // UnsignedInteger.Immutable + public static final ByteBinding UNSIGNED_BYTE; // UnsignedByte.Immutable + public static final LongBinding UNSIGNED_LONG; // UnsignedLong.Immutable + + public static final IntegerBinding MUTABLE_UNSIGNED_INTEGER; // UnsignedInteger.Mutable + public static final ByteBinding MUTABLE_UNSIGNED_BYTE; // UnsignedByte.Mutable + public static final LongBinding MUTABLE_UNSIGNED_LONG; // UnsignedLong.Mutable + /** * Get or create a binding that is completely mutable java class. * @@ -178,11 +180,11 @@ public class Bindings { * StringType | ValueContainer.class * ArrayType | ArrayList.class * MapType | TreeMap.class - * VariantType | MutableVariant.class - * - * Note, requesting a binding with this convenience method stores the - * binding and the type with strong reference, thus preventing garbage - * collection. To allow garbage collection, please use another instance of + * VariantType | MutableVariant.class + * + * Note, requesting a binding with this convenience method stores the + * binding and the type with strong reference, thus preventing garbage + * collection. To allow garbage collection, please use another instance of * GenericBindingFactory and binding repository (Map).

* * @param type the type to create binding to @@ -190,86 +192,86 @@ public class Bindings { */ @SuppressWarnings("unchecked") public static T getMutableBinding(Datatype type) { - try { - Binding binding = mutableBindingRepository.get(type); - if (binding!=null) return (T) binding; - synchronized(mutableBindingRepository) { - return (T) mutableBindingFactory.getBinding(type); - } - } catch (BindingConstructionException e) { - // Unexpected - if error is thrown there is fault in GenericBindingScheme - throw new RuntimeBindingConstructionException(e); + try { + Binding binding = mutableBindingRepository.get(type); + if (binding!=null) return (T) binding; + synchronized(mutableBindingRepository) { + return (T) mutableBindingFactory.getBinding(type); + } + } catch (BindingConstructionException e) { + // Unexpected - if error is thrown there is fault in GenericBindingScheme + throw new RuntimeBindingConstructionException(e); } - } - - /** - * Get or create a binding based on default java classes, such as - * Integer.class, or byte[].class. The result is often binding for an - * immutable classs. These bindings are more efficient than mutable bindings (above). - * - * DataType | Class of the bound instance - * ===================|================== - * BooleanType | Boolean.class - * ByteType | Byte.class - * FloatType | Float.class - * DoubleType | Double.class - * IntegerType | Int.class - * LongType | Long.class - * StringType | String.class - * UnionType | TaggedObject.class - * OptionType | ValueContainer.class - * RecordType | Object[].class - * MapType | TreeMap.class - * VariantType | Variant.class - * ArrayType(Boolean) | boolean[].class - * ArrayType(Byte) | byte[].class - * ArrayType(Integer) | int[].class - * ArrayType(Long) | long[].class - * ArrayType(Float) | float[].class - * ArrayType(Double) | double[].class - * ArrayType(Byte) | byte[].class - * ArrayType( T ) | Object[].class - * - * Note, requesting a binding with this convenience method stores the - * binding and the type with strong reference, thus preventing garbage - * collection. To allow garbage collection, please use another instance of - * DefaultBindingFactory and binding repository (Map).

- * - * @param type the type to create binding to - * @return binding binding to a mutable class - */ - @SuppressWarnings("unchecked") - public static T getBinding(Datatype type) { - try { - Binding binding = defaultBindingRepository.get(type); - if (binding!=null) return (T) binding; - synchronized(defaultBindingRepository) { - return (T) defaultBindingFactory.getBinding(type); - } - } catch (BindingConstructionException e) { - // Unexpected - if error is thrown there is fault in DefaultBindingScheme - throw new RuntimeBindingConstructionException(e); - } - } + } + + /** + * Get or create a binding based on default java classes, such as + * Integer.class, or byte[].class. The result is often binding for an + * immutable classs. These bindings are more efficient than mutable bindings (above). + * + * DataType | Class of the bound instance + * ===================|================== + * BooleanType | Boolean.class + * ByteType | Byte.class + * FloatType | Float.class + * DoubleType | Double.class + * IntegerType | Int.class + * LongType | Long.class + * StringType | String.class + * UnionType | TaggedObject.class + * OptionType | ValueContainer.class + * RecordType | Object[].class + * MapType | TreeMap.class + * VariantType | Variant.class + * ArrayType(Boolean) | boolean[].class + * ArrayType(Byte) | byte[].class + * ArrayType(Integer) | int[].class + * ArrayType(Long) | long[].class + * ArrayType(Float) | float[].class + * ArrayType(Double) | double[].class + * ArrayType(Byte) | byte[].class + * ArrayType( T ) | Object[].class + * + * Note, requesting a binding with this convenience method stores the + * binding and the type with strong reference, thus preventing garbage + * collection. To allow garbage collection, please use another instance of + * DefaultBindingFactory and binding repository (Map).

+ * + * @param type the type to create binding to + * @return binding binding to a mutable class + */ + @SuppressWarnings("unchecked") + public static T getBinding(Datatype type) { + try { + Binding binding = defaultBindingRepository.get(type); + if (binding!=null) return (T) binding; + synchronized(defaultBindingRepository) { + return (T) defaultBindingFactory.getBinding(type); + } + } catch (BindingConstructionException e) { + // Unexpected - if error is thrown there is fault in DefaultBindingScheme + throw new RuntimeBindingConstructionException(e); + } + } /** - * Get a binding to a Java Class. Details can be added by placing annotations + * Get a binding to a Java Class. Details can be added by placing annotations * to the java classes. See more in package org.simantics.databoard.annotations. *

* - * Whether the result is a completely mutable or not depends on the + * Whether the result is a completely mutable or not depends on the * requested class. For instance, fields such as Boolean, Integer, Long * are not mutable, instead MutableBoolean, MutableInteger and MutableLong are. - * The length of Object[] is not mutable, but length of List is.

- * - * Note, requesting a binding with this convenience method stores the - * binding and the class with strong reference, thus preventing garbage - * collection. To allow garbage collection, please use another instance of - * BindingFactory and binding repository (Map).

- * - * Is asm library is available, the binding is bytecode generated. Then read - * and write operations are direct get/set calls or direct field read/writes. - * There is no reflection used.

+ * The length of Object[] is not mutable, but length of List is.

+ * + * Note, requesting a binding with this convenience method stores the + * binding and the class with strong reference, thus preventing garbage + * collection. To allow garbage collection, please use another instance of + * BindingFactory and binding repository (Map).

+ * + * Is asm library is available, the binding is bytecode generated. Then read + * and write operations are direct get/set calls or direct field read/writes. + * There is no reflection used.

* * @see ClassBindingFactory * @param clazz @@ -279,276 +281,270 @@ public class Bindings { @SuppressWarnings("unchecked") public static T getBinding(Class clazz) throws BindingConstructionException - { - Binding binding = bindingRepository.get( clazz ); - if (binding != null) { - return (T) binding; - } - - BindingRequest request = new BindingRequest( clazz ); - synchronized(classBindingFactory) { - binding = classBindingFactory.construct(request); + { + Binding binding = bindingRepository.get( clazz ); + if (binding != null) { + return (T) binding; + } + + BindingRequest request = new BindingRequest( clazz ); + synchronized(classBindingFactory) { + binding = classBindingFactory.construct(request); } return (T) binding; - } - - @SuppressWarnings("unchecked") - public static T getBinding(BindingRequest request) - throws BindingConstructionException - { - synchronized(classBindingFactory) { - return (T) classBindingFactory.construct(request); - } - } - - /** - * Get a binding for a Java Class. Use this method to acquire class - * parameters for a generics class.

- * - * Example 1: - * - * Binding binding = Bindings.getBinding(Map.class, String.class, Integer.class); - * Map map = (Map) binding.createDefault(); - * - * Example 2: - * - * Binding d = Bindings.getBinding(List.class, Integer.class); - * List list = (List) d.createRandom(5); - * - * Example 3: - * - * Binding d = Bindings.getBinding(List.class, List.class, Integer.class); - * List> list = (List>) d.createRandom(5); - * - * @see ClassBindingFactory - * @param clazz - * @return binding - * @throws BindingConstructionException - */ - @SuppressWarnings("unchecked") - public static T getBinding(Class clazz, Class...parameters) - throws BindingConstructionException - { - BindingRequest request = new BindingRequest( clazz, parameters ); - synchronized(classBindingFactory) { - return (T) classBindingFactory.construct(request); - } - } - - /** - * Try to get a binding for the actual class of a Java object. - * @param obj A Java object - * @return A binding for the class of the object - * @throws BindingConstructionException if no binding can be constructed - */ - public static T getInstanceBinding(Object obj) - throws BindingConstructionException - { - return getBinding(obj.getClass()); - } - - /** - * Read binding and type from a class. DataType details and parameters - * are read as annotations placed in the class. - * (See org.simantics.databoard.annotations) - *

- * As an exception, in the subclasses of {@link Throwable}, the fields of - * Throwable are omited. - *

- * This method is used for well-known classes where the caller is 100% sure - * that a binding is construable without exception.

- * - * @param clazz - * @return binding - * @throws RuntimeBindingConstructionException - */ - @SuppressWarnings("unchecked") - public static T getBindingUnchecked(Class clazz) - throws RuntimeBindingConstructionException - { - try { - return (T) getBinding(clazz); - } catch (BindingConstructionException e) { - throw new RuntimeBindingConstructionException(e); - } + } + + @SuppressWarnings("unchecked") + public static T getBinding(BindingRequest request) + throws BindingConstructionException + { + synchronized(classBindingFactory) { + return (T) classBindingFactory.construct(request); + } + } + + /** + * Get a binding for a Java Class. Use this method to acquire class + * parameters for a generics class.

+ * + * Example 1: + * + * Binding binding = Bindings.getBinding(Map.class, String.class, Integer.class); + * Map map = (Map) binding.createDefault(); + * + * Example 2: + * + * Binding d = Bindings.getBinding(List.class, Integer.class); + * List list = (List) d.createRandom(5); + * + * Example 3: + * + * Binding d = Bindings.getBinding(List.class, List.class, Integer.class); + * List> list = (List>) d.createRandom(5); + * + * @see ClassBindingFactory + * @param clazz + * @return binding + * @throws BindingConstructionException + */ + @SuppressWarnings("unchecked") + public static T getBinding(Class clazz, Class...parameters) + throws BindingConstructionException + { + BindingRequest request = new BindingRequest( clazz, parameters ); + synchronized(classBindingFactory) { + return (T) classBindingFactory.construct(request); + } + } + + /** + * Try to get a binding for the actual class of a Java object. + * @param obj A Java object + * @return A binding for the class of the object + * @throws BindingConstructionException if no binding can be constructed + */ + public static T getInstanceBinding(Object obj) + throws BindingConstructionException + { + return getBinding(obj.getClass()); + } + + /** + * Read binding and type from a class. DataType details and parameters + * are read as annotations placed in the class. + * (See org.simantics.databoard.annotations) + *

+ * As an exception, in the subclasses of {@link Throwable}, the fields of + * Throwable are omited. + *

+ * This method is used for well-known classes where the caller is 100% sure + * that a binding is construable without exception.

+ * + * @param clazz + * @return binding + * @throws RuntimeBindingConstructionException + */ + @SuppressWarnings("unchecked") + public static T getBindingUnchecked(Class clazz) + throws RuntimeBindingConstructionException + { + try { + return (T) getBinding(clazz); + } catch (BindingConstructionException e) { + throw new RuntimeBindingConstructionException(e); + } + } + + /** + * Get a binding for a Java Class. Use this method to acquire class + * parameters for a generics class.

+ * + * Example 1: + * + * Binding binding = Bindings.getBinding(Map.class, String.class, Integer.class); + * Map map = (Map) binding.createDefault(); + * + * Example 2: + * + * Binding d = Bindings.getBinding(List.class, Integer.class); + * List list = (List) d.createRandom(5); + * + * Example 3: + * + * Binding d = Bindings.getBinding(List.class, List.class, Integer.class); + * List> list = (List>) d.createRandom(5); + * + * @see ClassBindingFactory + * @param clazz + * @return binding + * @throws BindingConstructionException + */ + @SuppressWarnings("unchecked") + public static T getBindingUnchecked(Class clazz, Class...parameters) + throws RuntimeBindingConstructionException + { + try { + Arguments args = new ArgumentImpl(parameters); + BindingRequest request = new BindingRequest( clazz, args ); + Binding binding = bindingRepository.get( request ); + if (binding!=null); + synchronized(classBindingFactory) { + binding = classBindingFactory.construct(request); + } + return (T) binding; + } catch (BindingConstructionException e) { + throw new RuntimeBindingConstructionException(e); + } } - - /** - * Get a binding for a Java Class. Use this method to acquire class - * parameters for a generics class.

- * - * Example 1: - * - * Binding binding = Bindings.getBinding(Map.class, String.class, Integer.class); - * Map map = (Map) binding.createDefault(); - * - * Example 2: - * - * Binding d = Bindings.getBinding(List.class, Integer.class); - * List list = (List) d.createRandom(5); - * - * Example 3: - * - * Binding d = Bindings.getBinding(List.class, List.class, Integer.class); - * List> list = (List>) d.createRandom(5); - * - * @see ClassBindingFactory - * @param clazz - * @return binding - * @throws BindingConstructionException - */ - @SuppressWarnings("unchecked") - public static T getBindingUnchecked(Class clazz, Class...parameters) - throws RuntimeBindingConstructionException - { - try { - Arguments args = new ArgumentImpl(parameters); - BindingRequest request = new BindingRequest( clazz, args ); - Binding binding = bindingRepository.get( request ); - if (binding!=null); - synchronized(classBindingFactory) { - binding = classBindingFactory.construct(request); - } - return (T) binding; - } catch (BindingConstructionException e) { - throw new RuntimeBindingConstructionException(e); - } - } - - /** - * Add a simple binding to reflection binding factory. - * - * @param binding - * @param clazz - * @param parameters parameter classes - */ - public static void addBinding( Binding binding, Class clazz, Class...parameters ) - { - ArgumentImpl args = new ArgumentImpl( parameters ); - BindingRequest request = new BindingRequest( clazz, args ); - bindingRepository.put( request, binding ); - } - - /** - * Add binding factory for compositive bindings - * - * @param factory - */ - public static void addBindingFactory( BindingProvider factory ) - { - classBindingFactory.addFactory( factory ); - } - - /** - * Creates a bean class - * @param type - * @return class - */ - public static BindingRequest getBeanBindingRequest( Datatype type ) throws RuntimeBindingConstructionException { - try { - return typeClassFactory.getClass(type); - } catch (BindingConstructionException e) { - throw new RuntimeBindingConstructionException(e); - } - } - - /** - * Creates a bean class - * @param type - * @return class - */ - public static Class getBeanClass( Datatype type ) throws BindingConstructionException { - BindingRequest br = typeClassFactory.getClass(type); - return br.getClazz(); - } - - /** - * Create binding from datatype that instantiates java classes. - * RecordTypes are Beans, UnionTypes are Classes with @Union annotation, - * ArrayTypes are []. - * - * @param type - * @return class - */ - public static Binding getBeanBinding( Datatype type ) throws RuntimeBindingConstructionException { - try { - BindingRequest br = typeClassFactory.getClass(type); - return getBinding( br ); - } catch (BindingConstructionException e) { - throw new RuntimeBindingConstructionException(e); - } - } - - /** - * Get a default array binding for a given component type binding. - * Returns a primitive array type binding for primitive types and an - * ObjectArrayBinding for others. - * - * @param componentBinding A binding for a component type - * @return A binding for the array type - */ - public static Binding getArrayBinding(Binding componentBinding) { - return getBinding(new ArrayType(componentBinding.type())); - } - - /** - * Get serializer that follows Databoard serialization spec. - * - * @param binding - * @return serializer - * @throws SerializerConstructionException - */ - public static Serializer getSerializer(Binding binding) throws SerializerConstructionException { - return serializationFactory.construct(binding); + + /** + * Add a simple binding to reflection binding factory. + * + * @param binding + * @param clazz + * @param parameters parameter classes + */ + public static void addBinding( Binding binding, Class clazz, Class...parameters ) + { + ArgumentImpl args = new ArgumentImpl( parameters ); + BindingRequest request = new BindingRequest( clazz, args ); + bindingRepository.put( request, binding ); + } + + /** + * Add binding factory for compositive bindings + * + * @param factory + */ + public static void addBindingFactory( BindingProvider factory ) + { + classBindingFactory.addFactory( factory ); + } + + /** + * Creates a bean class + * @param type + * @return class + */ + public static BindingRequest getBeanBindingRequest( Datatype type ) throws RuntimeBindingConstructionException { + try { + return typeClassFactory.getClass(type); + } catch (BindingConstructionException e) { + throw new RuntimeBindingConstructionException(e); + } + } + + /** + * Creates a bean class + * @param type + * @return class + */ + public static Class getBeanClass( Datatype type ) throws BindingConstructionException { + BindingRequest br = typeClassFactory.getClass(type); + return br.getClazz(); + } + + /** + * Create binding from datatype that instantiates java classes. + * RecordTypes are Beans, UnionTypes are Classes with @Union annotation, + * ArrayTypes are []. + * + * @param type + * @return class + */ + public static Binding getBeanBinding( Datatype type ) throws RuntimeBindingConstructionException { + try { + BindingRequest br = typeClassFactory.getClass(type); + return getBinding( br ); + } catch (BindingConstructionException e) { + throw new RuntimeBindingConstructionException(e); + } + } + + /** + * Get a default array binding for a given component type binding. + * Returns a primitive array type binding for primitive types and an + * ObjectArrayBinding for others. + * + * @param componentBinding A binding for a component type + * @return A binding for the array type + */ + public static Binding getArrayBinding(Binding componentBinding) { + return getBinding(new ArrayType(componentBinding.type())); + } + + /** + * Get serializer that follows Databoard serialization spec. + * + * @param binding + * @return serializer + * @throws SerializerConstructionException + */ + public static Serializer getSerializer(Binding binding) throws SerializerConstructionException { + return serializationFactory.getSerializer(binding); } - - /** - * Get serializer that follows Databoard serialization spec. - * - * @param binding - * @return serializer - * @throws RuntimeSerializerConstructionException - */ - public static Serializer getSerializerUnchecked(Binding binding) throws RuntimeSerializerConstructionException { - try { - return serializationFactory.construct(binding); - } catch (SerializerConstructionException e) { - throw new RuntimeSerializerConstructionException(e); - } - } - - /** - * Get serializer that follows Databoard serialization spec. - * - * @param clazz - * @return serializer - * @throws SerializerConstructionException - */ - public static Serializer getSerializer(Class clazz) throws SerializerConstructionException { - try { - Binding binding = getBinding(clazz); - return serializationFactory.construct(binding); - } catch (BindingConstructionException e) { - throw new SerializerConstructionException( e ); - } - } - - /** - * Get serializer that follows Databoard serialization spec. - * - * @param clazz - * @return serializer serializer - * @throws RuntimeSerializerConstructionException - */ - public static Serializer getSerializerUnchecked(Class clazz) throws RuntimeSerializerConstructionException { - try { - Binding binding = getBinding(clazz); - return serializationFactory.construct(binding); - } catch (SerializerConstructionException e) { - throw new RuntimeSerializerConstructionException(e); - } catch (BindingConstructionException e) { - throw new RuntimeSerializerConstructionException( new SerializerConstructionException(e) ); - } + + /** + * Get serializer that follows Databoard serialization spec. + * + * @param binding + * @return serializer + * @throws RuntimeSerializerConstructionException + */ + public static Serializer getSerializerUnchecked(Binding binding) throws RuntimeSerializerConstructionException { + return serializationFactory.getSerializerUnchecked(binding); + } + + /** + * Get serializer that follows Databoard serialization spec. + * + * @param clazz + * @return serializer + * @throws SerializerConstructionException + */ + public static Serializer getSerializer(Class clazz) throws SerializerConstructionException { + try { + Binding binding = getBinding(clazz); + return serializationFactory.getSerializer(binding); + } catch (BindingConstructionException e) { + throw new SerializerConstructionException( e ); + } + } + + /** + * Get serializer that follows Databoard serialization spec. + * + * @param clazz + * @return serializer serializer + * @throws RuntimeSerializerConstructionException + */ + public static Serializer getSerializerUnchecked(Class clazz) throws RuntimeSerializerConstructionException { + try { + Binding binding = getBinding(clazz); + return serializationFactory.getSerializerUnchecked(binding); + } catch (BindingConstructionException e) { + throw new RuntimeSerializerConstructionException( new SerializerConstructionException(e) ); + } } /** * Create an adapter that adapts two bindings of the same @@ -595,7 +591,7 @@ public class Bindings { * * {@link AdaptException} is thrown at runtime, if number conversion is not * posible, e.g. converting value 500 from Integer to Byte. - * Note, there is also a possibility of precision loss, in many conversions + * Note, there is also a possibility of precision loss, in many conversions * e.g. from double to int. * * @param domain binding of the source instance @@ -651,34 +647,34 @@ public class Bindings { throws AdaptException { try { - if (domain.equals(range)) { - return value; - } - else if (range instanceof VariantBinding) { - if (domain instanceof VariantBinding) { - // Copy variant contents directly - Binding contentBinding = ((VariantBinding)domain).getContentBinding( value ); - Object content = ((VariantBinding)domain).getContent( value ); - return ((VariantBinding)range).create( contentBinding, content ); - } - else { - // Default to just wrapping the value (avoid adapter construction to save memory) - return ((VariantBinding)range).create(domain, value); - } - } - else if (domain instanceof VariantBinding) { - return adapt(((VariantBinding)domain).getContent( value ), ((VariantBinding)domain).getContentBinding( value ), range ); - } - else { - return adapterFactory.getAdapter(domain, range, true, false).adapt(value); + if (domain.equals(range)) { + return value; + } + else if (range instanceof VariantBinding) { + if (domain instanceof VariantBinding) { + // Copy variant contents directly + Binding contentBinding = ((VariantBinding)domain).getContentBinding( value ); + Object content = ((VariantBinding)domain).getContent( value ); + return ((VariantBinding)range).create( contentBinding, content ); + } + else { + // Default to just wrapping the value (avoid adapter construction to save memory) + return ((VariantBinding)range).create(domain, value); + } + } + else if (domain instanceof VariantBinding) { + return adapt(((VariantBinding)domain).getContent( value ), ((VariantBinding)domain).getContentBinding( value ), range ); + } + else { + return adapterFactory.getAdapter(domain, range, true, false).adapt(value); } } catch (AdapterConstructionException | BindingException e) { throw new AdaptException(e); - } + } } /** - * Adapt a value of one type to another. Exceptions are run-time. Use this + * Adapt a value of one type to another. Exceptions are run-time. Use this * if it safe to assume the conversion will be successful. * * @param value @@ -690,27 +686,27 @@ public class Bindings { */ public static Object adaptUnchecked(Object value, Binding domain, Binding range) throws RuntimeAdapterConstructionException, RuntimeAdaptException - { + { try { - if (domain==range) { - return value; - } - if (range instanceof VariantBinding && !(domain instanceof VariantBinding)) { - // Default to just wrapping the value (avoid adapter construction to save memory) - return ((VariantBinding)range).create(domain, value); - } + if (domain==range) { + return value; + } + if (range instanceof VariantBinding && !(domain instanceof VariantBinding)) { + // Default to just wrapping the value (avoid adapter construction to save memory) + return ((VariantBinding)range).create(domain, value); + } return adapterFactory.getAdapter(domain, range, true, false).adaptUnchecked(value); } catch (RuntimeAdapterConstructionException e) { throw new RuntimeAdaptException(new AdaptException(e.getCause())); } catch (AdapterConstructionException e) { throw new RuntimeAdaptException(new AdaptException(e)); - } catch (BindingException e) { - throw new RuntimeAdaptException(new AdaptException(e)); + } catch (BindingException e) { + throw new RuntimeAdaptException(new AdaptException(e)); } } /** - * Adapt and clone a value instance to another type. Immutable + * Adapt and clone a value instance to another type. Immutable * bindings may return the argument as is, others return a cloned copy. * * @param value @@ -723,13 +719,13 @@ public class Bindings { public static Object clone(Object value, Binding domain, Binding range) throws AdaptException { - try { - if (domain==range) { - if (domain.isImmutable()) { - return value; - } else { - return domain.clone(value); - } + try { + if (domain==range) { + if (domain.isImmutable()) { + return value; + } else { + return domain.clone(value); + } } return adapterFactory.getAdapter(domain, range, true, true).adapt(value); } catch (AdapterConstructionException e) { @@ -741,9 +737,9 @@ public class Bindings { /** * Clone a value of one binding to another. Bindings that handle immutable values * may return the same instance, others will guarantee a complete copy. - * - * This method throws only runtime exceptions. Use this if it is safe to assume - * that the conversion will be successful. + * + * This method throws only runtime exceptions. Use this if it is safe to assume + * that the conversion will be successful. * * @param value * @param domain @@ -768,7 +764,7 @@ public class Bindings { /** * Compares two data values for order. Returns a negative integer, - * zero, or a positive integer if, the first argument precedes/lesser than + * zero, or a positive integer if, the first argument precedes/lesser than * the second, is equal to, or successor/greater than the second.

* * DataTypes of b1 and b2 are not equal, then data types are compared.

@@ -818,79 +814,88 @@ public class Bindings { public static Comparator createComparator(final Binding b1, final Binding b2) { return DataValueUtil.createComparator(b1, b2); - } - - /** - * Print the content of an object as a structure. - * Utility function for debug purposes. - * - * @param o - * @return content - */ - public static String toString(Object o) { - try { - Binding b = Bindings.getBinding( o.getClass() ); - return b.printValueDefinition(o, true); - } catch (BindingConstructionException e) { - return ""; - } catch (IOException e) { - return ""; - } catch (BindingException e) { - return ""; - } - } - - static { - STRING = new StringBindingDefault( Datatypes.STRING ); - INTEGER = new IntegerBindingDefault( Datatypes.INTEGER ); - BOOLEAN = new BooleanBindingDefault( Datatypes.BOOLEAN ); - BYTE = new ByteBindingDefault( Datatypes.BYTE ); - LONG = new LongBindingDefault( Datatypes.LONG ); - DOUBLE = new DoubleBindingDefault( Datatypes.DOUBLE ); - FLOAT = new FloatBindingDefault( Datatypes.FLOAT ); - VOID = VoidBinding.VOID_BINDING; - BOOLEAN_ARRAY = new BooleanArrayBinding( Datatypes.BOOLEAN_ARRAY, BOOLEAN ); - BYTE_ARRAY = new ByteArrayBinding( Datatypes.BYTE_ARRAY, BYTE ); - INT_ARRAY = new IntArrayBinding( Datatypes.INTEGER_ARRAY, INTEGER ); - LONG_ARRAY = new LongArrayBinding( Datatypes.LONG_ARRAY, LONG ); - FLOAT_ARRAY = new FloatArrayBinding( Datatypes.FLOAT_ARRAY, FLOAT ); - DOUBLE_ARRAY = new DoubleArrayBinding( Datatypes.DOUBLE_ARRAY, DOUBLE ); - STRING_ARRAY = new StringArrayBinding( Datatypes.STRING_ARRAY, STRING ); - UNSIGNED_INTEGER = new UnsignedIntegerBinding.Immutable( Datatypes.INTEGER ); - UNSIGNED_BYTE = new UnsignedByteBinding.Immutable( Datatypes.BYTE ); - UNSIGNED_LONG = new UnsignedLongBinding.Immutable( Datatypes.LONG ); - MUTABLE_STRING = new MutableStringBinding( Datatypes.STRING ); - MUTABLE_INTEGER = new MutableIntegerBinding( Datatypes.INTEGER ); - MUTABLE_BOOLEAN = new MutableBooleanBinding( Datatypes.BOOLEAN ); - MUTABLE_BYTE = new MutableByteBinding( Datatypes.BYTE ); - MUTABLE_LONG = new MutableLongBinding( Datatypes.LONG ); - MUTABLE_FLOAT = new MutableFloatBinding( Datatypes.FLOAT ); - MUTABLE_DOUBLE = new MutableDoubleBinding( Datatypes.DOUBLE ); - MUTABLE_UNSIGNED_INTEGER = new UnsignedIntegerBinding.Mutable( Datatypes.INTEGER ); - MUTABLE_UNSIGNED_BYTE = new UnsignedByteBinding.Mutable( Datatypes.BYTE ); - MUTABLE_UNSIGNED_LONG = new UnsignedLongBinding.Mutable( Datatypes.LONG ); - - databoard = new Databoard(); - - mutableBindingRepository = databoard.mutableBindingRepository; - defaultBindingRepository = databoard.defaultBindingRepository; - bindingRepository = databoard.bindingRepository; - serializerRepository = databoard.serializerRepository; - mutableBindingFactory = databoard.mutableBindingFactory; - defaultBindingFactory = databoard.defaultBindingFactory; - classBindingFactory = databoard.classBindingFactory; - serializationFactory = databoard.serializationFactory; - adapterFactory = databoard.adapterFactory; - typeClassFactory = databoard.typeClassFactory; - - BEAN = databoard.BEAN; - VARIANT = databoard.VARIANT; - MUTABLE_VARIANT = new MutableVariantBinding( classBindingFactory, adapterFactory ); - STR_VARIANT = databoard.STR_VARIANT; - OBJECT = databoard.OBJECT; - - databoard.initialize(); - } + } + + /** + * Print the content of an object as a structure. + * Utility function for debug purposes. + * + * @param o + * @return content + */ + public static String toString(Object o) { + try { + Binding b = Bindings.getBinding( o.getClass() ); + return b.printValueDefinition(o, true); + } catch (BindingConstructionException e) { + return ""; + } catch (IOException e) { + return ""; + } catch (BindingException e) { + return ""; + } + } + static { + STRING = new StringBindingDefault( Datatypes.STRING ); + INTEGER = new IntegerBindingDefault( Datatypes.INTEGER ); + BOOLEAN = new BooleanBindingDefault( Datatypes.BOOLEAN ); + BYTE = new ByteBindingDefault( Datatypes.BYTE ); + LONG = new LongBindingDefault( Datatypes.LONG ); + DOUBLE = new DoubleBindingDefault( Datatypes.DOUBLE ); + FLOAT = new FloatBindingDefault( Datatypes.FLOAT ); + VOID = VoidBinding.VOID_BINDING; + BOOLEAN_ARRAY = new BooleanArrayBinding( Datatypes.BOOLEAN_ARRAY, BOOLEAN ); + BYTE_ARRAY = new ByteArrayBinding( Datatypes.BYTE_ARRAY, BYTE ); + INT_ARRAY = new IntArrayBinding( Datatypes.INTEGER_ARRAY, INTEGER ); + LONG_ARRAY = new LongArrayBinding( Datatypes.LONG_ARRAY, LONG ); + FLOAT_ARRAY = new FloatArrayBinding( Datatypes.FLOAT_ARRAY, FLOAT ); + DOUBLE_ARRAY = new DoubleArrayBinding( Datatypes.DOUBLE_ARRAY, DOUBLE ); + STRING_ARRAY = new StringArrayBinding( Datatypes.STRING_ARRAY, STRING ); + UNSIGNED_INTEGER = new UnsignedIntegerBinding.Immutable( Datatypes.INTEGER ); + UNSIGNED_BYTE = new UnsignedByteBinding.Immutable( Datatypes.BYTE ); + UNSIGNED_LONG = new UnsignedLongBinding.Immutable( Datatypes.LONG ); + MUTABLE_STRING = new MutableStringBinding( Datatypes.STRING ); + MUTABLE_INTEGER = new MutableIntegerBinding( Datatypes.INTEGER ); + MUTABLE_BOOLEAN = new MutableBooleanBinding( Datatypes.BOOLEAN ); + MUTABLE_BYTE = new MutableByteBinding( Datatypes.BYTE ); + MUTABLE_LONG = new MutableLongBinding( Datatypes.LONG ); + MUTABLE_FLOAT = new MutableFloatBinding( Datatypes.FLOAT ); + MUTABLE_DOUBLE = new MutableDoubleBinding( Datatypes.DOUBLE ); + MUTABLE_UNSIGNED_INTEGER = new UnsignedIntegerBinding.Mutable( Datatypes.INTEGER ); + MUTABLE_UNSIGNED_BYTE = new UnsignedByteBinding.Mutable( Datatypes.BYTE ); + MUTABLE_UNSIGNED_LONG = new UnsignedLongBinding.Mutable( Datatypes.LONG ); + + databoard = new Databoard(); + + mutableBindingRepository = databoard.mutableBindingRepository; + defaultBindingRepository = databoard.defaultBindingRepository; + bindingRepository = databoard.bindingRepository; + serializerRepository = databoard.serializerRepository; + mutableBindingFactory = databoard.mutableBindingFactory; + defaultBindingFactory = databoard.defaultBindingFactory; + classBindingFactory = databoard.classBindingFactory; + serializationFactory = databoard.serializationFactory; + adapterFactory = databoard.adapterFactory; + typeClassFactory = databoard.typeClassFactory; + + BEAN = databoard.BEAN; + VARIANT = databoard.VARIANT; + MUTABLE_VARIANT = new MutableVariantBinding( classBindingFactory, adapterFactory ); + STR_VARIANT = databoard.STR_VARIANT; + OBJECT = databoard.OBJECT; + + databoard.initialize(); + + DATATYPE = getBindingUnchecked(Datatype.class); + /** + * {@link Datatype} class has annotations but it can be considered a "class + * request" as it is a fundamental building block of Databoard and it has a + * fixed structure. Therefore {@link BindingRepository#classMap} is allowed + * to contain a cached Datatype.class -> Binding mapping. + */ + bindingRepository.registerClassMapping(Datatype.class, DATATYPE); + } + }