Permalink
Browse files

GEOS-5756 GetPropertyValue support for complex features and App-schema

  • Loading branch information...
NielsCharlier committed May 6, 2013
1 parent e76dd59 commit e8ecc218d5fc6b6f57d0cdf88b61dbe46da0171e
@@ -179,7 +179,7 @@ public AbstractMappingFeatureIterator(AppSchemaDataAccess store, FeatureTypeMapp
ResolveValueType resolveVal = (ResolveValueType) hints.get( Hints.RESOLVE );
boolean resolve = ResolveValueType.ALL.equals(resolveVal) || ResolveValueType.LOCAL.equals(resolveVal);
- if (!resolve && !ResolveValueType.NONE.equals(resolveVal)) {
+ if (!resolve && resolveVal!=null && !ResolveValueType.NONE.equals(resolveVal)) {
throw new IllegalArgumentException("Resolve:" + resolveVal.getName() + " is not supported in app-schema!");
}
@@ -19,9 +19,13 @@
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection;
@@ -34,53 +38,66 @@
import org.opengis.feature.Attribute;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureFactory;
+import org.opengis.feature.Property;
+import org.opengis.feature.simple.SimpleFeature;
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;
+import org.opengis.filter.expression.PropertyName;
/**
* Wrapping feature collection used by GetPropertyValue operation.
* <p>
- * This feature collection pulls only the specified property out of the delegate
- * feature collection.
+ * This feature collection pulls only the specified property out of the delegate feature collection.
* </p>
+ *
* @author Justin Deoliveira, OpenGeo
- *
+ *
*/
public class PropertyValueCollection extends AbstractCollection<Attribute> {
static FeatureTypeFactory typeFactory = new FeatureTypeFactoryImpl();
+
static FeatureFactory factory = CommonFactoryFinder.getFeatureFactory(null);
FeatureCollection delegate;
+
AttributeDescriptor descriptor;
+
List<Schema> typeMappingProfiles = new ArrayList();
- public PropertyValueCollection(FeatureCollection delegate, AttributeDescriptor descriptor) {
+ PropertyName propertyName;
+
+ public PropertyValueCollection(FeatureCollection delegate, AttributeDescriptor descriptor,
+ PropertyName propName) {
this.delegate = delegate;
- this.descriptor = descriptor;
+ this.descriptor = (AttributeDescriptor) propName.evaluate(delegate.getSchema());
this.typeMappingProfiles.add(XS.getInstance().getTypeMappingProfile());
this.typeMappingProfiles.add(GML.getInstance().getTypeMappingProfile());
+ this.propertyName = propName;
}
@Override
public int size() {
- //JD: this is a lie, since we skip over features without the attribute
+ // JD: this is a lie, since we skip over features without the attribute
return delegate.size();
}
@Override
public Iterator iterator() {
return new PropertyValueIterator(delegate.features());
}
-
+
class PropertyValueIterator implements Iterator {
-
+
FeatureIterator it;
+
Feature next;
-
+
+ Queue values = new LinkedList();
+
PropertyValueIterator(FeatureIterator it) {
this.it = it;
}
@@ -90,63 +107,79 @@ public boolean hasNext() {
if (it == null) {
return false;
}
- if (next == null) {
- while(it.hasNext()) {
+ if (values.isEmpty()) {
+ Object value = null;
+ while (it.hasNext()) {
Feature f = (Feature) it.next();
- if (f.getProperty(descriptor.getName()).getValue() != null) {
+ value = propertyName.evaluate(f);
+ if (value != null
+ && !(value instanceof Collection && ((Collection) value).isEmpty())) {
next = f;
break;
}
}
+ if (value != null) {
+ if (value instanceof Collection) {
+ values.addAll((Collection) value);
+ } else {
+ values.add(value);
+ }
+ }
}
- if (next != null) {
+ if (!values.isEmpty()) {
return true;
}
- //close the iterator
+ // close the iterator
it.close();
it = null;
return false;
}
@Override
public Object next() {
- //create a new descriptor based on teh xml type
+ Object value = values.remove();
+
+ // 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");
+ 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
+ // 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);
+ Name name = new NameImpl(next.getType().getName().getNamespaceURI(),
+ descriptor.getLocalName());
+ AttributeDescriptor newDescriptor = typeFactory.createAttributeDescriptor(xmlType,
+ name, descriptor.getMinOccurs(), descriptor.getMaxOccurs(),
+ descriptor.isNillable(), descriptor.getDefaultValue());
+
+ if (next instanceof SimpleFeature) {
+ return factory.createAttribute(value, newDescriptor, null);
+ } else {
+ return factory
+ .createComplexAttribute(
+ Collections.<Property> singletonList((Property) value),
+ newDescriptor, null);
+ }
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
-
+
AttributeType findType(Class binding) {
for (Schema schema : typeMappingProfiles) {
- for (Map.Entry<Name,AttributeType> e : schema.entrySet()) {
+ 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;
@@ -27,6 +27,7 @@
import net.opengis.wfs20.ValueCollectionType;
import net.opengis.wfs20.Wfs20Factory;
+import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
@@ -35,6 +36,7 @@
import org.geotools.wfs.v2_0.WFS;
import org.geotools.wfs.v2_0.WFSTestSupport;
import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.FilterFactory2;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@@ -45,6 +47,7 @@
public class ValueCollectionTypeBindingTest extends WFSTestSupport {
static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+ private FilterFactory2 filterFac = CommonFactoryFinder.getFilterFactory2();
@Override
protected void setUp() throws Exception {
@@ -82,7 +85,7 @@ public void testEncode() throws Exception {
features.add(b.buildFeature(null));
ValueCollectionType vc = Wfs20Factory.eINSTANCE.createValueCollectionType();
- PropertyValueCollection valueCollection = new PropertyValueCollection(features, featureType.getDescriptor("geom"));
+ PropertyValueCollection valueCollection = new PropertyValueCollection(features, featureType.getDescriptor("geom"), filterFac.property("geom"));
vc.getMember().add(valueCollection);
Document doc = encode(vc, WFS.ValueCollection);
@@ -96,7 +99,7 @@ public void testEncode() throws Exception {
assertNotNull(getElementByQName((Element)geoms.item(1), GML.Point));
vc = Wfs20Factory.eINSTANCE.createValueCollectionType();
- vc.getMember().add(new PropertyValueCollection(features, featureType.getDescriptor("str")));
+ vc.getMember().add(new PropertyValueCollection(features, featureType.getDescriptor("str"), filterFac.property("str")));
doc = encode(vc, WFS.ValueCollection);
assertEquals("wfs:ValueCollection", doc.getDocumentElement().getNodeName());
@@ -111,7 +114,7 @@ public void testEncode() throws Exception {
assertTrue(vals.isEmpty());
vc = Wfs20Factory.eINSTANCE.createValueCollectionType();
- vc.getMember().add(new PropertyValueCollection(features, featureType.getDescriptor("date")));
+ vc.getMember().add(new PropertyValueCollection(features, featureType.getDescriptor("date"), filterFac.property("date")));
doc = encode(vc, WFS.ValueCollection);
assertEquals("wfs:ValueCollection", doc.getDocumentElement().getNodeName());
@@ -1,17 +1,11 @@
/**
- * <copyright>
- * </copyright>
- *
- * $Id$
*/
package net.opengis.wfs20;
import java.math.BigInteger;
import net.opengis.fes20.AbstractQueryExpressionType;
-import org.eclipse.emf.ecore.util.FeatureMap;
-
/**
* <!-- begin-user-doc -->
* A representation of the model object '<em><b>Get Property Value Type</b></em>'.
@@ -38,19 +32,19 @@
* @generated
*/
public interface GetPropertyValueType extends BaseRequestType {
-
- /**
- * Returns the value of the '<em><b>Abstract Query Expression</b></em>' containment reference.
+ /**
+ * Returns the value of the '<em><b>Abstract Query Expression</b></em>' reference.
* <!-- begin-user-doc -->
* <p>
- * If the meaning of the '<em>Abstract Query Expression</em>' containment reference isn't clear,
+ * If the meaning of the '<em>Abstract Query Expression</em>' reference isn't clear,
* there really should be more of a description here...
* </p>
* <!-- end-user-doc -->
- * @return the value of the '<em>Abstract Query Expression</em>' containment reference.
+ * @return the value of the '<em>Abstract Query Expression</em>' reference.
+ * @see #setAbstractQueryExpression(AbstractQueryExpressionType)
* @see net.opengis.wfs20.Wfs20Package#getGetPropertyValueType_AbstractQueryExpression()
- * @model
- * @generated NOT
+ * @model
+ * @generated
*/
AbstractQueryExpressionType getAbstractQueryExpression();
@@ -214,14 +208,12 @@
* </p>
* <!-- end-user-doc -->
* @return the value of the '<em>Resolve Depth</em>' attribute.
- * @see #isSetResolveDepth()
- * @see #unsetResolveDepth()
- * @see #setResolveDepth(Object)
+ * @see #setResolveDepth(String)
* @see net.opengis.wfs20.Wfs20Package#getGetPropertyValueType_ResolveDepth()
- * @model
- * @generated NOT
+ * @model default="*" dataType="org.eclipse.emf.ecore.xml.type.String"
+ * @generated
*/
- Integer getResolveDepth();
+ String getResolveDepth();
/**
* Sets the value of the '{@link net.opengis.wfs20.GetPropertyValueType#getResolveDepth <em>Resolve Depth</em>}' attribute.
@@ -231,7 +223,7 @@
* @see #getResolveDepth()
* @generated
*/
- void setResolveDepth(Integer value);
+ void setResolveDepth(String value);
/**
* Returns the value of the '<em><b>Resolve Path</b></em>' attribute.
Oops, something went wrong.

0 comments on commit e8ecc21

Please sign in to comment.