diff gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java @ 376:d8f3ef441bf2

merged gnv-artifacts/0.3
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:13:47 +0200
parents 2f7a28f211c7
children 3ddc22aab764
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java	Fri Sep 28 12:13:47 2012 +0200
@@ -0,0 +1,513 @@
+/**
+ *
+ */
+package de.intevation.gnv.artifacts;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import de.intevation.artifactdatabase.Config;
+import de.intevation.artifactdatabase.DefaultArtifact;
+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.state.DefaultInputData;
+import de.intevation.gnv.state.InputData;
+import de.intevation.gnv.state.InputValue;
+import de.intevation.gnv.state.OutputMode;
+import de.intevation.gnv.state.OutputState;
+import de.intevation.gnv.state.State;
+import de.intevation.gnv.state.StateFactory;
+import de.intevation.gnv.state.exception.StateException;
+import de.intevation.gnv.transition.Transition;
+import de.intevation.gnv.transition.TransitionFactory;
+import de.intevation.gnv.utils.ArtifactXMLUtilities;
+
+/**
+ * @author Tim Englich <tim.englich@intevation.de>
+ * 
+ */
+public abstract class GNVArtifactBase extends DefaultArtifact {
+    /**
+     * the logger, used to log exceptions and additonaly information
+     */
+    private static Logger log = Logger.getLogger(GNVArtifactBase.class);
+    /**
+     * The UID of this Class
+     */
+    private static final long serialVersionUID = -8907096744400741458L;
+
+    /**
+     * The Identifier for the Replacement of the Artifactname
+     */
+    public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER";
+
+    /**
+     * The XPATH to the XML-Fragment that should be used for the Configuration
+     */
+    public static final String XPATH_ARTIFACT_CONFIGURATION = "/artifact-database/artifacts/artifact[@name='"
+                                                              + XPATH_IDENTIFIER_REPLACE
+                                                              + "']";
+
+    /**
+     * The current State
+     */
+    protected State current = null;
+
+    /**
+     * The States that can be used
+     */
+    protected Map<String, State> states = null;
+    
+    /**
+     * The Transitions which can switch between the different States.
+     */
+    protected Collection<Transition> transitions = null;
+
+    /**
+     * The Name of the Artifact
+     */
+    protected String name = null;
+
+    private ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities();
+
+    /**
+     * Constructor
+     */
+    public GNVArtifactBase() {
+        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();
+        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.Ergebnisse Berechnen
+                        this.current.advance(super.identifier, context.getMeta());
+                        // 2. Ergebnisse Übergeben
+                        nextStep.putInputData(this.current.getInputData(), 
+                                              super.identifier);
+                        // 3. Umschalten auf neue Transistion
+                        this.current = nextStep;
+                        
+                        // 4. Initialisieren des nächsten Schrittes == Laden der Daten
+                        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 = "Transitionsübergang wird nicht unterstützt.";
+                    log.error(msg);
+                    result = new ArtifactXMLUtilities().createExceptionReport(
+                            msg, XMLUtils.newDocument());
+                }
+            } else {
+                String msg = "Kein State aktiviert.";
+                log.error(msg);
+                result = new ArtifactXMLUtilities().createExceptionReport(msg,
+                        XMLUtils.newDocument());
+            }
+        } catch (Exception e) {
+            log.error(e, e);
+            result = new ArtifactXMLUtilities().createExceptionReport(e
+                    .getLocalizedMessage(), XMLUtils.newDocument());
+        }
+        return result;
+    }
+    
+    
+    private boolean isStateCurrentlyReachable(String stateid){
+        log.debug("GNVArtifactBase.isStateCurrentlyReachable "+stateid);
+        Iterator<Transition> it = this.transitions.iterator();
+        String from = this.current.getID();
+        while (it.hasNext()){
+            Transition transition = it.next();
+            if (transition.getFrom().equals(from)){
+                if (transition.getTo().equals(stateid) && transition.isValid(this.current)){
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    public Document initialize (CallContext context) {
+        Document result = XMLUtils.newDocument();
+        try {
+            this.current.initialize(super.identifier, context.getMeta());
+            result = new ArtifactXMLUtilities()
+            .createSuccessReport("Initialize success",
+                    XMLUtils.newDocument());
+        } catch (StateException e) {
+            log.error(e,e);
+            result = new ArtifactXMLUtilities().createExceptionReport(e
+                    .getLocalizedMessage(), XMLUtils.newDocument());
+        }
+        return result;
+    }
+
+    protected String readStateName(Document document) {
+        String returnValue = Config.getStringXPath(document,
+                "action/target/@name");
+        return returnValue;
+    }
+
+    protected Node getConfigurationFragment(Document document) {
+        log.debug("GNVArtifactBase.getConfigurationFragment");
+        String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll(
+                XPATH_IDENTIFIER_REPLACE, this.name);
+        log.debug(xpathQuery);
+        
+        Element configurationNode = (Element)Config.getNodeXPath(document, xpathQuery);
+        
+        String link = configurationNode.getAttribute("xlink:href");
+        if (link != null ){
+            String absolutFileName = Config.replaceConfigDir(link);
+            configurationNode = (Element)new ArtifactXMLUtilities().readConfiguration(absolutFileName);
+        }
+        
+        return configurationNode;
+    }
+
+    /**
+     * @see de.intevation.artifactdatabase.DefaultArtifact#feed(org.w3c.dom.Document,
+     *      de.intevation.artifacts.CallContext)
+     */
+    @Override
+    public Document feed(Document target, CallContext context) {
+        log.debug("GNVArtifactBase.feed");
+        Document result = XMLUtils.newDocument();
+        try {
+            if (this.current != null) {
+                Collection<InputData> inputData = this.parseInputData(target,
+                                                                      "/action/data/input");
+                if (!inputData.isEmpty()){
+                    this.current.putInputData(inputData, super.identifier);
+                    result = new ArtifactXMLUtilities().createSuccessReport(
+                            "Feed success", XMLUtils.newDocument());
+                }else{
+                    String msg = "No Inputdata given. Please select at least one Entry.";
+                    log.warn(msg);
+                    result = new ArtifactXMLUtilities().createExceptionReport(msg,
+                            XMLUtils.newDocument());
+                }
+            } else {
+                String msg = "No State instantiated";
+                log.warn(msg);
+                result = new ArtifactXMLUtilities().createExceptionReport(msg,
+                        XMLUtils.newDocument());
+            }
+        } catch (StateException e) {
+            log.error(e, e);
+            result = new ArtifactXMLUtilities().createExceptionReport(e
+                    .getLocalizedMessage(), XMLUtils.newDocument());
+        }
+        return result;
+    }
+
+    /**
+     * @see de.intevation.artifactdatabase.DefaultArtifact#setup(java.lang.String,
+     *      java.lang.Object)
+     */
+    @Override
+    public void setup(String identifier, ArtifactFactory factory, Object context) {
+        log.debug("GNVArtifactBase.setup");
+        super.setup(identifier, factory, context);
+
+        Object localContext = context;
+        if (context instanceof CallContext) {
+            localContext = ((CallContext) context).globalContext();
+
+        }
+
+        if (localContext instanceof GNVArtifactContext) {
+            GNVArtifactContext gnvContext = (GNVArtifactContext) localContext;
+            Document doc = gnvContext.getConfig();
+            Node artifactNode = this.getConfigurationFragment(doc);
+                        
+            NodeList stateList = Config.getNodeSetXPath(artifactNode,
+                    "states/state");
+            this.states = new HashMap<String, State>(stateList
+                    .getLength());
+            for (int i = 0; i < stateList.getLength(); i++) {
+                State tmpState = StateFactory.getInstance()
+                        .createState(stateList.item(i));
+                if (tmpState != null) {
+                    this.states.put(tmpState.getID(), tmpState);
+                    if (this.current == null) {
+                        this.current = tmpState;
+                    }
+                }
+            }
+            
+            NodeList transitionList = Config.getNodeSetXPath(artifactNode,
+            "states/transition");
+            this.transitions = new ArrayList<Transition>(transitionList.getLength());
+            for (int i = 0; i < transitionList.getLength(); i++) {
+                Transition tmpTransition = TransitionFactory.getInstance()
+                        .createTransition(transitionList.item(i));
+                if (tmpTransition != null) {
+                    this.transitions.add(tmpTransition);
+                }
+            }
+
+        }
+    }
+    
+    
+
+    protected Document createDescibeOutput(CallMeta callMeta, String uuid, boolean incudeUI) {
+        log.debug("GNVArtifactBase.createDescibeOutput");
+        Document document = XMLUtils.newDocument();
+        Element rootNode = this.createRootNode(document);
+        this.createHeader(rootNode, document, "describe");
+        this.createOutputs(rootNode, document);
+        this.createCurrentState(rootNode, document);
+        this.createReachableStates(rootNode, document);
+        this.createModel(rootNode, document);
+        if (incudeUI){
+            this.createUserInterface(rootNode, document, callMeta, uuid);
+        }
+        return document;
+    }
+    
+    protected boolean getIncludeUIFromDocument(Document document){
+        String value = Config.getStringXPath(document, "action/include-ui");
+        boolean includeUI = false;
+        if (value != null){
+            includeUI = Boolean.parseBoolean(value);
+        }
+        return includeUI;
+    }
+
+    protected Element createRootNode(Document document) {
+        Element rootNode = xmlUtilities.createArtifactElement(document,
+                "result");
+        document.appendChild(rootNode);
+        return rootNode;
+    }
+
+    protected void createHeader(Element parent, Document document,
+                                String documentType) {
+        Element typeNode = xmlUtilities.createArtifactElement(document, "type");
+        typeNode.setAttribute("name", documentType);
+        parent.appendChild(typeNode);
+
+        Element uuidNode = xmlUtilities.createArtifactElement(document, "uuid");
+        uuidNode.setAttribute("value", super.identifier);
+        parent.appendChild(uuidNode);
+
+        Element hashNode = xmlUtilities.createArtifactElement(document, "hash");
+        hashNode.setAttribute("value", this.hash());
+        parent.appendChild(hashNode);
+    }
+
+    protected void createReachableStates(Element parent, Document document) {
+        Element stateNode = xmlUtilities.createArtifactElement(document,
+                "reachable-states");
+        if (this.current != null) {
+            Iterator<Transition> transitions = this.transitions.iterator();
+            while (transitions.hasNext()) {
+                Transition tmpTransition = transitions.next();
+                if (tmpTransition.getFrom().equals(current.getID()) && 
+                    tmpTransition.isValid(this.current)){
+                    Element currentNode = xmlUtilities.createArtifactElement(
+                            document, "state");
+                    currentNode.setAttribute("name", tmpTransition.getTo());
+                    log.debug("Reachable State: " + tmpTransition.getTo());
+                    currentNode.setAttribute("description", 
+                                             this.states.get(tmpTransition.getTo())
+                                                             .getDescription());
+                    stateNode.appendChild(currentNode);
+                }
+            }
+        }
+        parent.appendChild(stateNode);
+    }
+
+    protected void createCurrentState(Element parent, Document document) {
+        Element stateNode = xmlUtilities.createArtifactElement(document,
+                "state");
+        stateNode.setAttribute("name", this.current.getID());
+        stateNode.setAttribute("description", this.current.getDescription());
+        parent.appendChild(stateNode);
+    }
+
+    protected void createModel(Element parent, Document document) {
+        Element modelNode = xmlUtilities.createArtifactElement(document,
+                "model");
+        if (this.current != null) {
+            Collection<InputValue> inputValues = this.current
+                    .getRequiredInputValues();
+            if (inputValues != null) {
+                Iterator<InputValue> it = inputValues.iterator();
+                while (it.hasNext()) {
+                    InputValue inputValue = it.next();
+                    Element inputNode = xmlUtilities.createArtifactElement(
+                            document, "input");
+                    inputNode.setAttribute("name", inputValue.getName());
+                    inputNode.setAttribute("type", inputValue.getType());
+                    modelNode.appendChild(inputNode);
+                }
+            }
+        }
+        parent.appendChild(modelNode);
+    }
+
+    protected void createUserInterface(Element parent, Document document,
+                                       CallMeta callMeta, String uuid) {
+        Element uiNode = xmlUtilities.createArtifactElement(document, "ui");
+
+        if (this.current != null) {
+            this.current.describe(document, uiNode, callMeta, uuid);
+        }
+
+        parent.appendChild(uiNode);
+    }
+
+    protected void createOutputs(Element parent, Document document) {
+        log.debug("GNVArtifactBase.createOutputs");
+        Element outputsNode = xmlUtilities.createArtifactElement(document,
+                "outputs");
+        if (this.current instanceof OutputState) {
+            Collection<OutputMode> outputModes = ((OutputState) this.current)
+                    .getOutputModes();
+            if (outputModes != null) {
+                Iterator<OutputMode> it = outputModes.iterator();
+                while (it.hasNext()) {
+                    OutputMode outputMode = it.next();
+                    log.debug("Write Outputnode for " + outputMode.toString());
+                    Element outputModeNode = xmlUtilities
+                            .createArtifactElement(document, "output");
+                    outputModeNode.setAttribute("name", outputMode.getName());
+                    outputModeNode.setAttribute("description", outputMode
+                            .getDescription());
+                    outputModeNode.setAttribute("mime-type", outputMode
+                            .getMimeType());
+                    outputsNode.appendChild(outputModeNode);
+
+                    Collection<InputValue> inputParameters = outputMode
+                            .getInputParameters();
+                    if (inputParameters != null) {
+                        Element inputParametersNode = xmlUtilities
+                                .createArtifactElement(document, "parameter");
+                        outputModeNode.appendChild(inputParametersNode);
+                        Iterator<InputValue> it2 = inputParameters.iterator();
+                        while (it2.hasNext()) {
+                            InputValue inputValue = it2.next();
+                            Element inputParameterNode = xmlUtilities
+                                    .createArtifactElement(document,
+                                            "parameter");
+                            inputParametersNode.appendChild(inputParameterNode);
+                            inputParameterNode.setAttribute("name", inputValue
+                                    .getName());
+                            inputParameterNode.setAttribute("type", inputValue
+                                    .getType());
+                            inputParameterNode.setAttribute("value", inputValue
+                                    .getDefaultValue());
+                        }
+                    }
+                }
+            } else {
+                log.warn("No Outputmodes given.");
+            }
+        }
+        parent.appendChild(outputsNode);
+    }
+
+    protected Collection<InputData> parseInputData(Document document,
+                                                   String xPath) {
+        log.debug("GNVArtifactBase.parseInputData");
+        HashMap<String, InputData> returnValue = null;
+
+        log.debug(new ArtifactXMLUtilities().writeDocument2String(document));
+
+        NodeList inputElemets = (NodeList) XMLUtils.xpath(document, xPath,
+                XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);// Config.getNodeSetXPath(document,
+                                                                           // "");
+        if (inputElemets != null) {
+            returnValue = new HashMap<String, InputData>(inputElemets
+                    .getLength());
+            for (int i = 0; i < inputElemets.getLength(); i++) {
+                Element inputDataNode = (Element)inputElemets.item(i);
+                String name = inputDataNode.getAttribute("name");
+                String value = inputDataNode.getAttribute("value");
+
+                if (returnValue.containsKey(name)) {
+                    InputData inputData = returnValue.get(name);
+                    inputData.concartValue(value);
+                    log.debug(inputData.toString());
+                    returnValue.put(name, inputData);
+                } else {
+                    InputData inputData = new DefaultInputData(name, value);
+
+                    returnValue.put(name, inputData);
+                }
+            }
+        }
+        return returnValue.values();
+    }
+
+    /**
+     * @see de.intevation.artifactdatabase.DefaultArtifact#out(org.w3c.dom.Document,
+     *      java.io.OutputStream, de.intevation.artifacts.CallContext)
+     */
+    @Override
+    public void out(Document format, OutputStream outputStream,
+                    CallContext context) throws IOException {
+        log.debug("TGNVArtifactBase.out");
+        try {
+
+            if (current != null && current instanceof OutputState) {
+                ((OutputState) current)
+                        .out(format, this.parseInputData(
+                                format, "/action/out/params/input"),
+                                outputStream, super.identifier, context);
+            }
+        } catch (StateException e) {
+            log.error(e, e);
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    protected String readOutputType(Document document) {
+        String value = Config.getStringXPath(document, "action/out/@name");
+        return value;
+    }
+}

http://dive4elements.wald.intevation.org