changeset 470:b7bb66440cc8

Added mechanism for advancing to previous states. gnv-artifacts/trunk@533 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 12 Jan 2010 15:25:32 +0000
parents 62fc63d0f71d
children 06887e2e3f7a
files gnv-artifacts/ChangeLog gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java gnv-artifacts/src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxState.java gnv-artifacts/src/main/java/de/intevation/gnv/state/SingleInputState.java gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java
diffstat 7 files changed, 202 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/gnv-artifacts/ChangeLog	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/ChangeLog	Tue Jan 12 15:25:32 2010 +0000
@@ -1,3 +1,24 @@
+2010-01-12  Ingo Weinzierl <ingo.weinzierl@intevation.de>
+
+	* src/main/java/de/intevation/gnv/state/SingleInputState.java,
+	  src/main/java/de/intevation/gnv/state/MinMaxState.java,
+	  src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java:
+	  Data, describing the user interface, is stored in a list instead of a
+	  collection, now. This makes it easier to remove the last element if we
+	  advance back.
+
+	* src/main/java/de/intevation/gnv/state/State.java,
+	  src/main/java/de/intevation/gnv/state/StateBase.java: Added a 'reset'
+	  method to clear data which has been inserted before returning to an old
+	  state. This is called when we try to advance into the past.
+
+	* src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: Now, it's
+	  possible to advance to an earlier state. The 'advance' method first
+	  searches for a given target name in the list of reachable targets. If no
+	  future target has been found, the method looks for an old state with this
+	  target name. The last option is to return to the initial step for choosing
+	  the FIS, if the target name is 'start'.
+
 2010-01-12  Tim Englich  <tim.englich@intevation.de>
 
 	* doc/conf/queries.properties: 
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java	Tue Jan 12 15:25:32 2010 +0000
@@ -21,12 +21,14 @@
 
 import de.intevation.artifactdatabase.Config;
 import de.intevation.artifactdatabase.DefaultArtifact;
+import de.intevation.artifactdatabase.ProxyArtifact;
 import de.intevation.artifactdatabase.XMLUtils;
 import de.intevation.artifacts.ArtifactFactory;
 import de.intevation.artifacts.ArtifactNamespaceContext;
 import de.intevation.artifacts.CallContext;
 import de.intevation.artifacts.CallMeta;
 import de.intevation.gnv.artifacts.context.GNVArtifactContext;
+import de.intevation.gnv.artifacts.fis.FISSelectArtifact;
 import de.intevation.gnv.artifacts.fis.product.Product;
 import de.intevation.gnv.artifacts.ressource.RessourceFactory;
 import de.intevation.gnv.state.DefaultInputData;
@@ -80,6 +82,8 @@
 
     public static final String XPATH_OUTPUT_PARAMS = "/art:action/art:out/art:params/art:input"; 
 
+    public static final String INITIAL_STATE = "start";
+
     /**
      * The current State
      */
@@ -106,8 +110,6 @@
      */
     protected String name = null;
 
-    private ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities();
-
     /**
      * Constructor
      */
@@ -115,64 +117,152 @@
         super();
     }
 
-    /**
-     * @see de.intevation.artifactdatabase.DefaultArtifact#advance(org.w3c.dom.Document,
-     *      de.intevation.artifacts.CallContext)
-     */
+
     @Override
     public Document advance(Document target, CallContext context) {
-        log.debug("GNVArtifactBase.advance");
-        Document result = XMLUtils.newDocument();
+        log.debug("GNVArtifactBase.advance()");
+
+        Document result      = XMLUtils.newDocument();
+        String   targetState = XMLUtils.xpathString(
+            target, XPATH_TARGET_NAME, ArtifactNamespaceContext.INSTANCE
+        );
+
+        // no current state...
+        if (current == null) {
+            log.debug("No current state. Advance not possible.");
+
+            result = createReport(
+                result,
+                "exceptionreport",
+                "exception",
+                "No State activated."
+            );
+
+            return result;
+        }
+
+        State next = null;
+
         try {
-            if (this.current != null) {
-                String stateName = this.readStateName(target);
-                log.debug("Statename: " + stateName);
-                if (this.isStateCurrentlyReachable(stateName)) {
-                    try {
-                        State nextStep = this.states
-                                .get(stateName);
-                        // 1.Calculate Results
-                        this.current.advance(super.identifier, context.getMeta());
-                        // 2. Transfer Results
-                        nextStep.putInputData(this.current.getInputData(), 
-                                              super.identifier);
-                        // 3. Switch to next State
-                        this.current = nextStep;
-                        
-                        // 4. Initialize next Step
-                        this.current.initialize(super.identifier, context.getMeta());
-                        
-                        result = new ArtifactXMLUtilities()
-                                .createSuccessReport("Advance success",
-                                        XMLUtils.newDocument());
-                    } catch (StateException e) {
-                        log.error(e, e);
-                        result = new ArtifactXMLUtilities()
-                                .createExceptionReport(e
-                                        .getLocalizedMessage(), XMLUtils
-                                        .newDocument());
-                    }
-                } else {
-                    String msg = "Statetransition is not supported";
-                    log.error(msg);
-                    result = new ArtifactXMLUtilities().createExceptionReport(
-                            msg, XMLUtils.newDocument());
-                }
-            } else {
-                String msg = "No State activated.";
-                log.error(msg);
-                result = new ArtifactXMLUtilities().createExceptionReport(msg,
-                        XMLUtils.newDocument());
+
+            // step forward
+            if (isStateCurrentlyReachable(targetState)) {
+                next = states.get(targetState);
+
+                // 2. Transfer Results
+                next.putInputData(current.getInputData(), identifier);
+                next.setParent(current);
+
+                // 3. Switch to next State
+                current = next;
+
+                // 4. Initialize next Step
+                current.initialize(identifier, context.getMeta());
+
+                result = createReport(
+                    result, "result", "success", "Advance success"
+                );
             }
-        } catch (Exception e) {
-            log.error(e, e);
-            result = new ArtifactXMLUtilities().createExceptionReport(e
-                    .getLocalizedMessage(), XMLUtils.newDocument());
+
+            // step backward
+            else if((next = getPreviousState(current, targetState)) != null) {
+                resetFutureStates(current, targetState);
+                current = next;
+
+                result = createReport(
+                    result, "result", "success", "Advance success"
+                );
+            }
+
+            // goto initial step
+            else if(targetState.equals(INITIAL_STATE)) {
+                FISSelectArtifact select = new FISSelectArtifact();
+                select.setup(identifier, new GNVArtifactFactory(), context);
+                context.putContextValue(ProxyArtifact.REPLACE_PROXY, select);
+
+                result = createReport(
+                    result, "result", "success", "Advance success"
+                );
+            }
+
+            // advance not possible
+            else {
+                log.warn("advance not possible for target: " + targetState);
+                result = createReport(
+                    result,
+                    "exceptionreport",
+                    "exception",
+                    "Statetransition not supported"
+                );
+            }
         }
+        catch (StateException se) {
+            log.error(se, se);
+            result = createReport(
+                result,
+                "exceptionreport",
+                "exception",
+                se.getLocalizedMessage()
+            );
+        }
+
         return result;
     }
-    
-    
+
+
+    protected Document createReport(
+        Document document,
+        String   nodeName,
+        String   state,
+        String   msg
+    ) {
+        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
+            document,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX
+        );
+
+        Element reportNode = creator.create(nodeName);
+        Element stateNode  = creator.create(state);
+
+        stateNode.setTextContent(msg);
+        reportNode.appendChild(stateNode);
+        document.appendChild(reportNode);
+
+        return document;
+
+    }
+
+
+    protected State getPreviousState(State current, String name) {
+        if (current == null) {
+            return null;
+        }
+
+        if (current.getID().equals(name)) {
+            return current;
+        }
+        else {
+            return getPreviousState(current.getParent(), name);
+        }
+    }
+
+
+    protected void resetFutureStates(State current, String name) {
+        if (current == null) {
+            return;
+        }
+
+        if (current.getID().equals(name)) {
+            return;
+        }
+        else {
+            current.reset(identifier);
+            resetFutureStates(current.getParent(), name);
+        }
+    }
+
+
     private boolean isStateCurrentlyReachable(String stateid){
         log.debug("GNVArtifactBase.isStateCurrentlyReachable "+stateid);
         Iterator<Transition> it = this.transitions.iterator();
@@ -185,6 +275,7 @@
                 }
             }
         }
+        log.debug("State is not reachable.");
         return false;
     }
     
@@ -328,6 +419,7 @@
                 State tmpState = StateFactory.getInstance()
                         .createState(stateList.item(i));
                 if (tmpState != null) {
+                    log.debug("Initiate new state: " + tmpState.getID());
                     this.states.put(tmpState.getID(), tmpState);
                     if (this.current == null) {
                         this.current = tmpState;
@@ -359,7 +451,7 @@
             ArtifactNamespaceContext.NAMESPACE_URI,
             ArtifactNamespaceContext.NAMESPACE_PREFIX
         );
-        Element rootNode = this.createRootNode(document);
+        Element rootNode = this.createRootNode(creator, document);
         this.createHeader(creator, rootNode, document, "describe");
         this.createOutputs(creator, rootNode, document);
         this.createCurrentState(creator, rootNode, document);
@@ -384,9 +476,11 @@
         return includeUI;
     }
 
-    protected Element createRootNode(Document document) {
-        Element rootNode = xmlUtilities.createArtifactElement(document,
-                "result");
+    protected Element createRootNode(
+        XMLUtils.ElementCreator creator,
+        Document                document
+    ) {
+        Element rootNode = creator.create("result");
         document.appendChild(rootNode);
         return rootNode;
     }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java	Tue Jan 12 15:25:32 2010 +0000
@@ -6,6 +6,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.log4j.Logger;
 
@@ -47,7 +48,7 @@
     @Override
     protected void purifyResult(Collection<Result> result, String uuid) {
         log.debug("CoordinateSelectionState.purifyResult");
-        Collection<Object> describeData = this.getDescibeData(uuid);
+        List<Object> describeData = this.getDescibeData(uuid);
         if (describeData == null) {
             describeData = new ArrayList<Object>();
         }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxState.java	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/MinMaxState.java	Tue Jan 12 15:25:32 2010 +0000
@@ -5,6 +5,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.log4j.Logger;
 
@@ -41,7 +42,7 @@
     @Override
     protected void purifyResult(Collection<Result> result, String uuid) {
         log.debug("MinMaxState.purifyResult");
-        Collection<Object> describeData = this.getDescibeData(uuid);
+        List<Object> describeData = this.getDescibeData(uuid);
         if (describeData == null) {
             describeData = new ArrayList<Object>();
         }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/SingleInputState.java	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/SingleInputState.java	Tue Jan 12 15:25:32 2010 +0000
@@ -5,6 +5,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.log4j.Logger;
 
@@ -40,7 +41,7 @@
     @Override
     protected void purifyResult(Collection<Result> result, String uuid) {
         log.debug("SingleInputState.purifyResult");
-        Collection<Object> describeData = this.getDescibeData(uuid);
+        List<Object> describeData = this.getDescibeData(uuid);
         if (describeData == null) {
             describeData = new ArrayList<Object>();
         }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java	Tue Jan 12 15:25:32 2010 +0000
@@ -43,5 +43,5 @@
     public void initialize(String uuid, CallMeta callMeta)
                                                     throws StateException;
     
-
+    public void reset(String uuid);
 }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java	Tue Jan 12 12:42:53 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java	Tue Jan 12 15:25:32 2010 +0000
@@ -116,6 +116,23 @@
         return this.inputValues.values();
     }
 
+
+    public void reset(String uuid) {
+        
+        // clear input values of the current state
+        Iterator iter = inputValueNames.iterator();
+        while (iter.hasNext()) {
+            String name = (String) iter.next();
+            inputValues.remove(name);
+        }
+
+        // remove data of last state from cache
+        List describeData = getDescibeData(uuid);
+        if (describeData != null && describeData.size() != 0) {
+            describeData.remove(describeData.size()-1);
+        }
+    }
+
     /**
      * @see de.intevation.gnv.state.State#setup(org.w3c.dom.Node)
      */
@@ -344,7 +361,6 @@
             }
         }
         return null;
-
     }
 
     /**
@@ -460,7 +476,7 @@
      */
     protected void purifyResult(Collection<Result> result, String uuid) {
         log.debug("StateBase.purifyResult");
-        Collection<Object> describeData = this.getDescibeData(uuid);
+        List<Object> describeData = this.getDescibeData(uuid);
         if (describeData == null) {
             describeData = new ArrayList<Object>();
         }
@@ -518,7 +534,8 @@
      */
     public void describe(Document document, Node rootNode, CallMeta callMeta,String uuid) {
         log.debug("StateBase.describe");
-        Collection<Object> descibeData = this.getDescibeData(uuid);
+
+        List<Object> descibeData = this.getDescibeData(uuid);
         if (descibeData != null) {
             Iterator<Object> it = descibeData.iterator();
 
@@ -798,13 +815,13 @@
     /**
      * @see de.intevation.gnv.state.State#getDescibeData()
      */
-    protected Collection<Object> getDescibeData(String uuid) {
+    protected List<Object> getDescibeData(String uuid) {
         if (CacheFactory.getInstance().isInitialized()) {
             String key = uuid + DESCRIBEDATAKEY;
             log.debug("Hash for Queryelements: " + key);
             net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key);
             if (value != null) {
-                return (Collection<Object>) (value.getObjectValue());
+                return (List<Object>) (value.getObjectValue());
             }
         }
         return null;
@@ -813,7 +830,7 @@
     /**
      * @see de.intevation.gnv.state.State#getDescibeData()
      */
-    protected void setDescibeData(String uuid, Collection<Object> describeData) {
+    protected void setDescibeData(String uuid, List<Object> describeData) {
         
         if (CacheFactory.getInstance().isInitialized()) {
             String key = uuid + DESCRIBEDATAKEY;

http://dive4elements.wald.intevation.org