/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-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.wfs; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.FeatureCollection; import org.geotools.feature.NameImpl; import org.geotools.feature.collection.DecoratingFeatureCollection; import org.geotools.feature.type.FeatureTypeFactoryImpl; import org.geotools.gml3.v3_2.GML; import org.geotools.xs.XS; import org.opengis.feature.Feature; import org.opengis.feature.FeatureFactory; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.AttributeType; import org.opengis.feature.type.FeatureTypeFactory; import org.opengis.feature.type.Name; import org.opengis.feature.type.Schema; /** * Wrapping feature collection used by GetPropertyValue operation. * <p> * This feature collection pulls only the specified property out of the delegate * feature collection. * </p> * @author Justin Deoliveira, OpenGeo * */ public class PropertyValueCollection extends DecoratingFeatureCollection { static FeatureTypeFactory typeFactory = new FeatureTypeFactoryImpl(); static FeatureFactory factory = CommonFactoryFinder.getFeatureFactory(null); AttributeDescriptor descriptor; List<Schema> typeMappingProfiles = new ArrayList(); public PropertyValueCollection(FeatureCollection delegate, AttributeDescriptor descriptor) { super(delegate); this.descriptor = descriptor; this.typeMappingProfiles.add(XS.getInstance().getTypeMappingProfile()); this.typeMappingProfiles.add(GML.getInstance().getTypeMappingProfile()); } @Override public Iterator iterator() { return new PropertyValueIterator(delegate.iterator()); } @Override public void close(Iterator close) { delegate.close(((PropertyValueIterator)close).it); } class PropertyValueIterator implements Iterator { Iterator it; Feature next; PropertyValueIterator(Iterator it) { this.it = it; } @Override public boolean hasNext() { if (next == null) { while(it.hasNext()) { Feature f = (Feature) it.next(); if (f.getProperty(descriptor.getName()).getValue() != null) { next = f; break; } } } return next != null; } @Override public Object next() { //create a new descriptor based on teh xml type AttributeType xmlType = findType(descriptor.getType().getBinding()); if (xmlType == null) { throw new RuntimeException("Unable to map attribute " + descriptor.getName() + " to xml type"); } Object value = next.getProperty(descriptor.getName()).getValue(); //because simple features don't carry around their namespace, create a descritor name // that actually used the feature type schema namespace Name name = new NameImpl(next.getType().getName().getNamespaceURI(), descriptor.getLocalName()); AttributeDescriptor newDescriptor = typeFactory.createAttributeDescriptor(xmlType, name, descriptor.getMinOccurs(), descriptor.getMaxOccurs(), descriptor.isNillable(), descriptor.getDefaultValue()); next = null; return factory.createAttribute(value, newDescriptor, null); } @Override public void remove() { it.remove(); } AttributeType findType(Class binding) { for (Schema schema : typeMappingProfiles) { for (Map.Entry<Name,AttributeType> e : schema.entrySet()) { AttributeType at = e.getValue(); if (at.getBinding() != null && at.getBinding().equals(binding)) { return at; } } for (AttributeType at : schema.values()) { if (binding.isAssignableFrom(at.getBinding())) { return at; } } } return null; } } }