/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 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.process.function; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.geotools.filter.capability.FunctionNameImpl; import org.geotools.process.Process; import org.geotools.util.Converters; import org.opengis.filter.capability.FunctionName; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.ExpressionVisitor; import org.opengis.filter.expression.Function; import org.opengis.filter.expression.Literal; /** * A helper function helping to bridge the {@link Process} world with the {@link Function} one. * <p> * In particular this one is used to build a named parameter value, allowing to bridge between the * positional parameters of {@link Function} and the named parameters of {@link Process}. * <p> * The value in the returned map will vary depending on how many parameters are given: * <ul> * <li>The first parameter is always the process argument name</li> * <li>If there is no second parameter, the evaluation context is used as the value (normally that * would be a Feature, feature collection or grid coverage</li> * <li>If there is is more than one param left after the argument name a collection containing them * will be built and returned</li> * </ul> * * @author Andrea Aime - GeoSolutions */ class ParameterFunction implements Function { static final String NAME = "parameter"; Literal fallbackValue; List<Expression> parameters; ParameterFunction(Literal fallbackValue, List<Expression> parameters) { this.fallbackValue = fallbackValue; this.parameters = parameters; } public Literal getFallbackValue() { return fallbackValue; } public String getName() { return NAME; } public FunctionName getFunctionName() { return new FunctionNameImpl(NAME, parameters.size() ); } public List<Expression> getParameters() { return parameters; } public Object accept(ExpressionVisitor visitor, Object extraData) { return visitor.visit(this, extraData); } public Object evaluate(Object object) { if (parameters.size() < 1) { throw new IllegalArgumentException("The parameter function requires at " + "least one parameter, the argument name"); } // get the param name String name = parameters.get(0).evaluate(object, String.class); if (name == null) { throw new IllegalArgumentException("The first function parameter should be a string, " + "the name of a process argument"); } // get the other values Object value; if (parameters.size() == 1) { // we return the evaluation context itself value = object; } else if (parameters.size() == 2) { // a single value value = parameters.get(1).evaluate(object); } else { // a collection List<Object> values = new ArrayList<Object>(); for (int i = 1; i < parameters.size(); i++) { Object o = parameters.get(i).evaluate(object); values.add(o); } value = values; } return Collections.singletonMap(name, value); } public <T> T evaluate(Object object, Class<T> context) { return Converters.convert(evaluate(object), context); } }