r769 - in trunk: wikitty-api/src/main/java/org/nuiton/wikitty wikitty-api/src/main/java/org/nuiton/wikitty/services wikitty-publication/src/main/java/org/nuiton/wikitty/publication
Author: bpoussin Date: 2011-04-08 15:46:27 +0200 (Fri, 08 Apr 2011) New Revision: 769 Url: http://nuiton.org/repositories/revision/wikitty/769 Log: Evolution #1449: Add Hook support in WikittyService (useful for trigger or calculated field) Create ScriptEvaluator class for hook evaluation and use it for WikittyPublication Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/ScriptEvaluator.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java Modified: trunk/wikitty-publication/src/main/java/org/nuiton/wikitty/publication/ActionEval.java Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/ScriptEvaluator.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/ScriptEvaluator.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/ScriptEvaluator.java 2011-04-08 13:46:27 UTC (rev 769) @@ -0,0 +1,141 @@ +package org.nuiton.wikitty; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class ScriptEvaluator { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ScriptEvaluator.class); + + static protected ScriptEngineManager scriptEnginManager; + + /** + * Return all time new ScriptEnginManager if classLoader is not null + * else return default ScriptEnginManager + * + * @param classLoader ClassLoader used to looking for ScriptEngin, can be null + * @return ScriptEnginManager + */ + static public ScriptEngineManager getScriptEnginManager(ClassLoader classLoader) { + ScriptEngineManager result; + if (classLoader != null) { + result = new ScriptEngineManager(); + } else { + if (scriptEnginManager == null) { + // create default ScriptEngineManager + scriptEnginManager = new ScriptEngineManager(); + } + result = scriptEnginManager; + } + return result; + } + + /** + * + * @param classLoader + * @param name only used in exception message (this help to determine what + * script failed) + * @param mimetype script engine looking for this specific mimetype + * @return ScriptEngine or exception if not available for this mimetype + */ + static public ScriptEngine getScriptEngin(ClassLoader classLoader, + String name, String mimetype) { + ScriptEngineManager scriptEnginManager = getScriptEnginManager(classLoader); + ScriptEngine scriptEngin = scriptEnginManager.getEngineByMimeType(mimetype); + if (scriptEngin == null) { + List<ScriptEngineFactory> factories = + scriptEnginManager.getEngineFactories(); + String msgFactories = ""; + for (ScriptEngineFactory f : factories) { + msgFactories += String.format( + "\n%s extensions: %s mimetypes: %s", + f.getEngineName(), f.getExtensions(), f.getMimeTypes()); + } + throw new WikittyException(String.format( + "Can't find engine for %s(%s). Available engines: %s", + name, mimetype, msgFactories)); + } else { + return scriptEngin; + } + } + + /** + * Evalue le script et retourne le retour de l'evaluation + * + * @param classLoader optionnal classLoader used to find ScriptEngine + * @param name + * @param script + * @param mimetype + * @param bindings + * @return + */ + static public Object eval(ClassLoader classLoader, String name, + String script, String mimetype, Map<String, Object> bindings) { + ScriptEngine scriptEngin = getScriptEngin(classLoader, name, mimetype); + + Bindings b = scriptEngin.createBindings(); + b.putAll(bindings); + try { + Object result = scriptEngin.eval(script, b); + return result; + } catch (ScriptException eee) { + throw new WikittyException(String.format( + "Can't evaluated script %s(%s=>%s) script was\n%s", + name, mimetype, + scriptEngin.getFactory().getEngineName(), script), eee); + } + } + + /** + * Evalue le script et recupere a la fin de l'evaluation les valeurs + * des variables presentes dans la map bindings. Le resultat a exactement + * les memes cles que binding. + * + * @param classLoader optionnal classLoader used to find ScriptEngine + * @param name + * @param script + * @param mimetype + * @param bindings + * @return + */ + static public Map<String, Object> exec(ClassLoader classLoader, String name, + String script, String mimetype, Map<String, Object> bindings) { + ScriptEngine scriptEngin = getScriptEngin(classLoader, name, mimetype); + + Bindings b = scriptEngin.createBindings(); + b.putAll(bindings); + try { + scriptEngin.eval(script, b); + Map<String, Object> result = new HashMap<String, Object>(); + for (Map.Entry<String, Object> e : bindings.entrySet()) { + Object value = scriptEngin.get(e.getKey()); + result.put(e.getKey(), value); + } + return result; + } catch (ScriptException eee) { + throw new WikittyException(String.format( + "Can't evaluated script %s(%s=>%s) script was\n%s", + name, mimetype, + scriptEngin.getFactory().getEngineName(), script), eee); + } + } + +} Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceHook.java 2011-04-08 13:46:27 UTC (rev 769) @@ -0,0 +1,276 @@ +package org.nuiton.wikitty.services; + + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.ApplicationConfig; +import org.nuiton.wikitty.ScriptEvaluator; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.entities.WikittyHook; +import org.nuiton.wikitty.entities.WikittyHookHelper; +import org.nuiton.wikitty.search.Criteria; +import org.nuiton.wikitty.search.PagedResult; +import org.nuiton.wikitty.search.Search; + +/** + * Cette classe permet d'intercepter les modifications faites via les differentes + * methodes de modification des données et d'executer les differents WikittyHook + * enregistres. + * + * Les WikittyHook peuvent + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceHook extends WikittyServiceDelegator { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceHook.class); + + final static public String PRE_STORE = "pre-store"; + final static public String POST_STORE = "post-store"; + final static public String PRE_STORE_EXTENSION = "pre-storeExtension"; + final static public String POST_STORE_EXTENSION = "post-storeExtension"; + final static public String PRE_DELETE = "pre-delete"; + final static public String POST_DELETE = "post-delete"; + final static public String PRE_DELETE_EXTENSION = "pre-deleteExtension"; + final static public String POST_DELETE_EXTENSION = "post-deleteExtension"; + final static public String PRE_DELETE_TREE = "pre-deleteTree"; + final static public String POST_DELETE_TREE = "post-deleteTree"; + final static public String PRE_CLEAR = "pre-clear"; + final static public String POST_CLEAR = "post-clear"; + final static public String PRE_LOGIN = "pre-login"; + final static public String POST_LOGIN = "post-login"; + final static public String PRE_LOGOUT = "pre-logout"; + final static public String POST_LOGOUT = "post-logout"; + final static public String PRE_REPLAY = "pre-replay"; + final static public String POST_REPLAY = "post-replay"; + final static public String PRE_SYNC_SEARCH_ENGINE = "pre-syncSearchEngine"; + final static public String POST_SYNC_SEARCH_ENGINE = "post-syncSearchEngine"; + + /** + * + * @param config not use currently but needed in futur + * @param ws + */ + public WikittyServiceHook(ApplicationConfig config, WikittyService ws) { + super(ws); + } + + protected Collection<Wikitty> getHook(String securityToken, String actionName) { + Criteria criteria = Search.query().exteq(WikittyHook.EXT_WIKITTYHOOK) + .and().eq(WikittyHook.FQ_FIELD_WIKITTYHOOK_ACTIONTOHOOK, actionName) + .criteria(); + PagedResult<String>[] ids = getDelegate().findAllByCriteria(securityToken, criteria); + + List<Wikitty> result = getDelegate().restore(securityToken, ids[0].getAll()); + + return result; + } + + protected Map<String, Object> callHook(String securityToken, String actionName, + Map<String, Object> args, WikittyEvent event) { + Collection<Wikitty> hooks = getHook(securityToken, actionName); + + WikittyService ws = getDelegate(); + args.put("actionName", actionName); + args.put("ws", ws); + args.put("event", event); + + for (Wikitty hook : hooks) { + String hookName = WikittyHookHelper.getName(hook); + String mimetype = WikittyHookHelper.getMimetype(hook); + String script = WikittyHookHelper.getScript(hook); + + args.put("hook", hook); + + args = ScriptEvaluator.exec(null, hookName, script, mimetype, args); + } + return args; + } + + @Override + public WikittyEvent store(String securityToken, Collection<Wikitty> wikitties, boolean force) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + args.put("wikitties", wikitties); + args.put("force", force); + + args = callHook(securityToken, PRE_STORE, args, null); + + securityToken = (String)args.get("securityToken"); + wikitties= (Collection<Wikitty>)args.get("wikitties"); + force = (Boolean)args.get("force"); + + WikittyEvent result = super.store(securityToken, wikitties, force); + + callHook(securityToken, POST_STORE, args, result); + + return result; + } + + @Override + public WikittyEvent storeExtension(String securityToken, Collection<WikittyExtension> exts) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + args.put("exts", exts); + + args = callHook(securityToken, PRE_STORE_EXTENSION, args, null); + + securityToken = (String)args.get("securityToken"); + exts = (Collection<WikittyExtension>) args.get("exts"); + + WikittyEvent result = super.storeExtension(securityToken, exts); + + callHook(securityToken, POST_STORE_EXTENSION, args, result); + + return result; + } + + @Override + public WikittyEvent delete(String securityToken, Collection<String> ids) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + args.put("ids", ids); + + args = callHook(securityToken, PRE_DELETE, args, null); + + securityToken = (String)args.get("securityToken"); + ids = (Collection<String>) args.get("ids"); + + WikittyEvent result = super.delete(securityToken, ids); + + callHook(securityToken, POST_DELETE, args, result); + + return result; + } + + @Override + public WikittyEvent deleteExtension(String securityToken, Collection<String> extNames) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + args.put("extNames", extNames); + + args = callHook(securityToken, PRE_DELETE_EXTENSION, args, null); + + securityToken = (String)args.get("securityToken"); + extNames = (Collection<String>) args.get("extNames"); + + WikittyEvent result = super.deleteExtension(securityToken, extNames); + + callHook(securityToken, POST_DELETE_EXTENSION, args, result); + + return result; + } + + @Override + public WikittyEvent deleteTree(String securityToken, String wikittyId) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + args.put("wikittyId", wikittyId); + + args = callHook(securityToken, PRE_DELETE_TREE, args, null); + + securityToken = (String)args.get("securityToken"); + wikittyId = (String) args.get("wikittyId"); + + WikittyEvent result = super.deleteTree(securityToken, wikittyId); + + callHook(securityToken, POST_DELETE_TREE, args, result); + + return result; + } + + @Override + public WikittyEvent clear(String securityToken) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + + args = callHook(securityToken, PRE_CLEAR, args, null); + + securityToken = (String)args.get("securityToken"); + + WikittyEvent result = super.clear(securityToken); + + callHook(securityToken, POST_CLEAR, args, result); + + return result; + } + + @Override + public String login(String login, String password) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("login", login); + args.put("password", password); + + args = callHook(null, PRE_LOGIN, args, null); + + login = (String)args.get("login"); + password = (String) args.get("password"); + + String result = super.login(login, password); + + callHook(null, POST_LOGIN, args, null); + + return result; + } + + @Override + public void logout(String securityToken) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + + args = callHook(securityToken, PRE_LOGOUT, args, null); + + securityToken = (String)args.get("securityToken"); + + super.logout(securityToken); + + callHook(securityToken, POST_LOGOUT, args, null); + } + + @Override + public WikittyEvent replay(String securityToken, List<WikittyEvent> events, boolean force) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + args.put("events", events); + args.put("force", force); + + args = callHook(securityToken, PRE_REPLAY, args, null); + + securityToken = (String)args.get("securityToken"); + events = (List<WikittyEvent>) args.get("events"); + force = (Boolean)args.get("force"); + + WikittyEvent result = super.replay(securityToken, events, force); + + callHook(securityToken, POST_REPLAY, args, result); + + return result; + } + + @Override + public void syncSearchEngine(String securityToken) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("securityToken", securityToken); + + args = callHook(securityToken, PRE_SYNC_SEARCH_ENGINE, args, null); + + securityToken = (String)args.get("securityToken"); + + super.syncSearchEngine(securityToken); + + callHook(securityToken, POST_SYNC_SEARCH_ENGINE, args, null); + + } + +} Modified: trunk/wikitty-publication/src/main/java/org/nuiton/wikitty/publication/ActionEval.java =================================================================== --- trunk/wikitty-publication/src/main/java/org/nuiton/wikitty/publication/ActionEval.java 2011-04-08 11:26:05 UTC (rev 768) +++ trunk/wikitty-publication/src/main/java/org/nuiton/wikitty/publication/ActionEval.java 2011-04-08 13:46:27 UTC (rev 769) @@ -38,6 +38,7 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.util.ApplicationConfig; import org.nuiton.util.StringUtil; +import org.nuiton.wikitty.ScriptEvaluator; import org.nuiton.wikitty.WikittyException; import org.nuiton.wikitty.WikittyProxy; import org.nuiton.wikitty.entities.Wikitty; @@ -102,37 +103,6 @@ scriptEnginManager = new ScriptEngineManager(); } - protected Object eval(String name, String script, String mimetype, - Map<String, Object> bindings) { - ScriptEngine scriptEngin = scriptEnginManager.getEngineByMimeType(mimetype); - if (scriptEngin == null) { - List<ScriptEngineFactory> factories = - scriptEnginManager.getEngineFactories(); - String msgFactories = ""; - for (ScriptEngineFactory f : factories) { - msgFactories += String.format( - "\n%s extensions: %s mimetypes: %s", - f.getEngineName(), f.getExtensions(), f.getMimeTypes()); - } - throw new WikittyException(String.format( - "Can't find engine for %s(%s). Available engines: %s", - name, mimetype, msgFactories)); - } else { - Bindings b = scriptEngin.createBindings(); - b.putAll(bindings); - try { - Object result = scriptEngin.eval(script, b); - return result; - } catch (ScriptException eee) { - throw new WikittyException(String.format( - "Can't evaluated script %s(%s=>%s) script was\n%s", - name, mimetype, - scriptEngin.getFactory().getEngineName(), script), eee); - } - } - - } - public Object doAction(WikittyPublicationContext context, List<String> subContext) { log.info("path " + subContext); @@ -150,7 +120,7 @@ if (w == null) { context.setContentType("text/plain"); result = String.format( - "no data found for criteria %s", criteria); + "no data found for criteria '%s'", criteria); } else { String contentField = getContentFieldName(context, criteria.getName(), w); @@ -173,7 +143,8 @@ bindings.put(WIKITTY_VAR, w); bindings.put(EVAL_VAR, this); - result = eval(criteria.getName(), content, mimetype, bindings); + result = ScriptEvaluator.eval( + null, criteria.getName(), content, mimetype, bindings); } } }
participants (1)
-
bpoussin@users.nuiton.org