/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-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.filter.function; import static org.geotools.filter.capability.FunctionNameImpl.parameter; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; //import org.apache.commons.beanutils.PropertyUtils; import org.geotools.filter.FunctionExpressionImpl; import org.geotools.filter.capability.FunctionNameImpl; import org.geotools.util.Utilities; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.FeatureType; import org.opengis.filter.capability.FunctionName; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Literal; import org.opengis.filter.expression.PropertyName; /** * A new function to check if a property exists. * * * @source $URL$ */ public class PropertyExistsFunction extends FunctionExpressionImpl { //public static FunctionName NAME = new FunctionNameImpl("PropertyExists","propertyName"); public static FunctionName NAME = new FunctionNameImpl("PropertyExists", parameter("exists", Boolean.class), parameter("propertyName", Object.class)); public PropertyExistsFunction() { super(NAME); } private String getPropertyName() { Expression expr = (Expression) getParameters().get(0); return getPropertyName(expr); } private String getPropertyName(Expression expr) { String propertyName; if (expr instanceof Literal) { propertyName = String.valueOf(((Literal) expr).getValue()); } else if (expr instanceof PropertyName) { propertyName = ((PropertyName) expr).getPropertyName(); } else { throw new IllegalStateException("Not a property name expression: " + expr); } return propertyName; } /** * @return {@link Boolean#TRUE} if the <code>feature</code>'s * {@link FeatureType} contains an attribute named as the property * name passed as this function argument, {@link Boolean#FALSE} * otherwise. */ public Object evaluate(SimpleFeature feature) { String propName = getPropertyName(); AttributeDescriptor attributeType = feature.getFeatureType().getDescriptor(propName); return Boolean.valueOf(attributeType != null); } /** * @return {@link Boolean#TRUE} if the Class of the object passed as * argument defines a property names as the property name passed as * this function argument, following the standard Java Beans naming * conventions for getters. {@link Boolean#FALSE} otherwise. */ public Object evaluate(Object bean) { if (bean instanceof SimpleFeature) { return evaluate((SimpleFeature) bean); } final String propName = getPropertyName(); try { Class type = bean.getClass(); //quick 1 // try { // String getName = "get"+propName.substring(0,1).toUpperCase()+propName.substring(1); // if (type.getMethod(getName, new Class[0]) != null) { // return true; // } // } catch (Exception ignore) { // } // // quick 2 // try { // String isName = "is"+propName.substring(0,1).toUpperCase()+propName.substring(1); // if (type.getMethod(isName, new Class[0]) != null) { // return true; // } // } catch (Exception ignore) { // } // okay go for real BeanInfo info = Introspector.getBeanInfo( type ); for( PropertyDescriptor descriptor : info.getPropertyDescriptors() ){ if( descriptor.getName().equals(propName) ){ if( descriptor.getReadMethod() != null ){ return true; } else { return false; // property found but not writable } } } //PropertyUtils.getProperty(bean, propName); //return true; } catch (IntrospectionException ignore) { } return false; } public String toString() { StringBuffer sb = new StringBuffer("PropertyExists('"); sb.append(getPropertyName()); sb.append("')"); String stringVal = sb.toString(); return stringVal; } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof PropertyExistsFunction)) { return false; } PropertyExistsFunction other = (PropertyExistsFunction) obj; if (other.getParameters().size() != this.getParameters().size()) return false; if (other.getParameters().size() > 0) { final String propName = getPropertyName(); Expression otherPropNameExpr = (Expression) other.getParameters() .get(0); final String otherPropName = getPropertyName(otherPropNameExpr); return Utilities.equals(propName, otherPropName); } else { return true; } } }