]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/MutableBindingFactory.java
Improved Bindings.getBinding(Class) caching for Datatype.class
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / factory / MutableBindingFactory.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.binding.factory;
13
14 import java.util.Map;
15
16 import org.simantics.databoard.Bindings;
17 import org.simantics.databoard.binding.Binding;
18 import org.simantics.databoard.binding.error.BindingConstructionException;
19 import org.simantics.databoard.binding.impl.ArrayListBinding;
20 import org.simantics.databoard.binding.impl.TreeMapBinding;
21 import org.simantics.databoard.binding.mutable.ContainerOptionalBinding;
22 import org.simantics.databoard.binding.mutable.MutableBooleanBinding;
23 import org.simantics.databoard.binding.mutable.MutableByteBinding;
24 import org.simantics.databoard.binding.mutable.MutableDoubleBinding;
25 import org.simantics.databoard.binding.mutable.MutableFloatBinding;
26 import org.simantics.databoard.binding.mutable.MutableIntegerBinding;
27 import org.simantics.databoard.binding.mutable.MutableLongBinding;
28 import org.simantics.databoard.binding.mutable.MutableStringBinding;
29 import org.simantics.databoard.binding.mutable.UnionTaggedObjectBinding;
30 import org.simantics.databoard.type.ArrayType;
31 import org.simantics.databoard.type.BooleanType;
32 import org.simantics.databoard.type.ByteType;
33 import org.simantics.databoard.type.Datatype;
34 import org.simantics.databoard.type.DoubleType;
35 import org.simantics.databoard.type.FloatType;
36 import org.simantics.databoard.type.IntegerType;
37 import org.simantics.databoard.type.LongType;
38 import org.simantics.databoard.type.MapType;
39 import org.simantics.databoard.type.OptionalType;
40 import org.simantics.databoard.type.RecordType;
41 import org.simantics.databoard.type.StringType;
42 import org.simantics.databoard.type.UnionType;
43
44 /**
45  * MutableBindingScheme is a type to binding mapping that binds any DataType to an Object.
46  * All resulting bindings are completely mutable java classes.
47  * 
48  * DataType           | Class of the bound instance
49  * ===================|==================
50  * BooleanType        | MutableBoolean.class
51  * ByteType           | MutableByte.class
52  * FloatType          | MutableFloat.class
53  * DoubleType         | MutableDouble.class
54  * IntegerType        | MutableInt.class
55  * LongType           | MutableLong.class
56  * StringType         | MutableString.class
57  * UnionType          | TaggedObject.class
58  * OptionType         | ValueContainer.class
59  * RecordType         | Object[].class
60  * ArrayType          | ArrayList.class
61  * MapType            | TreeMap.class
62  * VariantType        | MutableVariant.class
63  *
64  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
65  */
66
67 public class MutableBindingFactory extends TypeBindingFactory {
68
69         /**
70          * Construct a binding factory.
71          */
72         public MutableBindingFactory() {
73                 super();
74         }
75         
76         /**
77          * Construct a scheme factory that appends constructed bindings to the user given
78          * repository  
79          * 
80          * @param repository repository where bindings are placed
81          */
82         public MutableBindingFactory(Map<Datatype, Binding> repository) {
83                 super(repository);
84         }
85
86         @Override
87         protected Binding doConstruct(Datatype type)
88                         throws BindingConstructionException {
89
90                 // Exact, non-annotated types
91                 if (type.equals( Bindings.BOOLEAN.type() )) return Bindings.MUTABLE_BOOLEAN;
92                 if (type.equals( Bindings.BYTE.type() )) return Bindings.MUTABLE_BYTE;
93                 if (type.equals( Bindings.INTEGER.type() )) return Bindings.MUTABLE_INTEGER;
94                 if (type.equals( Bindings.LONG.type() )) return Bindings.MUTABLE_LONG;
95                 if (type.equals( Bindings.FLOAT.type() )) return Bindings.MUTABLE_FLOAT;
96                 if (type.equals( Bindings.DOUBLE.type() )) return Bindings.MUTABLE_DOUBLE;
97                 if (type.equals( Bindings.STRING.type() )) return Bindings.MUTABLE_STRING;
98                 if (type.equals( Bindings.VARIANT.type() )) return Bindings.MUTABLE_VARIANT;
99                 
100                 // Annotated types 
101                 if (type instanceof BooleanType) return new MutableBooleanBinding((BooleanType)type);
102                 if (type instanceof DoubleType) return new MutableDoubleBinding((DoubleType)type);
103                 if (type instanceof FloatType) return new MutableFloatBinding((FloatType)type);
104                 if (type instanceof ByteType) return new MutableByteBinding((ByteType)type);
105                 if (type instanceof IntegerType) return new MutableIntegerBinding((IntegerType)type);
106                 if (type instanceof LongType) return new MutableLongBinding((LongType)type);
107                 if (type instanceof StringType) return new MutableStringBinding((StringType)type);
108                 
109                 // Constructed types
110                 if (type instanceof ArrayType) {
111                         ArrayType arrayType = (ArrayType) type;
112                         Datatype componentType = arrayType.componentType();
113
114                         ArrayListBinding binding = new ArrayListBinding(arrayType, null);
115                         inprogress.put(type, binding);
116                         binding.componentBinding = construct( componentType );                                          
117                         inprogress.remove(type);
118                         return binding;
119                 }
120                 
121                 if (type instanceof OptionalType) {
122                         OptionalType optionalType = (OptionalType) type;
123                         Datatype componentType = optionalType.componentType;
124                         ContainerOptionalBinding binding = new ContainerOptionalBinding( optionalType, null );
125                         inprogress.put(type, binding);
126                         binding.componentBinding = construct( componentType );
127                         inprogress.remove(type);
128                         return binding;
129                 }
130                 
131                 if (type instanceof RecordType) {                       
132                         RecordType recordType = (RecordType) type;
133                         Binding componentBindings[] = new Binding[ recordType.getComponentCount() ];
134                         RecordObjectArrayBinding binding = new RecordObjectArrayBinding(recordType, componentBindings);
135                         inprogress.put(type, binding);
136                         for (int i=0; i<componentBindings.length; i++) {
137                                 componentBindings[i] = construct( recordType.getComponentType(i) );
138                         }
139                         inprogress.remove(type);
140                         return binding;
141                 }
142                 
143                 if (type instanceof UnionType) {
144                         UnionType unionType = (UnionType) type;
145                         Binding componentBindings[] = new Binding[ unionType.components.length ];
146                         UnionTaggedObjectBinding binding = new UnionTaggedObjectBinding(unionType, componentBindings);
147                         inprogress.put(type, binding);
148                         for (int i=0; i<componentBindings.length; i++) {
149                                 componentBindings[i] = construct( unionType.getComponent(i).type );
150                         }
151                         inprogress.remove(type);
152                         return binding;
153                 }               
154                 
155                 if (type instanceof MapType) {                  
156                         MapType mapType = (MapType) type;
157                         TreeMapBinding binding = new TreeMapBinding(mapType, null, null);
158                         inprogress.put(type, binding);
159                         binding.setKeyBinding( construct(mapType.keyType) );
160                         binding.setValueBinding( construct(mapType.valueType) );
161                         inprogress.remove(type);
162                         return binding;
163                 }
164                 
165                 throw new BindingConstructionException("Unexpected, I don't know how to create binding for "+type);
166         }
167
168         @Override
169         public boolean supportsType(Datatype type) {
170                 // unexpected
171                 if (failures.containsKey(type)) return false;
172                 return true;
173         }
174         
175 }
176
177
178
179
180
181