/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-2011, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.feature; import java.util.logging.Logger; import org.geotools.data.complex.config.NonFeatureTypeProxy; import org.geotools.data.complex.config.Types; import org.geotools.feature.type.AttributeDescriptorImpl; import org.geotools.feature.type.GeometryDescriptorImpl; import org.opengis.feature.Attribute; import org.opengis.feature.FeatureFactory; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.AttributeType; import org.opengis.feature.type.GeometryType; import org.opengis.feature.type.Name; /** * Builder for attributes. * * @author Justin Deoliveira (The Open Planning Project) * * * * * * @source $URL$ */ public class AppSchemaAttributeBuilder extends AttributeBuilder { private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(AppSchemaAttributeBuilder.class.getPackage().getName()); public AppSchemaAttributeBuilder(FeatureFactory attributeFactory) { super(attributeFactory); } /** * Adds an attribute to the complex attribute being built overriding the type of the declared * attribute descriptor by a subtype of it. <br> * <p> * This method uses the type supplied in {@link #setType(AttributeType)} in order to determine * the attribute type. * </p> * * @param id * the attribtue id * @param value * The value of the attribute. * * @param name * The name of the attribute. * @param type * the actual type of the attribute, which might be the same as the declared type * for the given AttributeDescriptor or a derived type. * */ public Attribute add(final String id, final Object value, final Name name, final AttributeType type) { // existence check AttributeDescriptor descriptor = attributeDescriptor(name); AttributeType declaredType = (AttributeType) descriptor.getType(); if (!declaredType.equals(type)) { boolean argIsSubType = Types.isSuperType(type, declaredType); if (!argIsSubType) { /* * commented out since we got community schemas where the required instance type is * not a subtype of the declared one throw new * IllegalArgumentException(type.getName() + " is not a subtype of " + * declaredType.getName()); */ LOGGER.fine("Adding attribute " + name + " of type " + type.getName() + " which is not a subtype of " + declaredType.getName()); } int minOccurs = descriptor.getMinOccurs(); int maxOccurs = descriptor.getMaxOccurs(); boolean nillable = descriptor.isNillable(); // TODO: handle default value Object defaultValue = null; if (type instanceof GeometryType) { descriptor = new GeometryDescriptorImpl((GeometryType) type, name, minOccurs, maxOccurs, nillable, defaultValue); } else { descriptor = new AttributeDescriptorImpl(type, name, minOccurs, maxOccurs, nillable, defaultValue); } } Attribute attribute; if (descriptor != null && descriptor.getType() instanceof NonFeatureTypeProxy) { // we don't want a feature. NonFeatureTypeProxy is used to make non feature types // a fake feature type, so it can be created as top level feature in app-schema // mapping file. When created inside other features, it should be encoded as // complex features though. attribute = createComplexAttribute(value, null, descriptor, id); } else { attribute = create(value, null, descriptor, id); } properties().add(attribute); return attribute; } }