Mercurial > dive4elements > river
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
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 :