changeset 106:5864c41219db

Initializes a TransitionEngine storing all transitions for each artifact at the application start. flys-artifacts/trunk@1288 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 03 Feb 2011 10:23:30 +0000
parents beb991dc4827
children a228b39494a9
files flys-artifacts/ChangeLog flys-artifacts/doc/conf/artifacts/winfo.xml flys-artifacts/doc/conf/conf.xml flys-artifacts/pom.xml flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/State.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/Transition.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/TransitionEngine.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java
diffstat 11 files changed, 506 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Wed Feb 02 14:56:22 2011 +0000
+++ b/flys-artifacts/ChangeLog	Thu Feb 03 10:23:30 2011 +0000
@@ -1,3 +1,38 @@
+2011-02-03  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/states/State.java: New. The
+	  interface description of a state.
+
+	* src/main/java/de/intevation/flys/artifacts/transitions/Transition.java,
+	  src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java:
+	  New. The interface description and a default implementation of a
+	  transition.
+
+	* src/main/java/de/intevation/flys/artifacts/transitions/TransitionEngine.java:
+	  New. The TransitionEngine stores all transitions for each artifact and
+	  should be used to determine, if an artifact can advance from one state to
+	  another.
+
+	* src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java:
+	  New. Transitions should be created by using this class.
+
+	* src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java: New.
+	  The Flys context. It currently defines keys to store important components
+	  in the context.
+
+	* src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java:
+	  New. The context factory initializes the basic components of the
+	  application. Currently, the TransitionEngine is created and all artifacts
+	  with its transitions are read from the global configuration and stored in
+	  the FLYSContext.
+
+	* pom.xml: Added a dependency to the 'artifacts-common' package.
+
+	* doc/conf/artifacts/winfo.xml: Corrected the classname of the
+	  DefaultTransition.
+
+	* doc/conf/conf.xml: Added FLYSContextFactory as context-factory.
+
 2011-02-02  Ingo Weinzierl <ingo@intevation.de>
 
 	* doc/conf/conf.xml: An initial configuration file for the FLYS artifact
--- a/flys-artifacts/doc/conf/artifacts/winfo.xml	Wed Feb 02 14:56:22 2011 +0000
+++ b/flys-artifacts/doc/conf/artifacts/winfo.xml	Thu Feb 03 10:23:30 2011 +0000
@@ -11,7 +11,7 @@
             -->
         </state>
 
-        <transition transition="de.intevation.gnv.transition.DefaultTransition">
+        <transition transition="de.intevation.flys.artifacts.transitions.DefaultTransition">
             <from state="winfo_gauge"/>
             <to state="winfo_calculation_type"/>
         </transition>
--- a/flys-artifacts/doc/conf/conf.xml	Wed Feb 02 14:56:22 2011 +0000
+++ b/flys-artifacts/doc/conf/conf.xml	Thu Feb 03 10:23:30 2011 +0000
@@ -1,6 +1,7 @@
 <artifact-database>
     <export-secret>YOUR_SECRET</export-secret>
     <factories>
+        <context-factory>de.intevation.flys.artifacts.context.FLYSContextFactory</context-factory>
         <artifact-factories>
             <!-- All Artifactfactories which are available in this Database.
                  Each Artifactfactory represents one river. -->
--- a/flys-artifacts/pom.xml	Wed Feb 02 14:56:22 2011 +0000
+++ b/flys-artifacts/pom.xml	Thu Feb 03 10:23:30 2011 +0000
@@ -40,5 +40,10 @@
       <artifactId>artifact-database</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>de.intevation.artifacts.common</groupId>
+      <artifactId>artifacts-common</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
   </dependencies>
 </project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContext.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,40 @@
+package de.intevation.flys.artifacts.context;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.DefaultArtifactContext;
+
+
+/**
+ * This class is used to store application wide information in a global context.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYSContext extends DefaultArtifactContext {
+
+    /** The logger used in this class */
+    private static Logger logger = Logger.getLogger(FLYSContext.class);
+
+    /** The key that is used to store the TransitionEngine in the context */
+    public static final String TRANSITION_ENGINE_KEY =
+        "artifact.transition.engine";
+
+
+    /**
+     * The default constructor.
+     */
+    public FLYSContext() {
+        super();
+    }
+
+
+    /**
+     * A constructor with a config document.
+     */
+    public FLYSContext(Document config) {
+        super(config);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,140 @@
+package de.intevation.flys.artifacts.context;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifacts.ArtifactContextFactory;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+import de.intevation.artifactdatabase.Config;
+
+import de.intevation.flys.artifacts.transitions.Transition;
+import de.intevation.flys.artifacts.transitions.TransitionEngine;
+import de.intevation.flys.artifacts.transitions.TransitionFactory;
+
+
+/**
+ * The ArtifactContextFactory is used to initialize basic components and put
+ * them into the global context of the application.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FLYSContextFactory implements ArtifactContextFactory {
+
+    /** The logger that is used in this class */
+    private static Logger logger = Logger.getLogger(FLYSContextFactory.class);
+
+    /** The XPath to the artifacts configured in the configuration. */
+    public static final String XPATH_ARTIFACTS =
+        "/artifact-database/artifacts/artifact";
+
+    /** The XPath to the name of the artifact. */
+    public static final String XPATH_ARTIFACT_NAME = "@name";
+
+    /** The XPath to the xlink ref in an artifact configuration. */
+    public static final String XPATH_XLINK = "xlink:href";
+
+    /** The XPath to the transitions configured in the artifact config. */
+    public static final String XPATH_TRANSITIONS =
+        "/artifact/states/transition";
+
+    /**
+     * Creates a new FLYSArtifactContext object and initialize all
+     * components required by the application.
+     *
+     * @param config The artifact server configuration.
+     * @return a FLYSArtifactContext.
+     */
+    public Object createArtifactContext(Document config) {
+        FLYSContext context = new FLYSContext(config);
+
+        configureTransitions(config, context);
+
+        return context;
+    }
+
+
+    /**
+     * This method initializes the transition configuration.
+     *
+     * @param config the config document.
+     * @param context the FLYSContext.
+     */
+    protected void configureTransitions(Document config, FLYSContext context) {
+        TransitionEngine engine = new TransitionEngine();
+
+        Document[] artifacts = getArtifactConfigurations(config);
+        logger.info("Found " + artifacts.length + " artifacts in the config.");
+
+        for (Document doc: artifacts) {
+            List<Transition> transitions = new ArrayList<Transition>();
+
+            String artName = (String) XMLUtils.xpath(
+                doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING);
+
+            NodeList transitionList = (NodeList) XMLUtils.xpath(
+                doc, XPATH_TRANSITIONS, XPathConstants.NODESET);
+
+            if (transitionList == null) {
+                logger.warn("The artifact has no transitions configured.");
+                return;
+            }
+
+            int trans = transitionList.getLength();
+
+            logger.info(
+                "Artifact '" + artName + "' has " + trans + " transitions.");
+
+            for (int i = 0; i < trans; i++) {
+                transitions.add(TransitionFactory.createTransition(
+                    transitionList.item(i)));
+            }
+
+            engine.addTransition(artName, transitions);
+        }
+
+        context.put(FLYSContext.TRANSITION_ENGINE_KEY, engine);
+    }
+
+
+    /**
+     * This method returns all artifact documents defined in
+     * <code>config</code>. <br>NOTE: The artifact configurations need to be
+     * stored in own files referenced by an xlink.
+     *
+     * @param config The global configuration.
+     *
+     * @return an array of Artifact configurations.
+     */
+    protected Document[] getArtifactConfigurations(Document config) {
+        NodeList artifacts = (NodeList) XMLUtils.xpath(
+            config, XPATH_ARTIFACTS, XPathConstants.NODESET);
+
+        int count = artifacts.getLength();
+
+        Document[] artifactDocs = new Document[count];
+
+        for (int i = 0; i < count; i++) {
+            Element tmp = (Element) artifacts.item(i);
+
+            String xlink = tmp.getAttribute(XPATH_XLINK);
+            xlink        = Config.replaceConfigDir(xlink);
+
+            File artifactFile = new File(xlink);
+            artifactDocs[i]   = XMLUtils.parseDocument(artifactFile);
+        }
+
+        return artifactDocs;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/State.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,27 @@
+package de.intevation.flys.artifacts.states;
+
+import java.io.Serializable;
+
+/**
+ * This interface describes the basic method a concrete state class needs to
+ * implement.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface State extends Serializable {
+
+    /**
+     * Return the id of the state.
+     *
+     * @return the id.
+     */
+    public String getID();
+
+    /**
+     * Return the description of the state.
+     *
+     * @return the description of the state.
+     */
+    public String getDescription();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/DefaultTransition.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,89 @@
+package de.intevation.flys.artifacts.transitions;
+
+import de.intevation.flys.artifacts.states.State;
+
+/**
+ * The default implementation of a <code>Transition</code>.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class DefaultTransition implements Transition {
+
+    /** The ID of the current state */
+    protected String from;
+
+    /** The ID of the target state */
+    protected String to;
+
+
+    /**
+     * The default constructor.
+     */
+    public DefaultTransition() {
+    }
+
+
+    /**
+     * The default constructor.
+     *
+     * @param from The current state.
+     * @param to The target state.
+     */
+    public DefaultTransition(String from, String to) {
+        this.from = from;
+        this.to   = to;
+    }
+
+
+    /**
+     * Returns the current state ID.
+     *
+     * @return the current state ID.
+     */
+    public String getFrom() {
+        return from;
+    }
+
+
+    /**
+     * Returns the target state ID.
+     *
+     * @return the target state ID.
+     */
+    public String getTo() {
+        return to;
+    }
+
+
+    /**
+     * Set the current state ID.
+     *
+     * @param to the current state ID.
+     */
+    public void setFrom(String from) {
+        this.from = from;
+    }
+
+
+    /**
+     * Set the target state ID.
+     *
+     * @param to the target state ID.
+     */
+    public void setTo(String to) {
+        this.to = to;
+    }
+
+
+    /**
+     * This method always returns <i>true</i>.
+     *
+     * @param state The target state.
+     *
+     * @return true.
+     */
+    public boolean isValid(State state) {
+        return true;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/Transition.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,40 @@
+package de.intevation.flys.artifacts.transitions;
+
+import de.intevation.flys.artifacts.states.State;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public interface Transition {
+
+    /**
+     * Return the ID of the start State.
+     */
+    public String getFrom();
+
+    /**
+     * Return the ID of the target State.
+     */
+    public String getTo();
+
+    /**
+     * Set the ID of the current State.
+     *
+     * @param from The ID of the current state.
+     */
+    public void setFrom(String from);
+
+    /**
+     * Set the ID of the target State.
+     *
+     * @param to The ID of the target state.
+     */
+    public void setTo(String to);
+
+    /**
+     * Determines if the transition from <code>state</code> is valid.
+     */
+    public boolean isValid(State state);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/TransitionEngine.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,60 @@
+package de.intevation.flys.artifacts.transitions;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+/**
+ * The TransitionEngine stores all transitions for each Artifact and should be
+ * used to determine, if an Artifact is able to advance from one to another
+ * state.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class TransitionEngine {
+
+    /** The logger used in this class. */
+    private static Logger logger = Logger.getLogger(TransitionEngine.class);
+
+    /**
+     * A map that contains the transitions of the artifacts. The key is the name
+     * of the artifact, its value is a list of all transitions of this artifact.
+     */
+    protected Map<String, List> transitions;
+
+
+    /**
+     * The default constructor.
+     */
+    public TransitionEngine() {
+        transitions = new HashMap<String, List>();
+    }
+
+
+    /**
+     * Add new transitions for a specific artifact.
+     *
+     * @param artifact the name of the Artifact.
+     * @param transitions the list of transition of the artifact.
+     *
+     * @return true, if the transitions were added, otherwise false.
+     */
+    public boolean addTransition(String artifact, List transitions) {
+        List tmp = this.transitions.get(artifact);
+
+        if (tmp != null) {
+            logger.info(
+                "Transitions for the artifact '"
+                + artifact
+                + "' already stored.");
+
+            return false;
+        }
+
+        logger.debug("Add new transitions for artifact '" + artifact + "'");
+        return this.transitions.put(artifact, transitions) != null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/transitions/TransitionFactory.java	Thu Feb 03 10:23:30 2011 +0000
@@ -0,0 +1,68 @@
+package de.intevation.flys.artifacts.transitions;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Node;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class TransitionFactory {
+
+    /** The logger used in this class */
+    private static Logger logger = Logger.getLogger(TransitionFactory.class);
+
+    /** The XPath to the classname of the transition */
+    public static final String XPATH_TRANSITION = "@transition";
+
+    /** The XPath to the current state ID */
+    public static final String XPATH_CURRENT_STATE = "from/@state";
+
+    /** The XPath to the target state ID */
+    public static final String XPATH_TARGET_STATE = "to/@state";
+
+
+    /**
+     * Creates a new Transition based on the configured class provided by
+     * <code>transitionConf</code>.
+     *
+     * @param transitionConf The configuration of the transition.
+     *
+     * @return a Transition.
+     */
+    public static Transition createTransition(Node transitionConf) {
+        String clazz = (String) XMLUtils.xpath(
+            transitionConf, XPATH_TRANSITION, XPathConstants.STRING);
+
+        Transition transition = null;
+
+        try {
+            transition = (Transition) Class.forName(clazz).newInstance();
+
+            String from = (String) XMLUtils.xpath(
+                transitionConf, XPATH_CURRENT_STATE, XPathConstants.STRING);
+            String to = (String) XMLUtils.xpath(
+                transitionConf, XPATH_TARGET_STATE, XPathConstants.STRING);
+
+            transition.setFrom(from);
+            transition.setTo(to);
+        }
+        catch (InstantiationException ie) {
+            logger.error(ie, ie);
+        }
+        catch (IllegalAccessException iae) {
+            logger.error(iae, iae);
+        }
+        catch (ClassNotFoundException cnfe) {
+            logger.error(cnfe, cnfe);
+        }
+
+        return transition;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org