/******************************************************************************* * 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 *******************************************************************************/ 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; /** * This ia a facade class for the binding services. * * @author Toni Kalajainen */ 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 /** 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 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. * * DataType | Class of the bound instance * ===================|================== * UnionType | GenericBinding.TaggedObject.class * OptionType | ValueContainer.class * RecordType | Object[].class * BooleanType | MutableBoolean.class * DoubleType | MutableDouble.class * FloatType | MutableFloat.class * ByteType | MutableByte.class * IntegerType | MutableInt.class * LongType | MutableLong.class * 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 * GenericBindingFactory and binding repository (Map).

* * @param type the type to create binding to * @return binding binding to a mutable class */ @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); } } /** * 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 * to the java classes. See more in package org.simantics.databoard.annotations. *

* * 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.

* * @see ClassBindingFactory * @param clazz * @return binding * @throws BindingConstructionException */ @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); } 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); } } /** * 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); } /** * 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) ); } } /** * Create an adapter that adapts two bindings of the same * data type. * * @param domain binding of the source instance * @param range binding of the result instance * @return result adapter * @throws AdapterConstructionException */ public static Adapter getAdapter(Binding domain, Binding range) throws AdapterConstructionException { return adapterFactory.getAdapter(domain, range, false, false); } /** * Create an adapter that adapts between two bindings of the same * data type. * * @param domain binding of the source instance * @param range binding of the result instance * @return result adapter * @throws AdapterConstructionException */ public static Adapter getAdapterUnchecked(Binding domain, Binding range) throws RuntimeAdapterConstructionException { try { return adapterFactory.getAdapter(domain, range, false, false); } catch (AdapterConstructionException e) { throw new RuntimeAdapterConstructionException(e); } } /** * Create a type adapter that adapts instances from one Datatype to * another. Type Adapter does the following conversions: * * o Number Types, e.g. long -> double * o Unit Types, e.g. mph -> km/h * o Record Types, for each field of the range, there must be equal in domain * o Union Types, for each tag type of the domain, there must be equal in range * * {@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 * e.g. from double to int. * * @param domain binding of the source instance * @param range binding of the result instance * @return adapter * @throws AdapterConstructionException */ public static Adapter getTypeAdapter(Binding domain, Binding range) throws AdapterConstructionException { return adapterFactory.getAdapter(domain, range, true, false); } /** * Create a type adapter that adapts instances from one DataType to * another. Type Adapter does the following conversions: * * o Number Types, e.g. long -> double * o Unit Types, e.g. mph -> km/h * o Record Types, for each field of the range, there must be equal in domain * o Union Types, for each tag type of the domain, there must be equal in range * * {@link AdaptException} is thrown at runtime, if number values are * not compatible, e.g. converting value 500 from Long to Byte. * Note, there is also a possibility of precision loss, e.g. when * converting from double to int. * * @param domain binding of the source instance * @param range binding of the result instance * @return result adapter * @throws AdapterConstructionException */ public static Adapter getTypeAdapterUnchecked(Binding domain, Binding range) { try { return adapterFactory.getAdapter(domain, range, true, false); } catch (AdapterConstructionException e) { throw new RuntimeAdapterConstructionException(e); } } /** * Adapt a value of one type to another. * * @param value * @param domain * @param range * @return adapted value * @throws AdapterConstructionException * @throws AdaptException */ public static Object adapt(Object value, Binding domain, Binding range) 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); } } catch (AdapterConstructionException | BindingException e) { throw new AdaptException(e); } } /** * 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 * @param domain * @param range * @return adapted value * @throws AdapterConstructionException * @throws AdaptException */ 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); } 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)); } } /** * Adapt and clone a value instance to another type. Immutable * bindings may return the argument as is, others return a cloned copy. * * @param value * @param domain * @param range * @return adapted value * @throws AdapterConstructionException * @throws AdaptException */ 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); } } return adapterFactory.getAdapter(domain, range, true, true).adapt(value); } catch (AdapterConstructionException e) { throw new AdaptException(e); } } /** * 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. * * @param value * @param domain * @param range * @return adapted value * @throws AdapterConstructionException * @throws AdaptException */ public static Object cloneUnchecked(Object value, Binding domain, Binding range) throws RuntimeAdapterConstructionException, RuntimeAdaptException { try { return adapterFactory.getAdapter(domain, range, true, true).adapt(value); } catch (AdaptException e) { throw new RuntimeAdaptException(e); } catch (RuntimeAdapterConstructionException e) { throw new RuntimeAdaptException(new AdaptException(e.getCause())); } catch (AdapterConstructionException e) { throw new RuntimeAdaptException(new AdaptException(e)); } } /** * Compares two data values for order. Returns a negative integer, * 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.

* * The comparison function is defined at * http://dev.simantics.org/index.php/Org.simantics.datatype_Manual#CompareTo_and_Equals

* * Note, comparing 2 different number types will not result a value comparison. * Instead values have the following type precedence ByteType, IntegerType, LongType, * FloatType, and the highest DoubleType.

* * @param b1 Binding of o1 * @param o1 the first object to be compared. * @param b2 Binding of o2 * @param o2 the second object to be compared. * @return a negative integer, zero, or a positive integer as the * first argument is less than, equal to, or greater than the * second. * @throws BindingException if object cannot be handled by a binding */ public static int compare(Binding b1, Object o1, Binding b2, Object o2) throws BindingException { return DataValueUtil.compare(b1, o1, b2, o2); } /** * Compare two data values for equality.

* * Note, comparing 2 different number types will not result a value comparison. * Instead values have the following type precedence ByteType, IntegerType, LongType, * FloatType, and the highest DoubleType.

* * @param b1 * @param o1 * @param b2 * @param o2 * @return true if equal * @throws BindingException */ public static boolean equals(Binding b1, Object o1, Binding b2, Object o2) throws BindingException { return DataValueUtil.equals(b1, o1, b2, o2); } 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(); DATATYPE = getBindingUnchecked(Datatype.class); } }