/* * 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 java.util.Collection; import java.util.HashSet; import com.vividsolutions.jts.geom.Geometry; 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.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.GeometryType; import eu.esdihumboldt.hale.common.schema.model.constraint.type.HasValueFlag; /** * Type condition that checks if it's geometry and optionally for certain * geometry types. * * @author Simon Templer */ public class GeometryCondition implements TypeCondition { private final Collection<Class<? extends Geometry>> bindings; private final boolean allowConversion; private final boolean allowCollection; /** * Default constructor */ public GeometryCondition() { this(null, true, true); } /** * Create a geometry condition that checks for certain geometry types. * * @param bindings the allowed geometry bindings, <code>null</code> for any * @param allowConversion if conversion is allowed regarding the geometry * binding check (only applicable if bindings is not * <code>null</code>) * @param allowCollection if a collection of geometries is allowed regarding * the geometry binding check (only applicable if bindings is not * <code>null</code>) */ public GeometryCondition(Collection<Class<? extends Geometry>> bindings, boolean allowConversion, boolean allowCollection) { super(); this.bindings = (bindings == null) ? (null) : (new HashSet<Class<? extends Geometry>>( bindings)); this.allowConversion = allowConversion; this.allowCollection = allowCollection; } /** * @see EntityCondition#accept(Entity) */ @Override public boolean accept(Type entity) { 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; } GeometryType geometryType = entity.getDefinition().getDefinition() .getConstraint(GeometryType.class); if (!geometryType.isGeometry()) { // is no geometry type return false; } Collection<Class<? extends Geometry>> tmpBindings = bindings; if (tmpBindings == null) { // check only if it is a geometry tmpBindings = new HashSet<Class<? extends Geometry>>(); tmpBindings.add(Geometry.class); } // otherwise check the allowed bindings boolean to = true; // default switch (entity.getDefinition().getSchemaSpace()) { case SOURCE: to = false; break; case TARGET: to = true; break; } for (Class<? extends Geometry> compatibleClass : tmpBindings) { Binding binding = type.getConstraint(Binding.class); boolean isCollection = Collection.class.isAssignableFrom(binding.getBinding()); // check binding if (isCompatibleClass(geometryType.getBinding(), to, compatibleClass, allowConversion) && (!isCollection || allowCollection)) { return true; } } // no check succeeded return false; } /** * Determine if the given binding is compatible to the compatible class. * * @param binding the geometry binding * @param to <code>true</code> if the binding is the target, * <code>false</code> if it is the source * @param compatibleClass the geometry compatible class requested * @param allowConversion if conversion is allowed * @return if the binding is classified as compatible to the geometry * compatible class */ private boolean isCompatibleClass(Class<? extends Geometry> binding, boolean to, Class<? extends Geometry> compatibleClass, boolean allowConversion) { if (to && compatibleClass.equals(Geometry.class)) { /* * Special case: It is not further specified, which type of geometry * is produced. So we allow any geometry binding. */ return true; } return BindingCondition.isCompatibleClass(binding, to, compatibleClass, allowConversion); } }