/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.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.geotoolkit.filter.function.other; import java.lang.reflect.InvocationTargetException; import java.util.Objects; import org.apache.commons.beanutils.PropertyUtils; import org.geotoolkit.filter.function.AbstractFunction; import org.opengis.feature.Feature; import org.opengis.feature.PropertyNotFoundException; 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. * @module */ public class PropertyExistsFunction extends AbstractFunction { public PropertyExistsFunction(final Expression parameter) { super(OtherFunctionFactory.PROPERTY_EXISTS, new Expression []{parameter}, null); } private String getPropertyName() { Expression expr = (Expression) getParameters().get(0); return getPropertyName(expr); } private String getPropertyName(final 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(final Feature feature) { String propName = getPropertyName(); try{ feature.getType().getProperty(propName); return true; }catch(PropertyNotFoundException ex){ return false; } } /** * @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. */ @Override public Object evaluate(final Object bean) { if (bean instanceof Feature) { return evaluate((Feature) 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; } @Override public String toString() { final StringBuilder sb = new StringBuilder("PropertyExists('"); sb.append(getPropertyName()); sb.append("')"); return sb.toString(); } @Override public boolean equals(final 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(); final Expression otherPropNameExpr = (Expression) other.getParameters().get(0); final String otherPropName = getPropertyName(otherPropNameExpr); return Objects.equals(propName, otherPropName); } else { return true; } } }