/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2010, Geomatys * * 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.geotoolkit.filter.binding; import java.util.Collection; import java.util.Iterator; import java.util.logging.Level; import org.apache.sis.util.ObjectConverters; import org.jaxen.JaxenException; import org.apache.sis.util.logging.Logging; import org.geotoolkit.filter.binding.JaxenFeatureNavigator.Fake; import org.opengis.feature.Attribute; import org.opengis.feature.Feature; import org.opengis.feature.FeatureAssociation; import org.opengis.feature.FeatureType; import org.opengis.feature.Property; /** * Creates property accessors for XPath expressions. * * @author Johann Sorel, Geomatys * @module */ public class XPathBinding<C> extends AbstractBinding<C> { public static class CAXPath extends XPathBinding<Feature>{ public CAXPath() { super(Feature.class, 19); } } public static class CTXPath extends XPathBinding<FeatureType>{ public CTXPath() { super(FeatureType.class, 9); } } public XPathBinding(Class<C> bindedClass, int priority) { super(bindedClass, priority); } @Override public boolean support(String xpath) { return true; } // @Override // public boolean canHandle(final Class type, final String xpath, final Class target) { // // if(xpath == null || xpath.isEmpty()){ // return false; // } // // if (!ComplexAttribute.class.isAssignableFrom(type) // && !PropertyType.class.isAssignableFrom(type) // && !PropertyDescriptor.class.isAssignableFrom(type)) { // return false; // we only work with complex types. // } // // return true; // } @Override public <T> T get(C candidate, String path, Class<T> target) throws IllegalArgumentException { if(candidate==null) return null; try { final JaxenFeatureXPath xpath = JaxenFeatureXPath.create(path); Object v = xpath.evaluate(candidate); if(v instanceof Fake){ v = ((Fake)v).value; } if(v instanceof Collection){ //several property for this path final Collection properties = (Collection) v; if(target != null && target.isInstance(properties)){ return (T) properties; }else{ final Iterator ite = properties.iterator(); if(ite.hasNext()){ v = ite.next(); } } } if(v instanceof Fake && Property.class.isAssignableFrom(target)){ v = ((Fake)v).value; } if(v instanceof Property){ //extract value from property if necessary final Property prop = (Property) v; if(target != null && target.isInstance(prop)){ return (T) prop; }else{ if(prop instanceof Attribute && ((Attribute)prop).getType().getMaximumOccurs()>1){ v = ((Attribute)prop).getValues(); }else if(prop instanceof FeatureAssociation && ((FeatureAssociation)prop).getRole().getMaximumOccurs()>1){ v = ((FeatureAssociation)prop).getValues(); }else{ v = prop.getValue(); } } } if(target == null){ return (T) v; }else{ return ObjectConverters.convert(v, target); } } catch (JaxenException ex) { Logging.getLogger("org.geotoolkit.filter.binding").log(Level.WARNING, null, ex); } return null; } @Override public void set(final C candidate, final String xpath, final Object value) throws IllegalArgumentException { final Object obj = get(candidate,xpath,Property.class); if(obj instanceof Attribute){ final Attribute prop = (Attribute)obj; prop.setValue(value); }else if(obj instanceof FeatureAssociation){ final FeatureAssociation prop = (FeatureAssociation)obj; prop.setValue((Feature)value); }else{ throw new IllegalArgumentException("Can not set value for xpath : " + xpath); } } }