# HG changeset patch # User Ingo Weinzierl # Date 1310562728 0 # Node ID 39c0ff00d1886c3226751e6f60c9c0f7abf9a8ee # Parent f8c4fa292c9c112f20c0a97ed415b8cb90b3c057 Introduced a hook concept - currently used for 'post-feed' and 'post-advance'. artifacts/trunk@2327 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r f8c4fa292c9c -r 39c0ff00d188 ChangeLog --- a/ChangeLog Wed Jul 13 11:00:30 2011 +0000 +++ b/ChangeLog Wed Jul 13 13:12:08 2011 +0000 @@ -1,3 +1,15 @@ +2011-07-13 Ingo Weinzierl + + * artifacts/src/main/java/de/intevation/artifacts/Hook.java: New. A hook + can be used to execute at a specific point in time. E.g. after an + Artifact was fed or after an Artifact has advanced. + + * artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java: + Call hooks after Artifact's feed() and advance() operations. + + * artifact-database/src/main/java/de/intevation/artifactdatabase/FactoryBootstrap.java: + Load hooks from configuration that match the XPath "/artifact-database/hooks/hook". + 2011-07-13 Sascha L. Teichmann Fix for flys/issue20 diff -r f8c4fa292c9c -r 39c0ff00d188 artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java --- a/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java Wed Jul 13 11:00:30 2011 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java Wed Jul 13 13:12:08 2011 +0000 @@ -23,6 +23,7 @@ import de.intevation.artifacts.CallContext; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.CollectionItem; +import de.intevation.artifacts.Hook; import de.intevation.artifacts.Service; import de.intevation.artifacts.ServiceFactory; import de.intevation.artifacts.User; @@ -38,6 +39,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.xml.xpath.XPathConstants; @@ -418,6 +420,16 @@ protected CallContext.Listener callContextListener; /** + * Hooks that are executed after an artifact has been fed. + */ + protected List postFeedHooks; + + /** + * Hooks that are executed after an artifact has advanced. + */ + protected List postAdvanceHooks; + + /** * Default constructor. */ public ArtifactDatabaseImpl() { @@ -449,6 +461,7 @@ setupServices(bootstrap); setupUserFactory(bootstrap); setupCallContextListener(bootstrap); + setupHooks(bootstrap); context = bootstrap.getContext(); exportSecret = bootstrap.getExportSecret(); @@ -466,6 +479,15 @@ this.callContextListener = callContextListener; } + + public void setPostFeedHook(List postFeedHooks) { + this.postFeedHooks = postFeedHooks; + } + + public void setPostAdvanceHook(List postAdvanceHooks) { + this.postAdvanceHooks = postAdvanceHooks; + } + /** * Used to extract the artifact collection factory from bootstrap. * @@ -509,6 +531,12 @@ setCallContextListener(bootstrap.getCallContextListener()); } + + protected void setupHooks(FactoryBootstrap bootstrap) { + setPostFeedHook(bootstrap.getPostFeedHooks()); + setPostAdvanceHook(bootstrap.getPostAdvanceHooks()); + } + /** * Used to extract the user factory from the bootstrap. */ @@ -734,7 +762,16 @@ artifact); try { - return artifact.getArtifact().advance(target, cc); + Artifact art = artifact.getArtifact(); + Document res = art.advance(target, cc); + + if (postAdvanceHooks != null) { + for (Hook hook: postAdvanceHooks) { + hook.execute(art, cc); + } + } + + return res; } finally { cc.postCall(); @@ -758,7 +795,16 @@ artifact); try { - return artifact.getArtifact().feed(data, cc); + Artifact art = artifact.getArtifact(); + Document res = art.feed(data, cc); + + if (postFeedHooks != null) { + for (Hook hook: postFeedHooks) { + hook.execute(art, cc); + } + } + + return res; } finally { cc.postCall(); diff -r f8c4fa292c9c -r 39c0ff00d188 artifact-database/src/main/java/de/intevation/artifactdatabase/FactoryBootstrap.java --- a/artifact-database/src/main/java/de/intevation/artifactdatabase/FactoryBootstrap.java Wed Jul 13 11:00:30 2011 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/FactoryBootstrap.java Wed Jul 13 13:12:08 2011 +0000 @@ -14,6 +14,7 @@ import de.intevation.artifacts.ArtifactContextFactory; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.Hook; import de.intevation.artifacts.ServiceFactory; import de.intevation.artifacts.UserFactory; @@ -21,6 +22,7 @@ import de.intevation.artifactdatabase.rest.HTTPServer; import java.util.ArrayList; +import java.util.List; import org.apache.log4j.Logger; @@ -104,6 +106,11 @@ public static final String CALLCONTEXT_LISTENER = "/artifact-database/callcontext-listener"; + /** + * XPath that points to configuration nodes for hooks. + */ + public static final String HOOKS = + "/artifact-database/hooks/hook"; public static final String HTTP_SERVER = "/artifact-database/rest-server/http-server/text()"; @@ -151,6 +158,10 @@ */ protected CallContext.Listener callContextListener; + protected List postFeedHooks; + + protected List postAdvanceHooks; + /** * byte array holding the export signing secret. */ @@ -428,6 +439,69 @@ } } + protected void loadHooks() { + logger.info("loading hooks"); + + postFeedHooks = new ArrayList(); + postAdvanceHooks = new ArrayList(); + + NodeList nodes = Config.getNodeSetXPath(HOOKS); + + for (int i = 0, len = nodes.getLength(); i < len; i++) { + Node cfg = nodes.item(i); + String applies = Config.getStringXPath(cfg, "@applies"); + + if (applies == null || applies.length() == 0) { + continue; + } + + Hook hook = loadHook(cfg); + String[] apply = applies.split(","); + + for (String a: apply) { + a = a.trim().toLowerCase(); + + if (a.equals("post-feed")) { + postFeedHooks.add(hook); + } + else if (a.equals("post-advance")) { + postAdvanceHooks.add(hook); + } + } + } + } + + protected Hook loadHook(Node hookCfg) { + if (hookCfg == null) { + return null; + } + + Hook hook = null; + + String className = Config.getStringXPath(hookCfg, "@class"); + + try { + Class clazz = Class.forName(className); + hook = (Hook) clazz.newInstance(); + + hook.setup(hookCfg); + } + catch (ClassNotFoundException cnfe) { + logger.error(cnfe.getLocalizedMessage(), cnfe); + } + catch (InstantiationException ie) { + logger.error(ie.getLocalizedMessage(), ie); + } + catch (ClassCastException cce) { + logger.error(cce.getLocalizedMessage(), cce); + } + catch (IllegalAccessException iae) { + logger.error(iae.getLocalizedMessage(), iae); + } + + return hook; + } + /** * Fetches the export signing secret from the global configuration. * If none is found if defaults to the DEFAULT_EXORT_SECRET which @@ -456,6 +530,7 @@ loadUserFactory(); loadCallContextListener(); loadHTTPServer(); + loadHooks(); } /** @@ -518,6 +593,14 @@ return callContextListener; } + public List getPostFeedHooks() { + return postFeedHooks; + } + + public List getPostAdvanceHooks() { + return postAdvanceHooks; + } + public HTTPServer getHTTPServer() { return httpServer; } diff -r f8c4fa292c9c -r 39c0ff00d188 artifacts/src/main/java/de/intevation/artifacts/Hook.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/de/intevation/artifacts/Hook.java Wed Jul 13 13:12:08 2011 +0000 @@ -0,0 +1,12 @@ +package de.intevation.artifacts; + +import org.w3c.dom.Node; + + +public interface Hook { + + void setup(Node config); + + void execute(Artifact artifact, CallContext context); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :