/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.common.align.model.condition.impl; import net.jcip.annotations.Immutable; import org.springframework.core.convert.ConversionService; import eu.esdihumboldt.hale.common.align.model.Entity; import eu.esdihumboldt.hale.common.align.model.Type; import eu.esdihumboldt.hale.common.align.model.condition.EntityCondition; import eu.esdihumboldt.hale.common.align.model.condition.TypeCondition; import eu.esdihumboldt.hale.common.core.HalePlatform; import eu.esdihumboldt.hale.common.schema.model.TypeDefinition; import eu.esdihumboldt.hale.common.schema.model.constraint.type.AugmentedValueFlag; import eu.esdihumboldt.hale.common.schema.model.constraint.type.Binding; import eu.esdihumboldt.hale.common.schema.model.constraint.type.ElementType; import eu.esdihumboldt.hale.common.schema.model.constraint.type.HasValueFlag; /** * Type condition that checks its binding and element type * * @author Simon Templer */ @Immutable public class BindingCondition implements TypeCondition { private final boolean allowCollection; private final boolean allowConversion; private final Class<?> compatibleClass; /** * Create a binding condition * * @param compatibleClass the class the binding should be compatible to * @param allowConversion specifies if a binding is classified as compatible * if conversion to the compatible class is possible * @param allowCollection specifies if a binding is classified as compatible * if it is a collection of the compatible class */ public BindingCondition(Class<?> compatibleClass, boolean allowConversion, boolean allowCollection) { this.compatibleClass = compatibleClass; this.allowConversion = allowConversion; this.allowCollection = allowCollection; } /** * @see EntityCondition#accept(Entity) */ @Override public boolean accept(Type entity) { boolean to = true; // default switch (entity.getDefinition().getSchemaSpace()) { case SOURCE: to = false; break; case TARGET: to = true; break; } TypeDefinition type = entity.getDefinition().getDefinition(); if (!type.getConstraint(HasValueFlag.class).isEnabled() && !type.getConstraint(AugmentedValueFlag.class).isEnabled()) { // only check binding for types that actually may have a value, // whether defined in the schema or augmented return false; } // check binding Binding binding = type.getConstraint(Binding.class); if (isCompatibleClass(binding.getBinding(), to)) { return true; } // check element type if (allowCollection) { ElementType elementType = type.getConstraint(ElementType.class); if (isCompatibleClass(elementType.getBinding(), to)) { return true; } } // no check succeeded return false; } /** * Check if the given binding is compatible to the configured compatible * class * * @param binding the binding * @param to if a value of {@link #compatibleClass} shall be assigned to the * binding or vice versa * @return if the binding is compatible */ protected boolean isCompatibleClass(Class<?> binding, boolean to) { return isCompatibleClass(binding, to, compatibleClass, allowConversion); } /** * Check if the given binding is compatible to the given compatible class * * @param binding the binding * @param to if a value of the compatible class shall be assigned to the * binding or vice versa * @param compatibleClass the compatible class * @param allowConversion if conversion is allowed * @return if the binding is compatible */ public static boolean isCompatibleClass(Class<?> binding, boolean to, Class<?> compatibleClass, boolean allowConversion) { // check if the classes are compatible by assignment if (to) { if (binding.isAssignableFrom(compatibleClass)) { return true; } } else { if (compatibleClass.isAssignableFrom(binding)) { return true; } } if (allowConversion) { // check if a corresponding conversion is possible ConversionService conversionService = HalePlatform.getService(ConversionService.class); if (to) { if (conversionService.canConvert(compatibleClass, binding)) { return true; } } else { if (conversionService.canConvert(binding, compatibleClass)) { return true; } } } return false; } }