/* (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.py; import java.util.Map; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptException; import org.geoserver.script.wfs.WfsTxHook; import org.geoserver.wfs.WFSException; import org.geoserver.wfs.request.TransactionRequest; import org.geoserver.wfs.request.TransactionResponse; import org.geotools.feature.FeatureCollection; import org.python.core.Py; import org.python.core.PyException; import org.python.core.PyFunction; import org.python.core.PyObject; public class PyWfsTxHook extends WfsTxHook { public PyWfsTxHook(PythonPlugin plugin) { super(plugin); } @Override protected void doHandlePreInsert(ScriptEngine engine, FeatureCollection inserted, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("preInsert", engine, inserted, tx, context)) { super.doHandlePreInsert(engine, inserted, tx, context); } } @Override protected void doHandlePostInsert(ScriptEngine engine, FeatureCollection inserted, TransactionRequest tx, java.util.Map<?,?> context) throws ScriptException { if (!findAndCall("postInsert", engine, inserted, tx, context)) { super.doHandlePostInsert(engine, inserted, tx, context); } } @Override protected void doHandlePreUpdate(ScriptEngine engine, FeatureCollection updated, Map<String, Object> props, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("preUpdate", engine, updated, props, tx, context)) { super.doHandlePreUpdate(engine, updated, props, tx, context); } } @Override protected void doHandlePostUpdate(ScriptEngine engine, FeatureCollection updated, Map<String, Object> props, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("postUpdate", engine, updated, props, tx, context)) { super.doHandlePostUpdate(engine, updated, props, tx, context); } } @Override protected void doHandlePreDelete(ScriptEngine engine, FeatureCollection deleted, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("preDelete", engine, deleted, tx, context)) { super.doHandlePreDelete(engine, deleted, tx, context); } } @Override protected void doHandlePostDelete(ScriptEngine engine, FeatureCollection deleted, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("postDelete", engine, deleted, tx, context)) { super.doHandlePostDelete(engine, deleted, tx, context); } } @Override protected void doHandleBefore(ScriptEngine engine, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("before", engine, tx, context)) { super.doHandleBefore(engine, tx, context); } } @Override protected void doHandlePreCommit(ScriptEngine engine, TransactionRequest tx, Map<?, ?> context) throws ScriptException { if (!findAndCall("preCommit", engine, tx, context)) { super.doHandlePreCommit(engine, tx, context); } } @Override protected void doHandlePostCommit(ScriptEngine engine, TransactionRequest tx, TransactionResponse result, Map<?, ?> context) throws ScriptException { if (!findAndCall("postCommit", engine, tx, result, context)) { super.doHandlePostCommit(engine, tx, result, context); } } @Override protected void doHandleAbort(ScriptEngine engine, TransactionRequest tx, TransactionResponse result, Map<?, ?> context) throws ScriptException { if (!findAndCall("abort", engine, tx, result, context)) { super.doHandleAbort(engine, tx, result, context); } } @Override protected void unWrapAndThrowWfsException(ScriptException e) throws ScriptException { if (e.getCause() instanceof PyException) { PyException pye = (PyException) e.getCause(); if (pye.value != null) { Object wfse = pye.value.__tojava__(Exception.class); if (wfse instanceof WFSException) { throw (WFSException) wfse; } } } throw e; } PyFunction findDecoratedFunction(ScriptEngine engine, String name) { Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); for (Object o : bindings.values()) { if (o instanceof PyFunction) { PyFunction f = (PyFunction) o; PyObject d = f.__findattr__("__decorator__"); if (d instanceof PyFunction && name.equals(((PyFunction)d).__name__)) { return f; } } } return null; } boolean findAndCall(String name, ScriptEngine engine, Object... args) { PyFunction f = findDecoratedFunction(engine, name); if (f != null) { call(f, args); return true; } return false; } Object call(PyFunction f, Object... args) { PyObject[] pyargs = new PyObject[args.length]; for (int i = 0; i < args.length; i++) { pyargs[i] = Py.java2py(args[i]); } return f.__call__(pyargs); } }