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%2Fadapter%2FAdapterFactory.java;h=066ed4c886e7bb4eb6500174b978fda5232c877a;hp=2dc51e402eee7300db0f8aea4dd898ff5168c905;hb=15a0f229f7340ed92e9157049483ed71f54677f9;hpb=bb5a3edf299cb943999c72c69dd68fb740c8a506 diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/adapter/AdapterFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/adapter/AdapterFactory.java index 2dc51e402..066ed4c88 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/adapter/AdapterFactory.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/adapter/AdapterFactory.java @@ -1,49 +1,49 @@ -/******************************************************************************* - * 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 + *******************************************************************************/ package org.simantics.databoard.adapter; -import java.util.ArrayList; -import java.util.Map; - -import org.apache.commons.collections.map.ReferenceMap; -import org.simantics.databoard.Bindings; -import org.simantics.databoard.Units; -import org.simantics.databoard.binding.ArrayBinding; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.BooleanBinding; -import org.simantics.databoard.binding.MapBinding; -import org.simantics.databoard.binding.NumberBinding; -import org.simantics.databoard.binding.OptionalBinding; -import org.simantics.databoard.binding.RecordBinding; -import org.simantics.databoard.binding.StringBinding; -import org.simantics.databoard.binding.UnionBinding; -import org.simantics.databoard.binding.VariantBinding; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.error.RuntimeBindingException; -import org.simantics.databoard.binding.impl.ArrayListBinding; -import org.simantics.databoard.binding.impl.BooleanArrayBinding; -import org.simantics.databoard.binding.impl.ByteArrayBinding; -import org.simantics.databoard.binding.impl.DoubleArrayBinding; -import org.simantics.databoard.binding.impl.FloatArrayBinding; -import org.simantics.databoard.binding.impl.IntArrayBinding; -import org.simantics.databoard.binding.impl.LongArrayBinding; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.NumberType; -import org.simantics.databoard.type.RecordType; -import org.simantics.databoard.type.UnionType; -import org.simantics.databoard.units.IUnitConverter; -import org.simantics.databoard.units.IdentityConverter; -import org.simantics.databoard.units.internal.UnitParseException; -import org.simantics.databoard.util.ObjectUtils; +import java.util.ArrayList; +import java.util.Map; + +import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength; +import org.apache.commons.collections4.map.ReferenceMap; +import org.simantics.databoard.Units; +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.BooleanBinding; +import org.simantics.databoard.binding.MapBinding; +import org.simantics.databoard.binding.NumberBinding; +import org.simantics.databoard.binding.OptionalBinding; +import org.simantics.databoard.binding.RecordBinding; +import org.simantics.databoard.binding.StringBinding; +import org.simantics.databoard.binding.UnionBinding; +import org.simantics.databoard.binding.VariantBinding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.error.RuntimeBindingException; +import org.simantics.databoard.binding.impl.ArrayListBinding; +import org.simantics.databoard.binding.impl.BooleanArrayBinding; +import org.simantics.databoard.binding.impl.ByteArrayBinding; +import org.simantics.databoard.binding.impl.DoubleArrayBinding; +import org.simantics.databoard.binding.impl.FloatArrayBinding; +import org.simantics.databoard.binding.impl.IntArrayBinding; +import org.simantics.databoard.binding.impl.LongArrayBinding; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.NumberType; +import org.simantics.databoard.type.RecordType; +import org.simantics.databoard.type.UnionType; +import org.simantics.databoard.units.IUnitConverter; +import org.simantics.databoard.units.IdentityConverter; +import org.simantics.databoard.units.internal.UnitParseException; +import org.simantics.databoard.util.ObjectUtils; /** * AdapterRepository is a factory and a collection of adapters. @@ -52,27 +52,26 @@ import org.simantics.databoard.util.ObjectUtils; */ public class AdapterFactory { - @SuppressWarnings( "unchecked" ) - Map cache = (Map) new ReferenceMap(ReferenceMap.SOFT, ReferenceMap.HARD); - + Map cache = new ReferenceMap<>(ReferenceStrength.SOFT, ReferenceStrength.HARD); + public synchronized Adapter getAdapter(Binding domain, Binding range, boolean typeAdapter, boolean mustClone) throws AdapterConstructionException { - if ((!mustClone || domain.isImmutable()) && domain.equals(range)) return PassThruAdapter.PASSTHRU; - - if (domain.getClass() == range.getClass() && - ( !mustClone || domain.isImmutable() ) && - NumberBinding.class.isAssignableFrom( domain.getClass() ) ) { - - NumberBinding db = (NumberBinding) domain; - NumberBinding rb = (NumberBinding) range; - String u1 = db.type().getUnit(); - String u2 = rb.type().getUnit(); - if (u1==null || u2==null || u1.equals("") || u2.equals("") || u1.equals(u2)) return PassThruAdapter.PASSTHRU; - } + if ((!mustClone || domain.isImmutable()) && domain.equals(range)) return PassThruAdapter.PASSTHRU; + + if (domain.getClass() == range.getClass() && + ( !mustClone || domain.isImmutable() ) && + NumberBinding.class.isAssignableFrom( domain.getClass() ) ) { + + NumberBinding db = (NumberBinding) domain; + NumberBinding rb = (NumberBinding) range; + String u1 = db.type().getUnit(); + String u2 = rb.type().getUnit(); + if (u1==null || u2==null || u1.equals("") || u2.equals("") || u1.equals(u2)) return PassThruAdapter.PASSTHRU; + } return getAdapterUnsynchronized(domain, range, typeAdapter, mustClone); - } + } private AbstractAdapter getCached(AdapterRequest type) { @@ -83,7 +82,7 @@ public class AdapterFactory { cache.put(type, binding); } - private void addToCache(AdapterRequest request, AbstractAdapter impl) { + private void addToCache(AdapterRequest request, AbstractAdapter impl) { impl.request = request; cache(request, impl); @@ -118,21 +117,21 @@ public class AdapterFactory { final RecordBinding domainRecord = (RecordBinding) domain; final RecordBinding rangeRecord = (RecordBinding) range; RecordType domainType = domainRecord.type(); - RecordType rangeType = rangeRecord.type(); - + RecordType rangeType = rangeRecord.type(); + // Field-Map describes the index of the fields in domain for each field in range boolean requiresTypeAdapting = domainType.getComponentCount() != rangeType.getComponentCount(); int fieldMap[] = new int[rangeType.getComponentCount()]; for (int rangeIndex=0; rangeIndex=0) { - Object srcValue = domainRecord.getComponent(src, domainIndex); - Object dstValue = componentAdapters[rangeIndex].adapt(srcValue); - values[rangeIndex] = dstValue; - } else { - // Optional value - values[rangeIndex] = rangeRecord.componentBindings[rangeIndex].createDefault(); + int domainIndex = _fieldMap[rangeIndex]; + if (domainIndex>=0) { + Object srcValue = domainRecord.getComponent(src, domainIndex); + Object dstValue = componentAdapters[rangeIndex].adapt(srcValue); + values[rangeIndex] = dstValue; + } else { + // Optional value + values[rangeIndex] = rangeRecord.componentBindings[rangeIndex].createDefault(); } } return rangeRecord.create(values); @@ -196,11 +195,11 @@ public class AdapterFactory { result.clones = true; for (int rangeIndex=0; rangeIndex=0) { componentAdapters[rangeIndex] = getAdapterUnsynchronized(domainRecord.componentBindings[domainIndex], rangeRecord.componentBindings[rangeIndex], typeAdapter, mustClone); result.typeAdapter |= componentAdapters[rangeIndex].typeAdapter; - result.clones &= componentAdapters[rangeIndex].clones; + result.clones &= componentAdapters[rangeIndex].clones; } } return result; @@ -296,63 +295,63 @@ public class AdapterFactory { } }; result.clones = mustClone; - result.typeAdapter = true; + result.typeAdapter = true; addToCache(req, result); return result; } - - if (domain instanceof BooleanBinding && range instanceof NumberBinding) - { - try { - final BooleanBinding domainBoolean = (BooleanBinding) domain; - final NumberBinding rangeNumber = (NumberBinding) range; - final Object falseValue = rangeNumber.create( Integer.valueOf(0) ); - final Object trueValue = rangeNumber.create( Integer.valueOf(1) ); - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - boolean value = domainBoolean.getValue_(obj); - return value ? trueValue : falseValue; - } catch (BindingException e) { - throw new AdaptException(e); - } - } - }; - result.clones = true; - result.typeAdapter = true; - addToCache(req, result); - return result; - } catch (BindingException e1) { - throw new AdapterConstructionException(e1); - } - } - - if (domain instanceof NumberBinding && range instanceof BooleanBinding) - { - try { - final NumberBinding domainNumber = (NumberBinding) domain; - final BooleanBinding rangeBoolean = (BooleanBinding) range; - final Object zeroValue = domainNumber.create( Integer.valueOf(0) ); - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - Object value = domainNumber.getValue(obj); - boolean bool = !domainNumber.equals(value, zeroValue); - return rangeBoolean.create(bool); - } catch (BindingException e) { - throw new AdaptException(e); - } - } - }; - result.clones = true; - addToCache(req, result); - return result; - } catch (BindingException e1) { - throw new AdapterConstructionException(e1); - } - } + + if (domain instanceof BooleanBinding && range instanceof NumberBinding) + { + try { + final BooleanBinding domainBoolean = (BooleanBinding) domain; + final NumberBinding rangeNumber = (NumberBinding) range; + final Object falseValue = rangeNumber.create( Integer.valueOf(0) ); + final Object trueValue = rangeNumber.create( Integer.valueOf(1) ); + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + boolean value = domainBoolean.getValue_(obj); + return value ? trueValue : falseValue; + } catch (BindingException e) { + throw new AdaptException(e); + } + } + }; + result.clones = true; + result.typeAdapter = true; + addToCache(req, result); + return result; + } catch (BindingException e1) { + throw new AdapterConstructionException(e1); + } + } + + if (domain instanceof NumberBinding && range instanceof BooleanBinding) + { + try { + final NumberBinding domainNumber = (NumberBinding) domain; + final BooleanBinding rangeBoolean = (BooleanBinding) range; + final Object zeroValue = domainNumber.create( Integer.valueOf(0) ); + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + Object value = domainNumber.getValue(obj); + boolean bool = !domainNumber.equals(value, zeroValue); + return rangeBoolean.create(bool); + } catch (BindingException e) { + throw new AdaptException(e); + } + } + }; + result.clones = true; + addToCache(req, result); + return result; + } catch (BindingException e1) { + throw new AdapterConstructionException(e1); + } + } if (domain instanceof StringBinding && range instanceof StringBinding) { @@ -372,47 +371,47 @@ public class AdapterFactory { result.clones = true; addToCache(req, result); return result; - } - - if(domain instanceof StringBinding && range instanceof NumberBinding) - { - final StringBinding domainString = (StringBinding) domain; - final NumberBinding rangeString = (NumberBinding) range; - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - String value = domainString.getValue(obj); - return rangeString.create(value); - } catch (BindingException e) { - throw new AdaptException(e); - } - } - }; - result.clones = true; - addToCache(req, result); - return result; + } + + if(domain instanceof StringBinding && range instanceof NumberBinding) + { + final StringBinding domainString = (StringBinding) domain; + final NumberBinding rangeString = (NumberBinding) range; + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + String value = domainString.getValue(obj); + return rangeString.create(value); + } catch (BindingException e) { + throw new AdaptException(e); + } + } + }; + result.clones = true; + addToCache(req, result); + return result; + } + + if(domain instanceof StringBinding && range instanceof BooleanBinding) + { + final StringBinding domainString = (StringBinding) domain; + final BooleanBinding rangeString = (BooleanBinding) range; + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + String value = domainString.getValue(obj); + return rangeString.create(Boolean.parseBoolean(value)); + } catch (BindingException e) { + throw new AdaptException(e); + } + } + }; + result.clones = true; + addToCache(req, result); + return result; } - - if(domain instanceof StringBinding && range instanceof BooleanBinding) - { - final StringBinding domainString = (StringBinding) domain; - final BooleanBinding rangeString = (BooleanBinding) range; - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - String value = domainString.getValue(obj); - return rangeString.create(Boolean.parseBoolean(value)); - } catch (BindingException e) { - throw new AdaptException(e); - } - } - }; - result.clones = true; - addToCache(req, result); - return result; - } // XXX We can optimizes here by using primitives if (domain instanceof NumberBinding && range instanceof NumberBinding) @@ -421,25 +420,25 @@ public class AdapterFactory { final NumberBinding rangeNumber = (NumberBinding) range; String domainUnit = ((NumberType) domainNumber.type()).getUnit(); - String rangeUnit = ((NumberType) rangeNumber.type()).getUnit(); - IUnitConverter unitConverter; - if(domainUnit == null || rangeUnit == null || domainUnit.equals(rangeUnit)) - unitConverter = null; - else - unitConverter = Units.createConverter(domainUnit, rangeUnit); - /*if(domainUnit == null || domainUnit.equals("")) { - if(rangeUnit == null || rangeUnit.equals("")) - unitConverter = null; - else - unitConverter = null; -// throw new AdapterConstructionException("Cannot convert from a unitless type to a type with unit."); - } - else { - if(rangeUnit == null || rangeUnit.equals("")) - unitConverter = null; -// throw new AdapterConstructionException("Cannot convert from a type with unit to unitless type."); - else - unitConverter = Units.createConverter(domainUnit, rangeUnit); + String rangeUnit = ((NumberType) rangeNumber.type()).getUnit(); + IUnitConverter unitConverter; + if(domainUnit == null || rangeUnit == null || domainUnit.equals(rangeUnit)) + unitConverter = null; + else + unitConverter = Units.createConverter(domainUnit, rangeUnit); + /*if(domainUnit == null || domainUnit.equals("")) { + if(rangeUnit == null || rangeUnit.equals("")) + unitConverter = null; + else + unitConverter = null; +// throw new AdapterConstructionException("Cannot convert from a unitless type to a type with unit."); + } + else { + if(rangeUnit == null || rangeUnit.equals("")) + unitConverter = null; +// throw new AdapterConstructionException("Cannot convert from a type with unit to unitless type."); + else + unitConverter = Units.createConverter(domainUnit, rangeUnit); } */ boolean doUnitConversion = unitConverter != null && unitConverter != IdentityConverter.INSTANCE; boolean doPrimitiveConversion = !domainNumber.type().getClass().equals( rangeNumber.type().getClass() ); @@ -489,7 +488,7 @@ public class AdapterFactory { @Override public Object adapt(Object obj) throws AdaptException { try { - boolean[] data = domainArray.getArray(obj); + boolean[] data = domainArray.getArray(obj); if (mustClone) data = data.clone(); return rangeArray.create(data); } catch (BindingException e) { @@ -536,7 +535,7 @@ public class AdapterFactory { @Override public Object adapt(Object obj) throws AdaptException { try { - byte[] data = domainArray.getArray(obj); + byte[] data = domainArray.getArray(obj); if (mustClone) data = data.clone(); return rangeArray.create(data); } catch (BindingException e) { @@ -557,7 +556,7 @@ public class AdapterFactory { String domainUnit = ((NumberType) ((ArrayType)domainArray.type()).componentType).getUnit(); String rangeUnit = ((NumberType) ((ArrayType)rangeArray.type()).componentType).getUnit(); - IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || + IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || domainUnit == null || rangeUnit == null ? null : Units.createConverter(domainUnit, rangeUnit); boolean doUnitConversion = unitConverter != null && unitConverter != IdentityConverter.INSTANCE; @@ -585,7 +584,7 @@ public class AdapterFactory { @Override public Object adapt(Object obj) throws AdaptException { try { - int[] data = domainArray.getArray(obj); + int[] data = domainArray.getArray(obj); if (mustClone) data = data.clone(); return rangeArray.create(data); } catch (BindingException e) { @@ -607,7 +606,7 @@ public class AdapterFactory { String domainUnit = ((NumberType) ((ArrayType)domainArray.type()).componentType).getUnit(); String rangeUnit = ((NumberType) ((ArrayType)rangeArray.type()).componentType).getUnit(); - IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || + IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || domainUnit == null || rangeUnit == null ? null : Units.createConverter(domainUnit, rangeUnit); boolean doUnitConversion = unitConverter != null && unitConverter != IdentityConverter.INSTANCE; @@ -635,7 +634,7 @@ public class AdapterFactory { @Override public Object adapt(Object obj) throws AdaptException { try { - long[] data = domainArray.getArray(obj); + long[] data = domainArray.getArray(obj); if (mustClone) data = data.clone(); return rangeArray.create(data); } catch (BindingException e) { @@ -657,7 +656,7 @@ public class AdapterFactory { String domainUnit = ((NumberType) ((ArrayType)domainArray.type()).componentType).getUnit(); String rangeUnit = ((NumberType) ((ArrayType)rangeArray.type()).componentType).getUnit(); - IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || + IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || domainUnit == null || rangeUnit == null ? null : Units.createConverter(domainUnit, rangeUnit); boolean doUnitConversion = unitConverter != null && unitConverter != IdentityConverter.INSTANCE; @@ -685,7 +684,7 @@ public class AdapterFactory { @Override public Object adapt(Object obj) throws AdaptException { try { - float[] data = domainArray.getArray(obj); + float[] data = domainArray.getArray(obj); if (mustClone) data = data.clone(); return rangeArray.create(data); } catch (BindingException e) { @@ -707,7 +706,7 @@ public class AdapterFactory { String domainUnit = ((NumberType) ((ArrayType)domainArray.type()).componentType).getUnit(); String rangeUnit = ((NumberType) ((ArrayType)rangeArray.type()).componentType).getUnit(); - IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) + IUnitConverter unitConverter = ObjectUtils.objectEquals(domainUnit, rangeUnit) || domainUnit == null || rangeUnit == null ? null : Units.createConverter(domainUnit, rangeUnit); boolean doUnitConversion = unitConverter != null && unitConverter != IdentityConverter.INSTANCE; @@ -735,7 +734,7 @@ public class AdapterFactory { @Override public Object adapt(Object obj) throws AdaptException { try { - double[] data = domainArray.getArray(obj); + double[] data = domainArray.getArray(obj); if (mustClone) data = data.clone(); return rangeArray.create(data); } catch (BindingException e) { @@ -801,29 +800,29 @@ public class AdapterFactory { result.clones = componentAdapter.clones; addToCache(req, result); return result; - } - - // Adapt a non-optional value to an optional value - if (range instanceof OptionalBinding && !(domain instanceof OptionalBinding)) - { - final Binding domainBinding = domain; - final OptionalBinding rangeBinding = (OptionalBinding) range; - final AbstractAdapter componentAdapter = getAdapterUnsynchronized(domainBinding, rangeBinding.componentBinding, typeAdapter, mustClone); - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - obj = componentAdapter.adapt(obj); - return rangeBinding.createValue(obj); - } catch (BindingException e) { - throw new AdaptException(e); - } - } - }; - result.typeAdapter = componentAdapter.typeAdapter; - result.clones = componentAdapter.clones; - addToCache(req, result); - return result; + } + + // Adapt a non-optional value to an optional value + if (range instanceof OptionalBinding && !(domain instanceof OptionalBinding)) + { + final Binding domainBinding = domain; + final OptionalBinding rangeBinding = (OptionalBinding) range; + final AbstractAdapter componentAdapter = getAdapterUnsynchronized(domainBinding, rangeBinding.componentBinding, typeAdapter, mustClone); + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + obj = componentAdapter.adapt(obj); + return rangeBinding.createValue(obj); + } catch (BindingException e) { + throw new AdaptException(e); + } + } + }; + result.typeAdapter = componentAdapter.typeAdapter; + result.clones = componentAdapter.clones; + addToCache(req, result); + return result; } if (domain instanceof VariantBinding && range instanceof VariantBinding) @@ -833,74 +832,74 @@ public class AdapterFactory { AbstractAdapter result = new AbstractAdapter() { @Override public Object adapt(Object obj) throws AdaptException { - try { + try { Binding domainValueBinding = domainBinding.getContentBinding(obj); - Object domainObject = domainBinding.getContent(obj, domainValueBinding); - if (mustClone && domainObject!=obj) { - Adapter valueAdapter = getAdapterUnsynchronized(domainValueBinding, domainValueBinding, false, true); - domainObject = valueAdapter.adapt(domainObject); + Object domainObject = domainBinding.getContent(obj, domainValueBinding); + if (mustClone && domainObject!=obj) { + Adapter valueAdapter = getAdapterUnsynchronized(domainValueBinding, domainValueBinding, false, true); + domainObject = valueAdapter.adapt(domainObject); } Object rangeVariant = rangeBinding.create(domainValueBinding, domainObject); return rangeVariant; } catch (BindingException e) { throw new AdaptException(e); - } catch (AdapterConstructionException e) { - throw new AdaptException(e); + } catch (AdapterConstructionException e) { + throw new AdaptException(e); + } + } + }; + result.clones = mustClone; + addToCache(req, result); + return result; + } + + if (domain instanceof VariantBinding && !(range instanceof VariantBinding)) + { + // Make a recursive adaptation from a variant source + final VariantBinding domainBinding = (VariantBinding)domain; + final Binding rangeBinding = range; + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + Object value = domainBinding.getContent(obj); + Binding contentBinding = domainBinding.getContentBinding(obj); + AbstractAdapter adapter = (AbstractAdapter) getAdapter(contentBinding, rangeBinding, typeAdapter, mustClone); + return adapter.adapt(value); + } catch (BindingException | AdapterConstructionException e) { + throw new AdaptException(e); + } + } + }; + result.clones = mustClone; + addToCache(req, result); + return result; + } + + if (range instanceof VariantBinding && !(domain instanceof VariantBinding)) + { + // Default to just wrapping the domain type + final VariantBinding rangeBinding = (VariantBinding)range; + final Binding domainBinding = domain; + AbstractAdapter result = new AbstractAdapter() { + @Override + public Object adapt(Object obj) throws AdaptException { + try { + if (mustClone) { + Adapter valueAdapter; + valueAdapter = getAdapterUnsynchronized(domainBinding, domainBinding, false, true); + obj = valueAdapter.adapt(obj); + } + return rangeBinding.create(domainBinding, obj); + } catch (AdapterConstructionException | BindingException e) { + throw new AdaptException(e); } } }; result.clones = mustClone; addToCache(req, result); return result; - } - - if (domain instanceof VariantBinding && !(range instanceof VariantBinding)) - { - // Make a recursive adaptation from a variant source - final VariantBinding domainBinding = (VariantBinding)domain; - final Binding rangeBinding = range; - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - Object value = domainBinding.getContent(obj); - Binding contentBinding = domainBinding.getContentBinding(obj); - AbstractAdapter adapter = (AbstractAdapter) getAdapter(contentBinding, rangeBinding, typeAdapter, mustClone); - return adapter.adapt(value); - } catch (BindingException | AdapterConstructionException e) { - throw new AdaptException(e); - } - } - }; - result.clones = mustClone; - addToCache(req, result); - return result; - } - - if (range instanceof VariantBinding && !(domain instanceof VariantBinding)) - { - // Default to just wrapping the domain type - final VariantBinding rangeBinding = (VariantBinding)range; - final Binding domainBinding = domain; - AbstractAdapter result = new AbstractAdapter() { - @Override - public Object adapt(Object obj) throws AdaptException { - try { - if (mustClone) { - Adapter valueAdapter; - valueAdapter = getAdapterUnsynchronized(domainBinding, domainBinding, false, true); - obj = valueAdapter.adapt(obj); - } - return rangeBinding.create(domainBinding, obj); - } catch (AdapterConstructionException | BindingException e) { - throw new AdaptException(e); - } - } - }; - result.clones = mustClone; - addToCache(req, result); - return result; } if (domain instanceof MapBinding && range instanceof MapBinding) @@ -1024,105 +1023,105 @@ public class AdapterFactory { } - - /** - * Adapt a value of one type to another. - * - * @param value - * @param domain - * @param range - * @return adapted value - * @throws AdapterConstructionException - * @throws AdaptException - */ - public Object adapt(Object value, Binding domain, Binding range) - throws AdaptException - { - if (domain == range) return value; - try { - 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 getAdapter(domain, range, true, false).adapt(value); - } catch (AdapterConstructionException | BindingException e) { - throw new AdaptException(e); - } - } - - /** - * Adapt a value of one type to another - * - * @param value - * @param domain - * @param range - * @return adapted value - * @throws AdapterConstructionException - * @throws AdaptException - */ - public Object adaptUnchecked(Object value, Binding domain, Binding range) - throws RuntimeAdapterConstructionException, RuntimeAdaptException - { - if (domain == range) return value; - try { - 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 getAdapter(domain, range, true, false).adaptUnchecked(value); - } catch (RuntimeAdapterConstructionException | RuntimeBindingException e) { - throw new RuntimeAdaptException(new AdaptException(e.getCause())); - } catch (AdapterConstructionException | BindingException e) { - throw new RuntimeAdaptException(new AdaptException(e)); - } - } - - /** - * Clone a value to a type to another. Bindings that handle immutable values - * may return the same instance, others will guarantee a complete copy. - * - * @param value - * @param domain - * @param range - * @return adapted value - * @throws AdapterConstructionException - * @throws AdaptException - */ - public Object clone(Object value, Binding domain, Binding range) - throws AdaptException - { - try { - return 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. - * - * @param value - * @param domain - * @param range - * @return adapted value - * @throws AdapterConstructionException - * @throws AdaptException - */ - public Object cloneUnchecked(Object value, Binding domain, Binding range) - throws RuntimeAdapterConstructionException, RuntimeAdaptException - { - try { - return 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)); - } - } + + /** + * Adapt a value of one type to another. + * + * @param value + * @param domain + * @param range + * @return adapted value + * @throws AdapterConstructionException + * @throws AdaptException + */ + public Object adapt(Object value, Binding domain, Binding range) + throws AdaptException + { + if (domain == range) return value; + try { + 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 getAdapter(domain, range, true, false).adapt(value); + } catch (AdapterConstructionException | BindingException e) { + throw new AdaptException(e); + } + } + + /** + * Adapt a value of one type to another + * + * @param value + * @param domain + * @param range + * @return adapted value + * @throws AdapterConstructionException + * @throws AdaptException + */ + public Object adaptUnchecked(Object value, Binding domain, Binding range) + throws RuntimeAdapterConstructionException, RuntimeAdaptException + { + if (domain == range) return value; + try { + 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 getAdapter(domain, range, true, false).adaptUnchecked(value); + } catch (RuntimeAdapterConstructionException | RuntimeBindingException e) { + throw new RuntimeAdaptException(new AdaptException(e.getCause())); + } catch (AdapterConstructionException | BindingException e) { + throw new RuntimeAdaptException(new AdaptException(e)); + } + } + + /** + * Clone a value to a type to another. Bindings that handle immutable values + * may return the same instance, others will guarantee a complete copy. + * + * @param value + * @param domain + * @param range + * @return adapted value + * @throws AdapterConstructionException + * @throws AdaptException + */ + public Object clone(Object value, Binding domain, Binding range) + throws AdaptException + { + try { + return 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. + * + * @param value + * @param domain + * @param range + * @return adapted value + * @throws AdapterConstructionException + * @throws AdaptException + */ + public Object cloneUnchecked(Object value, Binding domain, Binding range) + throws RuntimeAdapterConstructionException, RuntimeAdaptException + { + try { + return 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)); + } + } }