/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, 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.type; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; import org.geotools.feature.NameImpl; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.AttributeType; import org.opengis.feature.type.ComplexType; import org.opengis.feature.type.Name; /** * Helper methods for dealing with Descriptor. *
* This methods opperate directly on the interfaces provided by geoapi, no * actual classes were harmed in the making of these utility methods. *
* * @author Jody Garnett * @author Justin Deoliveira * * @since 2.5 * * * * @source $URL$ */ public class Descriptors { private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(Descriptors.class.getPackage().getName()); /** * Wraps a list of {@link AttributeType} in {@link AttributeDescriptor}. * * @param typeList The list of attribute types. * @return The list of attribute descriptors. * * @see #wrapAttributeType(AttributeType) */ public final static List wrapAttributeTypes( List/*null
if no such descriptor is found.
*
* @param descriptors The list of {@link AttributeDescriptor}.
* @param name The name to match.
*
* @return The matching attribute descriptor, or null
.
*/
public final static AttributeDescriptor find( List descriptors, Name name ){
if( name == null ) return null;
for( Iterator i = descriptors.iterator(); i.hasNext(); ){
AttributeDescriptor attributeType = (AttributeDescriptor) i.next();
if( name.equals( attributeType.getType().getName() ) ){
return attributeType;
}
}
return null; // no default geometry here?
}
// /**
// * Handle subtyping in a "sensible" manner.
// * // * We explored using the XMLSchema of extention and restriction, and have // * instead opted for the traditional Java lanaguage notion of an override. // *
// * The concept of an overrided allows both: // *
* This is the way XMLSchema handles it ... *
* * @param schema * @param sub * @return */ // @SuppressWarnings("unchecked") // public ComplexType restriction(ComplexType parent,ComplexType restrict) { // // ComplexType type = null; // // if ( // parent instanceof ChoiceType && restrict instanceof ChoiceType // ) { // // Set choices = (Set) restriction( // ((ChoiceType)parent).getAttributes(), // ((ChoiceType)restrict).getAttributes(), // new HashSet() // ); // // type = xmlFactory.createChoiceType(choices); // } // else if (parent instanceof SequenceType && restrict instanceof // SequenceType) { // List sequence = (List) restriction( // ((SequenceType)parent).getAttributes(), // ((SequenceType)restrict).getAttributes(), // new ArrayList() // ); // // type = xmlFactory.createSequenceType(sequence); // } // else if ( // parent instanceof ComplexType && restrict instanceof ComplexType // ){ // List elements = (List) restriction( // ((ComplexType)parent).getAttributes(), // ((ComplexType)restrict).getAttributes(), // new ArrayList() // ); // // ComplexType ct = (ComplexType) restrict; // type = xmlFactory.createType( // ct.getName(),elements,ct.isIdentified(),ct.isNillable().booleanValue(), // ct.getRestrictions(),ct,ct.isAbstract()); // // } // else { // throw new IllegalArgumentException("Cannot restrict provided schema"); // } // // return type; // // } // public ComplexType restriction(ComplexType parent, // Collection/*// * Since we will be creating a new Descriptor we need the factory. // */ // public ComplexType extension(ComplexType parent, ComplexType extend) { // // ComplexType type = null; // // if (parent instanceof ChoiceType && extend instanceof ChoiceType) { // // Set choices = new HashSet(); // choices.addAll(((ChoiceType)parent).getAttributes()); // choices.addAll(((ChoiceType)extend).getAttributes()); // // type = xmlFactory.createChoiceType(choices); // } // else if ( // parent instanceof SequenceType && extend instanceof SequenceType // ) { // // List sequence = new ArrayList(); // // sequence.addAll(((SequenceType)parent).getAttributes()); // sequence.addAll(((SequenceType)extend).getAttributes()); // // type = xmlFactory.createSequenceType(sequence); // } // else if ( // parent instanceof ComplexType && extend instanceof ComplexType // ){ // List elements = new ArrayList(); // elements.addAll(((ComplexType)parent).getAttributes()); // elements.addAll(((ComplexType)extend).getAttributes()); // // ComplexType ct = (ComplexType) extend; // // //JD: this is a bit of a hack, creating type manually (ie wihtout // // factory, because we have constructed the schema manually // type = new ComplexTypeImpl( // ct.getName(),elements,ct.isIdentified(), // ct.isNillable().booleanValue(),ct.getRestrictions(),ct, // ct.isAbstract() // ); // // } // // return type; // // } /** * We can only restrict node if the restricftion is a subtype that used by * node. * * @param node * @param restrict * @return restrict, iff restrict.getType() ISA node.getType() */ AttributeDescriptor restrict(AttributeDescriptor node, AttributeDescriptor restrict) { if (node.getType() == restrict.getType()) { return restrict; } for (AttributeType/* > */type = restrict.getType(); type != null; type = type.getSuper()) { if (node.getType().equals(type)) { return restrict; } } throw new IllegalArgumentException("Cannot restrict provided schema"); } Collection restriction(Collection schema, Collection restrict, Collection restriction) { if (schema.size() != restrict.size()) { throw new IllegalArgumentException( "You must provide an exact structure match in order to implement restriction"); } Iterator i = schema.iterator(); Iterator j = restrict.iterator(); while (i.hasNext() && j.hasNext()) { restriction .add(restrict((AttributeDescriptor) i.next(), (AttributeDescriptor) j.next())); } return restriction; } /** * Locate type associated with provided name, or null if not found. *
* Namespaces are not taken in count, so if two properties share the same * local name, the first one that matches will be returned. *
* * @param schema * @param name * @return */ static public AttributeType type(Collection schema, Name name) { AttributeDescriptor node = node(schema, name); if (node != null) return node.getType(); return null; } /** * Locate type associated with provided name, or null if not found. ** Namespaces are not taken in count, so if two properties share the same * local name, the first one that matches will be returned. *
* * @param schema * @param name * @return */ static public AttributeType type(ComplexType schema, String name) { return type(schema, new NameImpl(name)); } /** * Locate type associated with provided name, or null if not found. * * @param schema * @param name * @return */ static public AttributeType type(ComplexType schema, Name name) { AttributeDescriptor node = node(schema, name); if (node != null) return node.getType(); return null; } /** * Finds the first node associated with the provided name disregarding * namespaces * * @param schema * @param name * @return */ static public AttributeDescriptor node(ComplexType schema, String name) { // return node(schema,new org.geotools.feature.Name(name)); for (Iterator itr = list(schema).iterator(); itr.hasNext();) { AttributeDescriptor node = (AttributeDescriptor) itr.next(); if (node.getName() == null) { // this may be due to old api usage style, where // only types had names LOGGER.warning("node has no name set, try to fix! " + node); if (node.getType().getName().getLocalPart().equals(name)) { return node; } } else { // this is the correct usage if (node.getName().getLocalPart().equals(name)) { return node; } } } AttributeType superType = schema.getSuper(); if (superType instanceof ComplexType) { return node((ComplexType) superType, name); } return null; } // static public List nodes(Attribute schema) { // List nodes = new ArrayList(); // // for (Iterator itr = list(schema).iterator(); itr.hasNext();) { // Descriptor child = (Descriptor)itr.next(); // if (child instanceof AttributeDescriptor) { // AttributeDescriptor node = (AttributeDescriptor) child; // nodes.add(node); // } // } // return nodes; // } /** * Finds the node associated with the provided name. * * @param schema * @param name * @return AttributeDescriptor assoicated with provided name, or null if not * found. */ static public AttributeDescriptor node(ComplexType schema, Name name) { return node(list(schema), name); } /** * Finds the node associated with the provided name. * * @param schema * @param name * @return AttributeDescriptor assoicated with provided name, or null if not * found. */ static public AttributeDescriptor node(Collection schema, Name name) { for (Iterator itr = schema.iterator(); itr.hasNext();) { AttributeDescriptor node = (AttributeDescriptor) itr.next(); Name nodeName = node.getName(); if (nodeName == null) { // this may be due to old api usage style, where // only types had names LOGGER.warning("node has no name set, try to fix! " + node); Name name2 = node.getType().getName(); if (null == name.getNamespaceURI()) { if (name.getLocalPart().equals(name2.getLocalPart())) { return node; } } else if (name2.getNamespaceURI().equals(name.getNamespaceURI()) && name2.getLocalPart().equals(name.getLocalPart())) { return node; } } else { // this is the correct usage if (name.getNamespaceURI() != null) { if (name.getLocalPart().equals(nodeName.getLocalPart())) { return node; } } else if (name.equals(nodeName)) { return node; } } } return null; } /** * Finds the node associated with the provided type. ** Note a type may be included in more then one node, in which case this * will only find the first one. *
* * @param schema * @param type * @return AttributeDescriptor assoicated with provided name, or null if not * found. */ static public AttributeDescriptor node(ComplexType schema, AttributeType type) { for (Iterator itr = list(schema).iterator(); itr.hasNext();) { AttributeDescriptor node = (AttributeDescriptor) itr.next(); if (node.getType() == type) { return node; } } return null; } /** * List of nodes matching AttributeType. * * @param schema * @param type * @return List of nodes for the provided type, or empty. */ static public List/*
* On the cases where order matters, the returned list preserves the order
* of descriptors declared in schema
*
* This may happen if: *