/* * 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 java.lang.reflect.InvocationTargetException; import org.apache.commons.beanutils.PropertyUtils; import org.geotools.filter.FunctionExpressionImpl; 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.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 PropertyExistsFunction() { super("PropertyExists"); } public int getArgCount() { return 1; } 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(); Boolean propertyExists = Boolean.TRUE; try { PropertyUtils.getProperty(bean, propName); } catch (NoSuchMethodException e) { propertyExists = Boolean.FALSE; } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } return propertyExists; } 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; } } }