/*
* 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.xpath;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.jxpath.DynamicPropertyHandler;
import org.geotools.feature.Types;
import org.opengis.feature.Attribute;
import org.opengis.feature.ComplexAttribute;
import org.opengis.feature.Property;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.ComplexType;
import org.opengis.feature.type.Name;
import org.xml.sax.Attributes;
/**
* JXPath property handler that works on Attribute.
*
* @author Gabriel Roldan
* @author Justin Deoliveira
*
* @source $URL$
*/
public class AttributePropertyHandler implements DynamicPropertyHandler {
public String[] getPropertyNames(Object o) {
Attribute att = (Attribute) o;
// we only work on complex attributes
if (att instanceof ComplexAttribute) {
ComplexType type = (ComplexType) att.getType();
Collection attributes = type.getDescriptors();
String[] propNames = new String[attributes.size()];
int i = 0;
for (Iterator itr = attributes.iterator(); itr.hasNext(); i++) {
AttributeDescriptor descriptor = (AttributeDescriptor) itr.next();
// JD: this ignores namespaces
propNames[i] = descriptor.getName().getLocalPart();
}
return propNames;
}
return null;
}
public Object getProperty(Object o, String propName) {
Object value = null;
Attribute att = (Attribute)o;
// the Filter spec says the xpath expresion may or may not
// start with the Feature name. If it does, it is the self
// location path
AttributeDescriptor descriptor = att.getDescriptor();
String attName;
if (descriptor == null) {
attName = att.getType().getName().getLocalPart();
} else {
attName = descriptor.getName().getLocalPart();
}
if (propName.equals(attName) || propName.startsWith(attName + "/")) {
return o;
}
if (o instanceof ComplexAttribute) {
ComplexAttribute attribute = (ComplexAttribute) o;
Name name = Types.typeName(propName);
Collection<Property> found;
try {
found = attribute.getProperties(name);
} catch (NullPointerException e) {
e.printStackTrace();
throw e;
}
value = found.size() == 0 ? null : (found.size() == 1 ? found.iterator().next() : found);
// FIXME HACK: this is due to the Filter subsystem not dealing with
// PropertyHandler returning attribute, hence can't, for example,
// compare
// an Attribute with a Literal
/*
if (value instanceof Attribute && !(value instanceof ComplexAttribute)) {
value = ((Attribute) value).get();
}
*/
}
if (value == null && descriptor != null) {
if ("id".equals(propName)) {
value = att.getIdentifier();
} else {
String[] scopedAttName = propName.split(":");
attName = scopedAttName[scopedAttName.length - 1];
Map attributes = (Map) att.getUserData().get(Attributes.class);
if (attributes != null) {
for (Iterator it = attributes.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Entry) it.next();
Name key = (Name) entry.getKey();
if (attName.equals(key.getLocalPart())) {
value = entry.getValue();
break;
}
}
}
}
}
return value;
}
public void setProperty(Object att, String name, Object value) {
// Attribute attribute = (Attribute)att;
// if (att instanceof ComplexAttribute) {
//
// }
// else {
// //just set the value
//
// }
//
// if(!(attribute instanceof ComplexAttribute)){
// if(!propertyName.equals(attribute.getType().getName().getLocalPart())){
// throw new IllegalArgumentException("only self reference to type
// allowed for simple attributes");
// }
// attribute.set(value);
// }else{
// ComplexAttribute complex = (ComplexAttribute)attribute;
// List/*<Attribute>*/atts = complex.get(new
// org.geotools.util.AttributeName(propertyName));
// if(atts.size() == 0){
// throw new IllegalArgumentException("No attributes of type " +
// propertyName + " found");
// }
// ((Attribute)atts.get(0)).set(value);
// }
}
}