changeset 292:39c0ff00d188

Introduced a hook concept - currently used for 'post-feed' and 'post-advance'. artifacts/trunk@2327 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 13 Jul 2011 13:12:08 +0000
parents f8c4fa292c9c
children a367a0d011af
files ChangeLog artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java artifact-database/src/main/java/de/intevation/artifactdatabase/FactoryBootstrap.java artifacts/src/main/java/de/intevation/artifacts/Hook.java
diffstat 4 files changed, 155 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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 <ingo@intevation.de>
+
+	* 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	<sascha.teichmann@intevation.de>
 
 	Fix for flys/issue20
--- 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<Hook> postFeedHooks;
+
+    /**
+     * Hooks that are executed after an artifact has advanced.
+     */
+    protected List<Hook> 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<Hook> postFeedHooks) {
+        this.postFeedHooks = postFeedHooks;
+    }
+
+    public void setPostAdvanceHook(List<Hook> 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();
--- 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<Hook> postFeedHooks;
+
+    protected List<Hook> postAdvanceHooks;
+
     /**
      * byte array holding the export signing secret.
      */
@@ -428,6 +439,69 @@
         }
     }
 
+    protected void loadHooks() {
+        logger.info("loading hooks");
+
+        postFeedHooks    = new ArrayList<Hook>();
+        postAdvanceHooks = new ArrayList<Hook>();
+
+        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<Hook> getPostFeedHooks() {
+        return postFeedHooks;
+    }
+
+    public List<Hook> getPostAdvanceHooks() {
+        return postAdvanceHooks;
+    }
+
     public HTTPServer getHTTPServer() {
         return httpServer;
     }
--- /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 :

http://dive4elements.wald.intevation.org