/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.script.function; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.script.ScriptEngine; import org.geoserver.platform.FileWatcher; import org.geoserver.platform.resource.Resource; import org.geoserver.script.ScriptFileWatcher; import org.geoserver.script.ScriptManager; import org.geotools.filter.FunctionImpl; import org.geotools.filter.capability.FunctionNameImpl; import org.opengis.feature.type.Name; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.VolatileFunction; /** * Implementation of {@link org.opengis.filter.expression.Function} backed by a script. * <p> * This class does its work by delegating all methods to the {@link FunctionHook} interface. This * class maintains a link to the backing script {@link File} and uses a {@link FileWatcher} to * detect changes to the underlying script. When changed a new {@link ScriptEngine} is created and * the underlying script is reloaded. * </p> * @author Justin Deoliveira, OpenGeo * */ public class ScriptFunction { /** the hook for interacting with the script */ FunctionHook hook; /** watcher for changes */ ScriptFileWatcher watcher; public ScriptFunction(Resource file, ScriptManager scriptMgr) { watcher = new ScriptFileWatcher(file, scriptMgr); hook = scriptMgr.lookupFilterHook(file); } @Deprecated public ScriptFunction(File file, ScriptManager scriptMgr) { watcher = new ScriptFileWatcher(file, scriptMgr); hook = scriptMgr.lookupFilterHook(file); } Function instance(Name name, List<Expression> args) { return new Function(name, args); } class Function extends FunctionImpl implements VolatileFunction { Function(Name name, List<Expression> params) { setName(name.getLocalPart()); setParameters(params); functionName = new FunctionNameImpl(name, params.size()); } @Override public Object evaluate(Object object) { try { //round up the arguments List<Object> args = new ArrayList<Object>(); for (Expression e : getParameters()) { args.add(e.evaluate(object)); } return hook.run(object, args, watcher.readIfModified()); } catch(Exception e) { throw new RuntimeException(e); } } } }