All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotools.feature.AttributeBuilder Maven / Gradle / Ivy

Go to download

The main module contains the GeoTools public interfaces that are used by other GeoTools modules (and GeoTools applications). Where possible we make use industry standard terms as provided by OGC and ISO standards. The formal GeoTools public api consists of gt-metadata, jts and the gt-main module. The main module contains the default implementations that are available provided to other GeoTools modules using our factory system. Factories are obtained from an appropriate FactoryFinder, giving applications a chance configure the factory used using the Factory Hints facilities. FilterFactory ff = CommonFactoryFinder.getFilterFactory(); Expression expr = ff.add( expression1, expression2 ); If you find yourself using implementation specific classes chances are you doing it wrong: Expression expr = new AddImpl( expression1, expressiom2 );

The newest version!
/*
 *    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.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.geotools.feature.type.AttributeDescriptorImpl;
import org.geotools.feature.type.ComplexTypeImpl;
import org.geotools.feature.type.Types;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.Association;
import org.opengis.feature.Attribute;
import org.opengis.feature.ComplexAttribute;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureFactory;
import org.opengis.feature.GeometryAttribute;
import org.opengis.feature.Property;
import org.opengis.feature.type.AssociationDescriptor;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.ComplexType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.GeometryType;
import org.opengis.feature.type.Name;
import org.opengis.feature.type.PropertyDescriptor;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

/**
 * Builder for attributes.
 *
 * @author Justin Deoliveira (The Open Planning Project)
 */
public class AttributeBuilder {

    protected static final ComplexType ANYTYPE_TYPE =
            new ComplexTypeImpl(
                    new NameImpl("http://www.w3.org/2001/XMLSchema", "anyType"),
                    null,
                    false,
                    true,
                    Collections.EMPTY_LIST,
                    null,
                    null);

    /** Factory used to create attributes */
    FeatureFactory attributeFactory;

    /** Namespace context. */
    String namespace;

    /**
     * Type of complex attribute being built. This field is mutually exclusive with {@link
     * #descriptor}
     */
    AttributeType type;

    /**
     * Descriptor of complex attribute being built. This field is mutually exclusive with {@link
     * #type}
     */
    AttributeDescriptor descriptor;

    /** Contained properties (associations + attributes) */
    List properties;

    /** The crs of the attribute. */
    CoordinateReferenceSystem crs;

    /** Default geometry of the feature. */
    Object defaultGeometry;

    public AttributeBuilder(FeatureFactory attributeFactory) {
        this.attributeFactory = attributeFactory;
    }

    //
    // Injection
    //
    // Used to inject dependencies we need during construction time.
    //
    /** Returns the underlying attribute factory. */
    public FeatureFactory getFeatureFactory() {
        return attributeFactory;
    }

    /** Sets the underlying attribute factory. */
    public void setFeatureFactory(FeatureFactory attributeFactory) {
        this.attributeFactory = attributeFactory;
    }

    //
    // State
    //

    /**
     * Initializes the builder to its initial state, the same state it is in directly after being
     * instantiated.
     */
    public void init() {
        descriptor = null;
        type = null;
        properties = null;
        crs = null;
        defaultGeometry = null;
    }

    /**
     * Initializes the state of the builder based on a previously built attribute.
     *
     * 

This method is useful when copying another attribute. */ public void init(Attribute attribute) { init(); descriptor = attribute.getDescriptor(); type = attribute.getType(); if (attribute instanceof ComplexAttribute) { ComplexAttribute complex = (ComplexAttribute) attribute; Collection properties = (Collection) complex.getValue(); for (Iterator itr = properties.iterator(); itr.hasNext(); ) { Property property = (Property) itr.next(); if (property instanceof Attribute) { Attribute att = (Attribute) property; add( att.getIdentifier() == null ? null : att.getIdentifier().toString(), att.getValue(), att.getName()); } else if (property instanceof Association) { Association assoc = (Association) property; associate(assoc.getValue(), assoc.getName()); } } } if (attribute instanceof Feature) { Feature feature = (Feature) attribute; if (feature.getDefaultGeometryProperty() != null) { if (crs == null) { crs = feature.getDefaultGeometryProperty() .getType() .getCoordinateReferenceSystem(); } defaultGeometry = feature.getDefaultGeometryProperty().getValue(); } } } /** This namespace will be used when constructing attribute names. */ public void setNamespaceURI(String namespace) { this.namespace = namespace; } /** * This namespace will be used when constructing attribute names. * * @return namespace will be used when constructing attribute names. */ public String getNamespaceURI() { return namespace; } /** * Sets the type of the attribute being built. * *

When building a complex attribute, this type is used a reference to obtain the types of * contained attributes. */ public void setType(AttributeType type) { this.type = type; this.descriptor = null; } /** * Sets the descriptor of the attribute being built. * *

When building a complex attribute, this type is used a reference to obtain the types of * contained attributes. */ public void setDescriptor(AttributeDescriptor descriptor) { this.descriptor = descriptor; this.type = (AttributeType) descriptor.getType(); } /** @return The type of the attribute being built. */ public AttributeType getType() { return type; } // Feature specific methods /** Sets the coordinate reference system of the built feature. */ public void setCRS(CoordinateReferenceSystem crs) { this.crs = crs; } /** @return The coordinate reference system of the feature, or null if not set. */ public CoordinateReferenceSystem getCRS(Object geom) { if (crs != null) { return crs; } else if (geom != null && geom instanceof Geometry) { Object userData = ((Geometry) geom).getUserData(); if (userData != null && userData instanceof CoordinateReferenceSystem) { return (CoordinateReferenceSystem) userData; } } return null; } /** Sets the default geometry of the feature. */ public void setDefaultGeometry(Object defaultGeometry) { this.defaultGeometry = defaultGeometry; } /** @return The default geometry of the feature. */ public Object getDefaultGeometry() { return defaultGeometry; } // // Complex attribute specific methods // /** * Adds an attribute to the complex attribute being built.
* *

This method uses the result of {@link #getNamespaceURI()} to build a qualified attribute * name. * *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the attribute type. * * @param name The name of the attribute. * @param value The value of the attribute. */ public Attribute add(Object value, String name) { return add(null, value, name); } /** * Adds an association to the complex attribute being built.
* *

This method uses the result of {@link #getNamespaceURI()} to build a qualified attribute * name. * *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the association type. * * @param value The value of the association, an attribute. * @param name The name of the association. */ public void associate(Attribute value, String name) { associate(value, name, namespace); } /** * Adds an attribute to the complex attribute being built.
* *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the attribute type. * * @param value The value of the attribute. * @param name The name of the attribute. * @param namespaceURI The namespace of the attribute. */ public Attribute add(Object value, String name, String namespaceURI) { return add(null, value, name, namespaceURI); } /** * Adds an association to the complex attribute being built.
* *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the association type. * * @param attribute The value of the association, an attribute. * @param name The name of the association. * @param namespaceURI The namespace of the association */ public void associate(Attribute attribute, String name, String namespaceURI) { associate(attribute, Types.typeName(namespaceURI, name)); } /** * Adds an attribute to the complex attribute being built.
* *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the attribute type. * * @param name The name of the attribute. * @param value The value of the attribute. */ public Attribute add(Object value, Name name) { return add(null, value, name); } /** * Adds an association to the complex attribute being built.
* *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the association type. * * @param value The value of the association, an attribute. * @param name The name of the association. */ public void associate(Attribute value, Name name) { AssociationDescriptor descriptor = associationDescriptor(name); Association association = attributeFactory.createAssociation(value, descriptor); properties().add(association); } /** * Adds an attribute to the complex attribute being built.
* *

The result of {@link #getNamespaceURI()} to build a qualified attribute name. * *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the attribute type. * * @param id The id of the attribute. * @param name The name of the attribute. * @param value The value of the attribute. */ public Attribute add(String id, Object value, String name) { return add(id, value, name, namespace); } /** * Adds an attribute to the complex attribute being built.
* *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the attribute type. * * @param id The id of the attribute. * @param value The value of the attribute. * @param name The name of the attribute. * @param namespaceURI The namespace of the attribute. */ public Attribute add(String id, Object value, String name, String namespaceURI) { return add(id, value, Types.typeName(namespaceURI, name)); } /** * Adds an attribute to the complex attribute being built.
* *

This method uses the type supplied in {@link #setType(AttributeType)} in order to * determine the attribute type. * * @param id The id of the attribute. * @param name The name of the attribute. * @param value The value of the attribute. */ public Attribute add(String id, Object value, Name name) { AttributeDescriptor descriptor = attributeDescriptor(name); Attribute attribute = create(value, null, descriptor, id); properties().add(attribute); return attribute; } /** Convenience accessor for properties list which does the null check. */ protected List properties() { if (properties == null) { properties = new ArrayList(); } return properties; } protected AssociationDescriptor associationDescriptor(Name name) { PropertyDescriptor descriptor = Types.descriptor((ComplexType) type, name); if (descriptor == null) { String msg = "Could not locate association: " + name + " in type: " + type.getName(); throw new IllegalArgumentException(msg); } if (!(descriptor instanceof AssociationDescriptor)) { String msg = name + " references a non association"; throw new IllegalArgumentException(msg); } return (AssociationDescriptor) descriptor; } protected AttributeDescriptor attributeDescriptor(Name name) { PropertyDescriptor descriptor = Types.findDescriptor((ComplexType) type, name); if (descriptor == null) { String msg = "Could not locate attribute: " + name + " in type: " + type.getName(); throw new IllegalArgumentException(msg); } if (!(descriptor instanceof AttributeDescriptor)) { String msg = name + " references a non attribute"; throw new IllegalArgumentException(msg); } return (AttributeDescriptor) descriptor; } /** * Factors out attribute creation code, needs to be called with either one of type or descriptor * null. */ protected Attribute create( Object value, AttributeType type, AttributeDescriptor descriptor, String id) { if (descriptor != null) { type = (AttributeType) descriptor.getType(); } // if (type instanceof FeatureCollectionType) { // attribute = descriptor != null ? attributeFactory.createFeatureCollection( // (Collection) value, descriptor, id) : attributeFactory.createFeatureCollection( // (Collection) value, (FeatureCollectionType) type, id); // } else if (type instanceof FeatureType) { return descriptor != null ? attributeFactory.createFeature((Collection) value, descriptor, id) : attributeFactory.createFeature((Collection) value, (FeatureType) type, id); } else if (type instanceof ComplexType) { return createComplexAttribute((Collection) value, (ComplexType) type, descriptor, id); } else if (type instanceof GeometryType) { return attributeFactory.createGeometryAttribute( value, (GeometryDescriptor) descriptor, id, getCRS(value)); } else { return attributeFactory.createAttribute(value, descriptor, id); } } /** Create complex attribute */ public ComplexAttribute createComplexAttribute( Object value, ComplexType type, AttributeDescriptor descriptor, String id) { return descriptor != null ? attributeFactory.createComplexAttribute((Collection) value, descriptor, id) : attributeFactory.createComplexAttribute((Collection) value, type, id); } /** * Builds the attribute. * *

The class of the attribute built is determined from its type set with {@link * #setType(AttributeType)}. * * @return The build attribute. */ public Attribute build() { return build(null); } /** * Builds the attribute. * *

The class of the attribute built is determined from its type set with {@link * #setType(AttributeType)}. * * @param id The id of the attribute, or null. * @return The build attribute. */ public Attribute build(String id) { Attribute built = create(properties(), type, descriptor, id); // FIXME // // if geometry, set the crs // if (built instanceof GeometryAttribute) { // ((GeometryAttribute) built).getDescriptor().setCRS(getCRS()); // } // if feature, set crs and default geometry if (built instanceof Feature) { Feature feature = (Feature) built; // FIXME feature.setCRS(getCRS()); if (defaultGeometry != null) { for (Iterator itr = feature.getProperties().iterator(); itr.hasNext(); ) { Attribute att = (Attribute) itr.next(); if (att instanceof GeometryAttribute) { if (defaultGeometry.equals(att.getValue())) { feature.setDefaultGeometryProperty((GeometryAttribute) att); } } } } } properties().clear(); return built; } /** * Special case for any type. Skip validating existence in the schema, since anyType legally can * be casted into anything. * * @param value the value to be set * @param type the type of the value * @param descriptor the attribute descriptor of anyType type */ public Attribute addAnyTypeValue( Object value, AttributeType type, AttributeDescriptor descriptor, String id) { Attribute attribute = create(value, type, descriptor, id); properties().add(attribute); return attribute; } /** * Create a complex attribute for XS.AnyType, since it's defined as a simple type. We need a * complex attribute so we can set xlink:href in it. */ public Attribute addComplexAnyTypeAttribute( Object value, AttributeDescriptor descriptor, String id) { // need to create a complex attribute for any type, so we can have client properties // for xlink:href and so we chain features etc. Map userData = descriptor.getUserData(); descriptor = new AttributeDescriptorImpl( ANYTYPE_TYPE, descriptor.getName(), descriptor.getMinOccurs(), descriptor.getMaxOccurs(), descriptor.isNillable(), descriptor.getDefaultValue()); descriptor.getUserData().putAll(userData); return createComplexAttribute(value, ANYTYPE_TYPE, descriptor, id); } /** * @return The descriptor of the attribute being built or null there is no descriptor (this * occurs if setType() was used). */ public AttributeDescriptor getDescriptor() { return this.descriptor; } /** @return The coordinate reference system of the feature, or null if not set. */ public CoordinateReferenceSystem getCRS() { return crs; } /** Convenience accessor for properties list which does the null check. */ protected List getProperties() { if (this.properties == null) { this.properties = new ArrayList(); } return this.properties; } public Attribute buildSimple(String id, Object value) { return create(value, type, descriptor, id); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy