changeset 937:9e813e9137a5

Added a monitor that creates new artifacts for default themes in charts and maps. flys-artifacts/trunk@2329 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 14 Jul 2011 11:27:01 +0000
parents 759808931a2e
children bd3683453928
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/CollectionMonitor.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/OutputState.java
diffstat 6 files changed, 435 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Wed Jul 13 17:33:15 2011 +0000
+++ b/flys-artifacts/ChangeLog	Thu Jul 14 11:27:01 2011 +0000
@@ -1,3 +1,30 @@
+2011-07-14  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java,
+	  src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java: Moved code
+	  to create the output modes based on the given facets to FLYSArtifact. In
+	  addition, FLYSArtifact got a new method that returns a specific input
+	  value as string.
+
+	* src/main/java/de/intevation/flys/artifacts/CollectionMonitor.java: New.
+	  This hook monitors the "post-feed" and "post-advance". If the monitored
+	  Artifact's state has configured recommended artifacts, this hook will
+	  create new Artifacts.
+
+	  TODO: We have to add the UUIDs of the new Artifacts to the DESCRIBE
+	  document of the artifact to let the client know, that there are new
+	  recommended Artifacts.
+
+	* src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java: New.
+	  This Artifact is the base class for Artifacts, that represent static
+	  data. E.g. this could be a decoration theme in a chart or a background
+	  layer in the map.
+
+	* src/main/java/de/intevation/flys/artifacts/states/OutputState.java: New.
+	  This state might be used as base class for states, that doesn't require
+	  any user input, but only provide static Facets added by a computeFeed()
+	  operation. So, subclasses need to implement computeFeed() only.
+
 2011-07-13  Sascha L. Teichmann <sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CollectionMonitor.java	Thu Jul 14 11:27:01 2011 +0000
@@ -0,0 +1,239 @@
+package de.intevation.flys.artifacts;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+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.artifacts.Artifact;
+import de.intevation.artifacts.ArtifactDatabase;
+import de.intevation.artifacts.ArtifactDatabaseException;
+import de.intevation.artifacts.ArtifactNamespaceContext;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.Hook;
+
+import de.intevation.artifacts.common.utils.ClientProtocolUtils;
+import de.intevation.artifacts.common.utils.Config;
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+
+public class CollectionMonitor implements Hook {
+
+    public static final String XPATH_UUID = "/art:result/art:uuid/@art:value";
+    public static final String XPATH_HASH = "/art:result/art:hash/@art:value";
+
+
+    public class LoadArtifact {
+        public String factory;
+        public List<String> parameters;
+
+        public LoadArtifact(String factory) {
+            this.factory    = factory;
+            this.parameters = new ArrayList<String>();
+        }
+
+        public void addParameter(String parameter) {
+            parameters.add(parameter);
+        }
+    } // end of class LoadArtifact
+
+
+    public static final String XPATH_STATES = "output-defaults/state";
+
+
+    protected Map<String, List<LoadArtifact>> states;
+
+
+    private static final Logger logger =
+        Logger.getLogger(CollectionMonitor.class);
+
+
+    @Override
+    public void setup(Node cfg) {
+        Element config = (Element) cfg;
+        String  xlink  = config.getAttribute("xlink:href");
+        xlink          = Config.replaceConfigDir(xlink);
+
+        File file = new File(xlink);
+
+        if (file == null || !file.exists()) {
+            logger.error("The config file '" + xlink + "' does not exist.");
+            return;
+        }
+
+        Document outputDefaults = XMLUtils.parseDocument(file);
+
+        NodeList states = (NodeList) XMLUtils.xpath(
+            outputDefaults,
+            XPATH_STATES,
+            XPathConstants.NODESET);
+
+        int len = states != null ? states.getLength() : 0;
+
+        this.states = new HashMap<String, List<LoadArtifact>>(len);
+
+        for (int i = 0; i < len; i++) {
+            Element state = (Element) states.item(i);
+
+            String             stateId   = state.getAttribute("id");
+            List<LoadArtifact> artifacts = parseLoadArtifacts(state);
+
+            if (artifacts != null) {
+                this.states.put(stateId, artifacts);
+            }
+        }
+    }
+
+
+    protected List<LoadArtifact> parseLoadArtifacts(Element state) {
+        NodeList artifacts = (NodeList) XMLUtils.xpath(
+            state, "artifact", XPathConstants.NODESET);
+
+        int len = artifacts != null ? artifacts.getLength() : 0;
+
+        List<LoadArtifact> loadArtifacts = new ArrayList<LoadArtifact>(len);
+
+        for (int i = 0; i < len; i++) {
+            LoadArtifact la = parseLoadArtifact((Element) artifacts.item(i));
+
+            if (la != null) {
+                loadArtifacts.add(la);
+            }
+        }
+
+        return loadArtifacts;
+    }
+
+
+    protected LoadArtifact parseLoadArtifact(Element art) {
+        String factory = art.getAttribute("factory");
+
+        LoadArtifact artifact = new LoadArtifact(factory);
+
+        NodeList parameters = (NodeList) XMLUtils.xpath(
+            art, "parameter", XPathConstants.NODESET);
+
+        int len = parameters != null ? parameters.getLength() : 0;
+
+        for (int i = 0; i < len; i++) {
+            Element parameter = (Element) parameters.item(i);
+            artifact.addParameter(parameter.getAttribute("name"));
+        }
+
+        return artifact;
+    }
+
+
+    @Override
+    public void execute(Artifact artifact, CallContext context) {
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        String stateId = flys.getCurrentStateId();
+
+        List<LoadArtifact> loadArtifacts = states.get(stateId);
+
+        if (loadArtifacts == null || loadArtifacts.isEmpty()) {
+            return;
+        }
+
+        ArtifactDatabase db = context.getDatabase();
+        List<String> uuids  = new ArrayList<String>();
+
+        for (LoadArtifact rawArtifact: loadArtifacts) {
+            String[] art = createArtifact(db, context, rawArtifact);
+
+            if (art != null && art.length >= 2) {
+                Document feed   = prepareFeed(
+                    artifact, rawArtifact, art[0], art[1]);
+
+                boolean success = initializeArtifact(db, context, feed, art[0]);
+
+                if (success) {
+                    uuids.add(art[0]);
+                }
+            }
+        }
+
+        // TODO ADD UUIDS TO DESCRIBE
+    }
+
+
+    protected String[] createArtifact(
+        ArtifactDatabase db,
+        CallContext      cc,
+        LoadArtifact     raw)
+    {
+        Document create = ClientProtocolUtils.newCreateDocument(raw.factory);
+
+        try {
+            Document result = db.createArtifactWithFactory(
+                raw.factory, cc.getMeta(), create);
+
+            String uuid = XMLUtils.xpathString(
+                result, XPATH_UUID, ArtifactNamespaceContext.INSTANCE);
+            String hash = XMLUtils.xpathString(
+                result, XPATH_HASH, ArtifactNamespaceContext.INSTANCE);
+
+            return new String[] {uuid, hash};
+        }
+        catch (ArtifactDatabaseException ade) {
+            logger.error(ade, ade);
+        }
+
+        return null;
+    }
+
+
+    protected Document prepareFeed(
+        Artifact     artifact,
+        LoadArtifact rawArtifact,
+        String       uuid,
+        String       hash)
+    {
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        String[][] data = new String[rawArtifact.parameters.size()][2];
+
+        for (int i = 0, len = rawArtifact.parameters.size(); i < len; i++) {
+            String param = rawArtifact.parameters.get(i);
+            String value = flys.getDataAsString(param);
+
+            if (value != null) {
+                data[i][0] = param;
+                data[i][1] = value;
+            }
+        }
+
+        return ClientProtocolUtils.newFeedDocument(uuid, hash, data);
+    }
+
+
+    protected boolean initializeArtifact(
+        ArtifactDatabase db,
+        CallContext      cc,
+        Document         feed,
+        String           uuid)
+    {
+        try {
+            db.feed(uuid, feed, cc.getMeta());
+
+            return true;
+        }
+        catch (ArtifactDatabaseException adbe) {
+            logger.error(adbe, adbe);
+        }
+
+        return false;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java	Wed Jul 13 17:33:15 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java	Thu Jul 14 11:27:01 2011 +0000
@@ -5,6 +5,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.TreeMap;
 import java.util.List;
 import java.util.Map;
@@ -31,7 +32,9 @@
 import de.intevation.artifactdatabase.DefaultArtifact;
 import de.intevation.artifactdatabase.data.DefaultStateData;
 import de.intevation.artifactdatabase.data.StateData;
+import de.intevation.artifactdatabase.state.DefaultOutput;
 import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.Output;
 import de.intevation.artifactdatabase.state.State;
 import de.intevation.artifactdatabase.state.StateEngine;
 import de.intevation.artifactdatabase.transition.TransitionEngine;
@@ -364,6 +367,12 @@
     }
 
 
+    public String getDataAsString(String name) {
+        StateData data = getData(name);
+        return data != null ? (String) data.getValue() : null;
+    }
+
+
     public Facet getNativeFacet(Facet facet) {
         String name  = facet.getName();
         int    index = facet.getIndex();
@@ -1073,6 +1082,48 @@
     }
 
 
+    protected List<Output> generateOutputs(List<Output> list, List<Facet> fs) {
+        List<Output> generated = new ArrayList<Output>();
+
+        boolean debug = logger.isDebugEnabled();
+
+        for (Output out: list) {
+            Output o = new DefaultOutput(
+                out.getName(),
+                out.getDescription(),
+                out.getMimeType(),
+                out.getType());
+
+            Set<String> outTypes = new HashSet<String>();
+
+            for (Facet f: out.getFacets()) {
+                if (outTypes.add(f.getName()) && debug) {
+                    logger.debug("configured facet " + f);
+                }
+            }
+
+            boolean facetAdded = false;
+            for (Facet f: fs) {
+                String type = f.getName();
+
+                if (outTypes.contains(type)) {
+                    if (debug) {
+                        logger.debug("Add facet " + f);
+                    }
+                    facetAdded = true;
+                    o.addFacet(f);
+                }
+            }
+
+            if (facetAdded) {
+                generated.add(o);
+            }
+        }
+
+        return generated;
+    }
+
+
     /**
      * Dispatches the computation request to compute(CallContext context, String
      * hash) with the current hash value of the artifact which is provided by
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticFLYSArtifact.java	Thu Jul 14 11:27:01 2011 +0000
@@ -0,0 +1,75 @@
+package de.intevation.flys.artifacts;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import de.intevation.artifacts.ArtifactNamespaceContext;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.artifactdatabase.ProtocolUtils;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifactdatabase.state.Output;
+import de.intevation.artifactdatabase.state.State;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
+
+
+public abstract class StaticFLYSArtifact extends FLYSArtifact {
+
+    private static final Logger logger =
+        Logger.getLogger(StaticFLYSArtifact.class);
+
+
+    @Override
+    public Document describe(Document data, CallContext cc) {
+        logger.debug("Describe artifact: " + identifier());
+
+        Document desc = XMLUtils.newDocument();
+
+        ElementCreator creator = new ElementCreator(
+            desc,
+            ArtifactNamespaceContext.NAMESPACE_URI,
+            ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+        Element root = ProtocolUtils.createRootNode(creator);
+        desc.appendChild(root);
+
+        ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash());
+        root.appendChild(createOutputModes(cc, creator));
+
+        return desc;
+    }
+
+
+    protected Element createOutputModes(CallContext cc, ElementCreator creator){
+        Element outs = ProtocolUtils.createArtNode(
+            creator, "outputmodes", null, null);
+
+        State state       = getCurrentState(cc);
+        List<Output> list = state.getOutputs();
+
+        if (list != null && list.size() > 0) {
+            List<Facet>  fs = facets.get(state.getID());
+            if (fs != null && fs.size() > 0) {
+                List<Output> generated = generateOutputs(list, fs);
+
+                logger.debug("Found " + fs.size() + " current facets.");
+                if (!generated.isEmpty()) {
+                    ProtocolUtils.appendOutputModes(
+                        creator, outs, generated);
+                }
+            }
+            else {
+                logger.debug("No facets found for the current state.");
+            }
+        }
+
+        return outs;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Wed Jul 13 17:33:15 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Thu Jul 14 11:27:01 2011 +0000
@@ -2,10 +2,8 @@
 
 import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -17,7 +15,6 @@
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.artifactdatabase.ProtocolUtils;
-import de.intevation.artifactdatabase.state.DefaultOutput;
 import de.intevation.artifactdatabase.state.Facet;
 import de.intevation.artifactdatabase.state.Output;
 import de.intevation.artifactdatabase.state.State;
@@ -231,48 +228,6 @@
     }
 
 
-    protected List<Output> generateOutputs(List<Output> list, List<Facet> fs) {
-        List<Output> generated = new ArrayList<Output>();
-
-        boolean debug = logger.isDebugEnabled();
-
-        for (Output out: list) {
-            Output o = new DefaultOutput(
-                out.getName(),
-                out.getDescription(),
-                out.getMimeType(),
-                out.getType());
-
-            Set<String> outTypes = new HashSet<String>();
-
-            for (Facet f: out.getFacets()) {
-                if (outTypes.add(f.getName()) && debug) {
-                    logger.debug("configured facet " + f);
-                }
-            }
-
-            boolean facetAdded = false;
-            for (Facet f: fs) {
-                String type = f.getName();
-
-                if (outTypes.contains(type)) {
-                    if (debug) {
-                        logger.debug("Add facet " + f);
-                    }
-                    facetAdded = true;
-                    o.addFacet(f);
-                }
-            }
-
-            if (facetAdded) {
-                generated.add(o);
-            }
-        }
-
-        return generated;
-    }
-
-
     /**
      * This method appends the static data - that has already been inserted by
      * the user - to the static node of the DESCRIBE document.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/OutputState.java	Thu Jul 14 11:27:01 2011 +0000
@@ -0,0 +1,43 @@
+package de.intevation.flys.artifacts.states;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.model.FacetTypes;
+
+
+public class OutputState extends DefaultState implements FacetTypes {
+
+    private static final Logger logger = Logger.getLogger(OutputState.class);
+
+
+    @Override
+    public Element describeStatic(
+        Artifact    artifact,
+        Document    document,
+        Node        root,
+        CallContext context,
+        String      uuid)
+    {
+        return null;
+    }
+
+
+    @Override
+    public Element describe(
+        Artifact    artifact,
+        Document    document,
+        Node        root,
+        CallContext context,
+        String      uuid)
+    {
+        return null;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org