/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-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.HashSet; import java.util.Set; import org.geotools.feature.AttributeType; import org.geotools.feature.DefaultAttributeType; import org.geotools.feature.IllegalAttributeException; import org.geotools.feature.NameImpl; import org.opengis.filter.Filter; /** * Represents an un-ordered Set of AttributeTypes. For SFS this should not be used. * For GML this is the same as an element whose complexType contains a * All of Attributes. * * NOTE: Some of the methods in this class has nasty order-dependant assumptions, please fix. * * @author dzwiers * @source $URL$ * * @deprecated Will be removed from Geotools 2.6. */ public class SetAttributeType extends AttributeDescriptorImpl implements AttributeType { private final AttributeType[] children; /** * @param copy */ public SetAttributeType(SetAttributeType copy) { super(copy.getType(),copy.getName(),copy.getMinOccurs(),copy.getMaxOccurs(),copy.isNillable(),copy.getDefaultValue()); children = copy.getAttributeTypes(); } // The field for 'Class type' should be added when GT has moved to java 1.5 public SetAttributeType(String name, boolean nillable, int min, int max, AttributeType[] children, Filter restriction) { super(DefaultAttributeType.createAttributeType(name, Set.class, restriction), new NameImpl(name),min,max,nillable,null); this.children = children; } public SetAttributeType(String name, boolean nillable, AttributeType[] children) { this(name, nillable, 1, 1, children,Filter.EXCLUDE); } public Filter getRestriction(){ return DefaultAttributeType.getRestriction(this); } /** * {@inheritDoc} */ public String getLocalName() { return DefaultAttributeType.getLocalName(this); } /** * {@inheritDoc} */ public Class getBinding() { return DefaultAttributeType.getBinding(this); } /* (non-Javadoc) * @see org.geotools.feature.AttributeType#isGeometry() */ public boolean isGeometry() { return false; } /** * This method is unstable ... and does not yet check validity well. * TODO make this method robust * * This method assumes the Objects are in the order of the attributes. * In the future, this should be implemented with a bubble sort type * algorithm for testing each object vs each child. Bubble sort is * recommended as the sample size is typically less than 25 elements, * and the operation takes O(n*n) time. */ public Object parse(Object value) throws IllegalArgumentException { if(value instanceof Set){ Object[] in; in = ((Set)value).toArray(); Set out = new HashSet(in.length); if(in.length == children.length){ for(int i=0;i<children.length;i++){ out.add(children[i].parse(in[i])); } return out; } throw new IllegalArgumentException("Expected "+children.length+" Objects, got "+in.length+" Objects"); } throw new IllegalArgumentException("Not an Object []"); } /** * This method is unstable ... and does not yet check validity well. * TODO make this method robust * * This method assumes the Objects are in the order of the attributes. * In the future, this should be implemented with a bubble sort type * algorithm for testing each object vs each child. Bubble sort is * recommended as the sample size is typically less than 25 elements, * and the operation takes O(n*n) time. * * Note that on the Attribute side of the fence ... this is acutally * an unordered List (a Set of elements, where each element has multiplicity ...) */ public void validate(Object obj) throws IllegalArgumentException { if(obj instanceof Set){ Object[] in; in = ((Set)obj).toArray(); if(in.length == children.length){ for(int i=0;i<children.length;i++){ children[i].validate(in[i]); } return; } throw new IllegalArgumentException("Expected "+children.length+" Objects, got "+in.length+" Objects"); } throw new IllegalArgumentException("Not an Object []"); } /** * This method is unstable ... and does not yet check validity well. * TODO make this method robust * * This method assumes the Objects are in the order of the attributes. * In the future, this should be implemented with a bubble sort type * algorithm for testing each object vs each child. Bubble sort is * recommended as the sample size is typically less than 25 elements, * and the operation takes O(n*n) time. */ public Object duplicate(Object src) throws IllegalAttributeException { if(src instanceof Set){ Object[] in; in = ((Set)src).toArray(); Set out = new HashSet(in.length); if(in.length == children.length){ for(int i=0;i<children.length;i++){ out.add( children[i].duplicate(in[i])); } return out; } throw new IllegalArgumentException("Expected "+children.length+" Objects, got "+in.length+" Objects"); } throw new IllegalArgumentException("Not an Object []"); } /** * This method is unstable ... and does not yet check validity well. * TODO make this method robust * * This method assumes the Objects are in the order of the attributes. * In the future, this should be implemented with a bubble sort type * algorithm for testing each object vs each child. Bubble sort is * recommended as the sample size is typically less than 25 elements, * and the operation takes O(n*n) time. */ public Object createDefaultValue() { Set out = new HashSet(children.length); for(int i=0;i<children.length;i++){ out.add( children[i].createDefaultValue()); } return out; } /** * This is only used twice in the whole geotools code base, and one of * those is for a test, so we're removing it from the interface. If * getAttributeType does not have the AttributeType it will just return * null. Gets the number of occurrences of this attribute. * * @param xPath XPath pointer to attribute type. * * @return Number of occurrences. */ public boolean hasAttributeType(String xPath) { return getAttributeType(xPath) != null; } /** * Returns the number of attributes at the first 'level' of the schema. * * @return equivalent value to getAttributeTypes().length */ public int getAttributeCount(){ return children.length; } /** * Gets the attributeType at this xPath, if the specified attributeType * does not exist then null is returned. * * @param xPath XPath pointer to attribute type. * * @return True if attribute exists. */ public AttributeType getAttributeType(String xPath) { AttributeType attType = null; int idx = find(xPath); if (idx >= 0) attType = children[idx]; return attType; } /** * Find the position of a given AttributeType. * * @param type The type to search for. * * @return -1 if not found, a zero-based index if found. */ public int find(AttributeType type) { if (type == null) return -1; int idx = find(type.getLocalName()); if (idx < 0 || !children[idx].equals(type)) idx = -1; return idx; } /** * Find the position of an AttributeType which matches the given String. * @param attName the name to look for * @return -1 if not found, zero-based index otherwise */ public int find(String attName) { int i=0; while(i<children.length && !attName.equals(children[i].getLocalName()))i++; return i == children.length?-1:i; } /** * Gets the attributeType at the specified index. * * @param position the position of the attribute to check. * * @return The attribute type at the specified position. */ public AttributeType getAttributeType(int position) { return children[position]; } public AttributeType[] getAttributeTypes() { return (AttributeType[]) children.clone(); } }