1 /*******************************************************************************
2 * Copyright (c) 2010 Association for Decentralized Information Management in
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.databoard.adapter;
14 import java.util.ArrayList;
16 import org.simantics.databoard.binding.ArrayBinding;
17 import org.simantics.databoard.binding.Binding;
18 import org.simantics.databoard.binding.BooleanBinding;
19 import org.simantics.databoard.binding.ByteBinding;
20 import org.simantics.databoard.binding.DoubleBinding;
21 import org.simantics.databoard.binding.FloatBinding;
22 import org.simantics.databoard.binding.IntegerBinding;
23 import org.simantics.databoard.binding.LongBinding;
24 import org.simantics.databoard.binding.OptionalBinding;
25 import org.simantics.databoard.binding.RecordBinding;
26 import org.simantics.databoard.binding.StringBinding;
27 import org.simantics.databoard.binding.UnionBinding;
28 import org.simantics.databoard.binding.error.BindingException;
29 import org.simantics.databoard.binding.impl.ArrayListBinding;
30 import org.simantics.databoard.binding.impl.BooleanArrayBinding;
31 import org.simantics.databoard.binding.impl.ByteArrayBinding;
32 import org.simantics.databoard.binding.impl.DoubleArrayBinding;
33 import org.simantics.databoard.binding.impl.FloatArrayBinding;
34 import org.simantics.databoard.binding.impl.IntArrayBinding;
35 import org.simantics.databoard.binding.impl.LongArrayBinding;
38 * DefaultAdapter adapts anything to anything.
40 * @deprecated Use {@link AdapterFactory} instead (more efficient)
42 public class DefaultAdapter implements Adapter {
47 DefaultAdapter(Binding domain, Binding range) {
53 * Adapt instance of one binding to format of another binding.
54 * The datatype of the two bindings must be structurally equal.
56 * @param src source instance
58 * @throws AdaptException
60 public static Object adapt(Object src, Binding domain, Binding range)
64 if (domain instanceof RecordBinding && range instanceof RecordBinding)
66 RecordBinding srcRec = (RecordBinding) domain;
67 RecordBinding dstRec = (RecordBinding) range;
68 Object dst = dstRec.createPartial();
69 Object[] dstComponents = new Object[dstRec.componentBindings.length];
70 for (int i=0; i<srcRec.componentBindings.length; i++)
72 Binding cdomain = srcRec.componentBindings[i];
73 Binding crange = dstRec.componentBindings[i];
74 Object srcComponent = srcRec.getComponent(src, i);
75 Object dstComponent = adapt(srcComponent, cdomain, crange);
76 dstComponents[i] = dstComponent;
78 dstRec.setComponents(dst, dstComponents);
82 if (domain instanceof UnionBinding && range instanceof UnionBinding)
84 UnionBinding srcUni = (UnionBinding) domain;
85 UnionBinding dstUni = (UnionBinding) range;
86 int tag = srcUni.getTag(src);
87 Binding cdomain = srcUni.getComponentBindings()[tag];
88 Binding crange = dstUni.getComponentBindings()[tag];
89 Object srcComponent = srcUni.getValue(src);
90 Object dstComponent = adapt(srcComponent, cdomain, crange);
91 Object dst = dstUni.create(tag, dstComponent);
95 if (domain instanceof BooleanBinding && range instanceof BooleanBinding)
97 BooleanBinding srcBoo = (BooleanBinding) domain;
98 BooleanBinding dstBoo = (BooleanBinding) range;
99 boolean srcBoolean = srcBoo.getValue_(src);
100 Object dst = dstBoo.create(srcBoolean);
104 if (domain instanceof StringBinding && range instanceof StringBinding)
106 StringBinding srcStr = (StringBinding) domain;
107 StringBinding dstStr = (StringBinding) range;
108 String srcString = srcStr.getValue(src);
109 Object dst = dstStr.create(srcString);
113 if (domain instanceof ByteBinding && range instanceof ByteBinding)
115 ByteBinding srcNum = (ByteBinding) domain;
116 ByteBinding dstNum = (ByteBinding) range;
117 byte srcNumber = srcNum.getValue_(src);
118 Object dst = dstNum.create(srcNumber);
122 if (domain instanceof IntegerBinding && range instanceof IntegerBinding)
124 IntegerBinding srcNum = (IntegerBinding) domain;
125 IntegerBinding dstNum = (IntegerBinding) range;
126 int srcNumber = srcNum.getValue_(src);
127 Object dst = dstNum.create(srcNumber);
131 if (domain instanceof LongBinding && range instanceof LongBinding)
133 LongBinding srcNum = (LongBinding) domain;
134 LongBinding dstNum = (LongBinding) range;
135 long srcNumber = srcNum.getValue_(src);
136 Object dst = dstNum.create(srcNumber);
140 if (domain instanceof FloatBinding && range instanceof FloatBinding)
142 FloatBinding srcNum = (FloatBinding) domain;
143 FloatBinding dstNum = (FloatBinding) range;
144 float srcNumber = srcNum.getValue_(src);
145 Object dst = dstNum.create(srcNumber);
149 if (domain instanceof DoubleBinding && range instanceof DoubleBinding)
151 DoubleBinding srcNum = (DoubleBinding) domain;
152 DoubleBinding dstNum = (DoubleBinding) range;
153 double srcNumber = srcNum.getValue_(src);
154 Object dst = dstNum.create(srcNumber);
158 if (domain instanceof ByteArrayBinding && range instanceof ByteArrayBinding)
160 ByteArrayBinding srcArr = (ByteArrayBinding) domain;
161 ByteArrayBinding dstArr = (ByteArrayBinding) range;
162 return dstArr.create( srcArr.getArray(src) );
164 if (domain instanceof BooleanArrayBinding && range instanceof BooleanArrayBinding)
166 BooleanArrayBinding srcArr = (BooleanArrayBinding) domain;
167 BooleanArrayBinding dstArr = (BooleanArrayBinding) range;
168 return dstArr.create( srcArr.getArray(src) );
170 if (domain instanceof IntArrayBinding && range instanceof IntArrayBinding)
172 IntArrayBinding srcArr = (IntArrayBinding) domain;
173 IntArrayBinding dstArr = (IntArrayBinding) range;
174 return dstArr.create( srcArr.getArray(src) );
176 if (domain instanceof LongArrayBinding && range instanceof LongArrayBinding)
178 LongArrayBinding srcArr = (LongArrayBinding) domain;
179 LongArrayBinding dstArr = (LongArrayBinding) range;
180 return dstArr.create( srcArr.getArray(src) );
182 if (domain instanceof FloatArrayBinding && range instanceof FloatArrayBinding)
184 FloatArrayBinding srcArr = (FloatArrayBinding) domain;
185 FloatArrayBinding dstArr = (FloatArrayBinding) range;
186 return dstArr.create( srcArr.getArray(src) );
188 if (domain instanceof DoubleArrayBinding && range instanceof DoubleArrayBinding)
190 DoubleArrayBinding srcArr = (DoubleArrayBinding) domain;
191 DoubleArrayBinding dstArr = (DoubleArrayBinding) range;
192 return dstArr.create( srcArr.getArray(src) );
195 if (domain instanceof ArrayBinding && range instanceof ArrayBinding)
197 ArrayBinding srcArr = (ArrayBinding) domain;
198 ArrayBinding dstArr = (ArrayBinding) range;
199 int length = srcArr.size(src);
200 Binding cdomain = srcArr.getComponentBinding();
201 Binding crange = dstArr.getComponentBinding();
202 ArrayList<Object> dstArray = new ArrayList<Object>(length);
203 for (int i=0; i<length; i++)
205 Object srcComponent = srcArr.get(src, i);
206 Object dstComponent = adapt(srcComponent, cdomain, crange);
207 dstArray.add(dstComponent);
209 Object dst = dstArr instanceof ArrayListBinding ? dstArray : dstArr.create(dstArray);
213 if (domain instanceof OptionalBinding && range instanceof OptionalBinding)
215 OptionalBinding domainOptional = (OptionalBinding) domain;
216 OptionalBinding rangeOptional = (OptionalBinding) range;
217 Binding domainComponentBinding = domainOptional.getComponentBinding();
218 Binding rangeComponentBinding = rangeOptional.getComponentBinding();
221 if (!domainOptional.hasValue(value)) return rangeOptional.createNoValue();
223 value = domainOptional.getValue(value);
224 value = adapt(value, domainComponentBinding, rangeComponentBinding);
225 value = rangeOptional.createValue(value);
228 } catch (BindingException e) {
229 throw new AdaptException(e);
233 throw new AdaptException("Source binding "+domain.getClass().getName()+" and destination binding "+range.getClass().getName()+" are not compatible.");
238 * Adapt instance of one binding to format of another binding.
239 * The datatype of the two bindings must be structurally equal.
241 * @param obj source instance
243 * @throws AdaptException
246 public Object adapt(Object obj) throws AdaptException {
247 return adapt(obj, domain, range);
251 public Object adaptUnchecked(Object obj) throws RuntimeAdaptException {
253 return adapt(obj, domain, range);
254 } catch (AdaptException e) {
255 if (e.getCause() != null) throw new RuntimeAdaptException( e );
256 throw new RuntimeAdaptException( e );
260 public Binding getDomain() {
264 public Binding getRange() {
268 public int hashCode() {
269 return domain.hashCode() + 31*range.hashCode();
273 public boolean equals(Object obj) {
274 if (obj == null) return false;
275 if (!(obj.getClass().equals(this.getClass()))) return false;
276 DefaultAdapter other = (DefaultAdapter) obj;
277 return objectEquals(other.domain, domain) && objectEquals(other.range, range);
280 private static boolean objectEquals(Object o1, Object o2) {
281 if (o1==o2) return true;
282 if (o1==null && o2==null) return true;
283 if (o1==null || o2==null) return false;
284 return o1.equals(o2);