--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.databoard.adapter;
+
+import java.util.ArrayList;\r
+\r
+import org.simantics.databoard.binding.ArrayBinding;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.BooleanBinding;\r
+import org.simantics.databoard.binding.ByteBinding;\r
+import org.simantics.databoard.binding.DoubleBinding;\r
+import org.simantics.databoard.binding.FloatBinding;\r
+import org.simantics.databoard.binding.IntegerBinding;\r
+import org.simantics.databoard.binding.LongBinding;\r
+import org.simantics.databoard.binding.OptionalBinding;\r
+import org.simantics.databoard.binding.RecordBinding;\r
+import org.simantics.databoard.binding.StringBinding;\r
+import org.simantics.databoard.binding.UnionBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.impl.ArrayListBinding;\r
+import org.simantics.databoard.binding.impl.BooleanArrayBinding;\r
+import org.simantics.databoard.binding.impl.ByteArrayBinding;\r
+import org.simantics.databoard.binding.impl.DoubleArrayBinding;\r
+import org.simantics.databoard.binding.impl.FloatArrayBinding;\r
+import org.simantics.databoard.binding.impl.IntArrayBinding;\r
+import org.simantics.databoard.binding.impl.LongArrayBinding;\r
+
+/**
+ * DefaultAdapter adapts anything to anything.
+ *
+ * @deprecated Use {@link AdapterFactory} instead (more efficient)
+ */
+public class DefaultAdapter implements Adapter {
+
+ Binding domain;
+ Binding range;
+
+ DefaultAdapter(Binding domain, Binding range) {
+ this.domain = domain;
+ this.range = range;
+ }
+
+ /**
+ * Adapt instance of one binding to format of another binding.
+ * The datatype of the two bindings must be structurally equal.
+ *
+ * @param src source instance
+ * @return result
+ * @throws AdaptException
+ */
+ public static Object adapt(Object src, Binding domain, Binding range)
+ throws AdaptException
+ {
+ try {
+ if (domain instanceof RecordBinding && range instanceof RecordBinding)
+ {
+ RecordBinding srcRec = (RecordBinding) domain;
+ RecordBinding dstRec = (RecordBinding) range;
+ Object dst = dstRec.createPartial();
+ Object[] dstComponents = new Object[dstRec.componentBindings.length];
+ for (int i=0; i<srcRec.componentBindings.length; i++)
+ {
+ Binding cdomain = srcRec.componentBindings[i];
+ Binding crange = dstRec.componentBindings[i];
+ Object srcComponent = srcRec.getComponent(src, i);
+ Object dstComponent = adapt(srcComponent, cdomain, crange);
+ dstComponents[i] = dstComponent;
+ }
+ dstRec.setComponents(dst, dstComponents);
+ return dst;
+ }
+
+ if (domain instanceof UnionBinding && range instanceof UnionBinding)
+ {
+ UnionBinding srcUni = (UnionBinding) domain;
+ UnionBinding dstUni = (UnionBinding) range;
+ int tag = srcUni.getTag(src);
+ Binding cdomain = srcUni.getComponentBindings()[tag];
+ Binding crange = dstUni.getComponentBindings()[tag];
+ Object srcComponent = srcUni.getValue(src);
+ Object dstComponent = adapt(srcComponent, cdomain, crange);
+ Object dst = dstUni.create(tag, dstComponent);
+ return dst;
+ }
+
+ if (domain instanceof BooleanBinding && range instanceof BooleanBinding)
+ {
+ BooleanBinding srcBoo = (BooleanBinding) domain;
+ BooleanBinding dstBoo = (BooleanBinding) range;
+ boolean srcBoolean = srcBoo.getValue_(src);
+ Object dst = dstBoo.create(srcBoolean);
+ return dst;
+ }
+
+ if (domain instanceof StringBinding && range instanceof StringBinding)
+ {
+ StringBinding srcStr = (StringBinding) domain;
+ StringBinding dstStr = (StringBinding) range;
+ String srcString = srcStr.getValue(src);
+ Object dst = dstStr.create(srcString);
+ return dst;
+ }
+
+ if (domain instanceof ByteBinding && range instanceof ByteBinding)
+ {
+ ByteBinding srcNum = (ByteBinding) domain;
+ ByteBinding dstNum = (ByteBinding) range;
+ byte srcNumber = srcNum.getValue_(src);
+ Object dst = dstNum.create(srcNumber);
+ return dst;
+ }
+
+ if (domain instanceof IntegerBinding && range instanceof IntegerBinding)
+ {
+ IntegerBinding srcNum = (IntegerBinding) domain;
+ IntegerBinding dstNum = (IntegerBinding) range;
+ int srcNumber = srcNum.getValue_(src);
+ Object dst = dstNum.create(srcNumber);
+ return dst;
+ }
+
+ if (domain instanceof LongBinding && range instanceof LongBinding)
+ {
+ LongBinding srcNum = (LongBinding) domain;
+ LongBinding dstNum = (LongBinding) range;
+ long srcNumber = srcNum.getValue_(src);
+ Object dst = dstNum.create(srcNumber);
+ return dst;
+ }
+
+ if (domain instanceof FloatBinding && range instanceof FloatBinding)
+ {
+ FloatBinding srcNum = (FloatBinding) domain;
+ FloatBinding dstNum = (FloatBinding) range;
+ float srcNumber = srcNum.getValue_(src);
+ Object dst = dstNum.create(srcNumber);
+ return dst;
+ }
+
+ if (domain instanceof DoubleBinding && range instanceof DoubleBinding)
+ {
+ DoubleBinding srcNum = (DoubleBinding) domain;
+ DoubleBinding dstNum = (DoubleBinding) range;
+ double srcNumber = srcNum.getValue_(src);
+ Object dst = dstNum.create(srcNumber);
+ return dst;
+ }
+
+ if (domain instanceof ByteArrayBinding && range instanceof ByteArrayBinding)
+ {
+ ByteArrayBinding srcArr = (ByteArrayBinding) domain;
+ ByteArrayBinding dstArr = (ByteArrayBinding) range;
+ return dstArr.create( srcArr.getArray(src) );
+ }
+ if (domain instanceof BooleanArrayBinding && range instanceof BooleanArrayBinding)
+ {
+ BooleanArrayBinding srcArr = (BooleanArrayBinding) domain;
+ BooleanArrayBinding dstArr = (BooleanArrayBinding) range;
+ return dstArr.create( srcArr.getArray(src) );
+ }
+ if (domain instanceof IntArrayBinding && range instanceof IntArrayBinding)
+ {
+ IntArrayBinding srcArr = (IntArrayBinding) domain;
+ IntArrayBinding dstArr = (IntArrayBinding) range;
+ return dstArr.create( srcArr.getArray(src) );
+ }
+ if (domain instanceof LongArrayBinding && range instanceof LongArrayBinding)
+ {
+ LongArrayBinding srcArr = (LongArrayBinding) domain;
+ LongArrayBinding dstArr = (LongArrayBinding) range;
+ return dstArr.create( srcArr.getArray(src) );
+ }
+ if (domain instanceof FloatArrayBinding && range instanceof FloatArrayBinding)
+ {
+ FloatArrayBinding srcArr = (FloatArrayBinding) domain;
+ FloatArrayBinding dstArr = (FloatArrayBinding) range;
+ return dstArr.create( srcArr.getArray(src) );
+ }
+ if (domain instanceof DoubleArrayBinding && range instanceof DoubleArrayBinding)
+ {
+ DoubleArrayBinding srcArr = (DoubleArrayBinding) domain;
+ DoubleArrayBinding dstArr = (DoubleArrayBinding) range;
+ return dstArr.create( srcArr.getArray(src) );
+ }
+
+ if (domain instanceof ArrayBinding && range instanceof ArrayBinding)
+ {
+ ArrayBinding srcArr = (ArrayBinding) domain;
+ ArrayBinding dstArr = (ArrayBinding) range;
+ int length = srcArr.size(src);
+ Binding cdomain = srcArr.getComponentBinding();
+ Binding crange = dstArr.getComponentBinding();
+ ArrayList<Object> dstArray = new ArrayList<Object>(length);
+ for (int i=0; i<length; i++)
+ {
+ Object srcComponent = srcArr.get(src, i);
+ Object dstComponent = adapt(srcComponent, cdomain, crange);
+ dstArray.add(dstComponent);
+ }
+ Object dst = dstArr instanceof ArrayListBinding ? dstArray : dstArr.create(dstArray);
+ return dst;
+ }
+
+ if (domain instanceof OptionalBinding && range instanceof OptionalBinding)
+ {
+ OptionalBinding domainOptional = (OptionalBinding) domain;
+ OptionalBinding rangeOptional = (OptionalBinding) range;
+ Binding domainComponentBinding = domainOptional.getComponentBinding();
+ Binding rangeComponentBinding = rangeOptional.getComponentBinding();
+ Object value = src;
+
+ if (!domainOptional.hasValue(value)) return rangeOptional.createNoValue();
+
+ value = domainOptional.getValue(value);
+ value = adapt(value, domainComponentBinding, rangeComponentBinding);
+ value = rangeOptional.createValue(value);
+ return value;
+ }
+ } catch (BindingException e) {
+ throw new AdaptException(e);
+ }
+
+
+ throw new AdaptException("Source binding "+domain.getClass().getName()+" and destination binding "+range.getClass().getName()+" are not compatible.");
+ }
+
+
+ /**
+ * Adapt instance of one binding to format of another binding.
+ * The datatype of the two bindings must be structurally equal.
+ *
+ * @param obj source instance
+ * @return result
+ * @throws AdaptException
+ */
+ @Override
+ public Object adapt(Object obj) throws AdaptException {
+ return adapt(obj, domain, range);
+ }\r
+ \r
+ @Override\r
+ public Object adaptUnchecked(Object obj) throws RuntimeAdaptException {\r
+ try {\r
+ return adapt(obj, domain, range);\r
+ } catch (AdaptException e) {\r
+ if (e.getCause() != null) throw new RuntimeAdaptException( e );\r
+ throw new RuntimeAdaptException( e ); \r
+ }\r
+ }
+
+ public Binding getDomain() {
+ return domain;
+ }
+
+ public Binding getRange() {
+ return range;
+ }
+ @Override
+ public int hashCode() {
+ return domain.hashCode() + 31*range.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+ if (!(obj.getClass().equals(this.getClass()))) return false;
+ DefaultAdapter other = (DefaultAdapter) obj;
+ return objectEquals(other.domain, domain) && objectEquals(other.range, range);
+ }
+
+ private static boolean objectEquals(Object o1, Object o2) {
+ if (o1==o2) return true;
+ if (o1==null && o2==null) return true;
+ if (o1==null || o2==null) return false;
+ return o1.equals(o2);
+ }
+
+}
+