diff gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java @ 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 70df44021a9f
children a6a33ef35809
line wrap: on
line diff
--- 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;
     }

http://dive4elements.wald.intevation.org