package org.geoserver.python.filter; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.python.Python; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.NameImpl; import org.geotools.filter.FunctionFactory; import org.geotools.util.SoftValueHashMap; import org.opengis.feature.type.Name; import org.opengis.filter.FilterFactory; import org.opengis.filter.capability.FunctionName; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Function; import org.opengis.filter.expression.Literal; public class PythonFilterFunctionFactory implements FunctionFactory { Python py; SoftValueHashMap<Name, PythonFilterFunctionAdapter> adapters = new SoftValueHashMap(10); public List<FunctionName> getFunctionNames() { FilterFactory ff = CommonFactoryFinder.getFilterFactory(null); Python py = py(); List<FunctionName> names = new ArrayList<FunctionName>(); try { File filterRoot = py.getFilterRoot(); for (String file : filterRoot.list()) { if (file.endsWith(".py")) { PythonFilterFunctionAdapter adapter = new PythonFilterFunctionAdapter(new File(filterRoot, file), py); for(String name : adapter.getNames()) { FunctionName fname = ff.functionName(name, adapter.getParameterNames(name).size()); names.add(fname); } } } } catch (IOException e) { Python.LOGGER.log(Level.WARNING, "Error looking up filter functions", e); } return names; } public Function function(String name, List<Expression> args, Literal fallback) { return function(new NameImpl(name), args, fallback); } public Function function(Name name, List<Expression> args, Literal fallback) { PythonFilterFunctionAdapter adapter = adapter(name); if (adapter == null) { return null; } return new PythonFunction(name, args, adapter); }; Python py() { if (py == null) { py = GeoServerExtensions.bean(Python.class); } return py; } PythonFilterFunctionAdapter adapter(Name name) { PythonFilterFunctionAdapter adapter = adapters.get(name); if (adapter == null) { synchronized(this) { adapter = adapters.get(name); if (adapter == null) { try { adapter = createFilterFunctionAdapter(name); } catch (IOException e) { throw new RuntimeException(e); } if (adapter != null) { adapters.put(name, adapter); } } } } return adapter; } private PythonFilterFunctionAdapter createFilterFunctionAdapter(Name name) throws IOException { for (File f : py().getFilterRoot().listFiles()) { PythonFilterFunctionAdapter adapter = new PythonFilterFunctionAdapter(f, py()); if (adapter.getNames().contains(name.getLocalPart())) { return adapter; } } return null; } }