/* * 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.schema.model.constraint.type; import java.util.Collection; import java.util.HashMap; import java.util.Map; import net.jcip.annotations.Immutable; import com.vividsolutions.jts.geom.Geometry; import eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty; import eu.esdihumboldt.hale.common.schema.model.Constraint; import eu.esdihumboldt.hale.common.schema.model.TypeConstraint; import eu.esdihumboldt.hale.common.schema.model.TypeDefinition; /** * Specifies the geometry type for properties with a {@link GeometryProperty} * binding. * * @author Simon Templer * @since 2.5 */ @Immutable @Constraint(mutable = false) public class GeometryType implements TypeConstraint { /** * Geometry binding singletons, binding class mapped to the corresponding * geometry type constraint. Defaults to the type binding as geometry * binding if it is a {@link Geometry} binding or to {@link Geometry} if it * is a {@link GeometryProperty} binding. */ private static final Map<Class<? extends Geometry>, GeometryType> singletons = new HashMap<Class<? extends Geometry>, GeometryType>(); /** * Get the geometry type constraint with the given JTS geometry binding. * * @param binding the type's geometry binding * @return the binding constraint (which is a singleton) */ public static GeometryType get(Class<? extends Geometry> binding) { GeometryType bc = singletons.get(binding); if (bc == null) { bc = new GeometryType(binding, null); singletons.put(binding, bc); } return bc; } /** * The geometry binding */ private final Class<? extends Geometry> binding; /** * The type the constraint is associated to, may be <code>null</code> if * unknown. */ private final TypeDefinition type; /** * Creates a default geometry constraint classifying the type as being no * geometry type. * * @see Constraint */ public GeometryType() { this(null); } /** * Creates a geometry type constraint that determines the geometry binding * from the given type definition. * * @param type the type definition */ public GeometryType(TypeDefinition type) { this(null, type); } /** * Creates a constraint with the given geometry binding * * @param binding the JTS geometry binding * @param type the definition of the type the constraint is associated to, * may be <code>null</code> */ private GeometryType(Class<? extends Geometry> binding, TypeDefinition type) { super(); this.binding = binding; this.type = type; } /** * Get the geometry binding of the type. * * @return the binding, <code>null</code> if it is no geometry * * @see #isGeometry() */ @SuppressWarnings("unchecked") public Class<? extends Geometry> getBinding() { if (binding == null && type != null) { // determine from type // check binding Binding binding = type.getConstraint(Binding.class); if (Geometry.class.isAssignableFrom(binding.getBinding())) { return (Class<? extends Geometry>) binding.getBinding(); } if (Collection.class.isAssignableFrom(binding.getBinding())) { // check element type ElementType elementType = type.getConstraint(ElementType.class); if (Geometry.class.isAssignableFrom(elementType.getBinding())) { return (Class<? extends Geometry>) elementType.getBinding(); } } if (isGeometry()) { // cases for which the exact geometry type can't be determined return Geometry.class; } } return binding; } /** * Specifies if the type the constraint is associated to is a geometry type * (meaning it has a {@link GeometryProperty} or {@link Geometry} value). * * @return if the type is a geometry type */ public boolean isGeometry() { if (binding == null && type != null) { // determine from type // check binding Binding binding = type.getConstraint(Binding.class); if (Geometry.class.isAssignableFrom(binding.getBinding()) || GeometryProperty.class.isAssignableFrom(binding.getBinding())) { return true; } if (Collection.class.isAssignableFrom(binding.getBinding())) { // check element type ElementType elementType = type.getConstraint(ElementType.class); if (Geometry.class.isAssignableFrom(elementType.getBinding()) || GeometryProperty.class.isAssignableFrom(elementType.getBinding())) { return true; } } } return binding != null; } /** * @see TypeConstraint#isInheritable() */ @Override public boolean isInheritable() { // inherit unless overridden return true; } }