changeset 2564:3f038d54bc87

FixingsOverviewService: Made the filter mechanisms available via the incoming XML document. flys-artifacts/trunk@4090 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 Feb 2012 19:13:19 +0000
parents 59c920e73d8a
children 72f77b2210c2
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/FixingsOverviewService.java
diffstat 3 files changed, 191 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Mon Feb 20 16:41:45 2012 +0000
+++ b/flys-artifacts/ChangeLog	Mon Feb 20 19:13:19 2012 +0000
@@ -1,3 +1,28 @@
+2012-02-20  Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/services/FixingsOverviewService.java:
+	  Made the filter mechanisms available via the incoming XML document.
+
+	  1 - range: Simply add a <range from="..." to="..."/> element next to the
+	      <river> element. Optional. Defaults to full extent.
+
+	  2 - filters: Add a <filter> element next to the <river> element.
+	      Optional. Defaults to accepting all.
+	      The <filter> element can contain the following elements:
+
+	        <column cid="..."/>: Creates an IdFilter.
+	        <date when="..."/>: Creates a DateFilter.
+	        <date-range from="..." to="..."/>: Creates a DateRangeFilter.
+	        <sector-range from="..." to="..."/>: Create a SectorRangeFilter.
+	        <not>...</not>: Creates a NotFilter. The nested element is negated.
+	        <and>...</and>: Create an AndFilter: The nested elements are 'and'ed.
+	        <or>...</or>: Create an OrFilter: The nested elements are 'or'ed.
+
+	  These filters need testing!
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
+	  Made date format a public constant.
+
 2012-02-20  Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Mon Feb 20 16:41:45 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Mon Feb 20 19:13:19 2012 +0000
@@ -30,6 +30,8 @@
     public static final double EPSILON  = 1e-5;
     public static final double EPSILON2 = 1e-1;
 
+    public static final String DATE_FORMAT = "dd.MM.yyyy HH:mm";
+
     public static final String SQL_RIVER_ID =
         "SELECT" +
         "    id AS river_id," +
@@ -884,7 +886,7 @@
 
         fixingsElement.appendChild(riverElement);
 
-        SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm");
+        SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
 
         Element esE = document.createElement("events");
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/FixingsOverviewService.java	Mon Feb 20 16:41:45 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/FixingsOverviewService.java	Mon Feb 20 19:13:19 2012 +0000
@@ -5,13 +5,32 @@
 
 import de.intevation.artifacts.common.utils.XMLUtils;
 
+import de.intevation.flys.artifacts.model.FixingsOverview.Fixing.Filter;
+
+import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.DateFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.NotFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.OrFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.Range;
+import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
+
 import de.intevation.flys.artifacts.model.FixingsOverview;
 import de.intevation.flys.artifacts.model.FixingsOverviewFactory;
 
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
 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;
 
 public class FixingsOverviewService
@@ -42,7 +61,9 @@
         FixingsOverview overview = FixingsOverviewFactory.getOverview(river);
 
         if (overview != null) {
-            overview.generateOverview(document);
+            Range  range  = getRange(data);
+            Filter filter = getFilter(data);
+            overview.generateOverview(document, range, filter);
         }
         else {
             log.warn("No overview for river '" + river + "' available.");
@@ -50,5 +71,146 @@
 
         return document;
     }
+
+    public static Range getRange(Document data) {
+
+        NodeList ranges = data.getElementsByTagName("range");
+
+        if (ranges.getLength() < 1) {
+            return FixingsOverview.FULL_EXTENT;
+        }
+
+        Element range = (Element)ranges.item(0);
+
+        String from = range.getAttribute("from").trim();
+        String to   = range.getAttribute("to"  ).trim();
+
+        double start = -Double.MAX_VALUE;
+        double end   =  Double.MAX_VALUE;
+
+        if (from.length() > 0) {
+            try {
+                start = Double.parseDouble(from);
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("Invalid from value: " + from);
+            }
+        }
+
+        if (to.length() > 0) {
+            try {
+                end = Double.parseDouble(to);
+            }
+            catch (NumberFormatException nfe) {
+                log.warn("Invalid to value: " + to);
+            }
+        }
+
+        if (start > end) {
+            double t = start;
+            start = end;
+            end = t;
+        }
+
+        return new Range(start, end);
+    }
+
+    public static Filter getFilter(Document data) {
+
+        NodeList filters = data.getElementsByTagName("filter");
+
+        return filters.getLength() < 1
+            ? FixingsOverview.ACCEPT
+            : buildFilter((Element)filters.item(0));
+    }
+
+    public static Filter buildFilter(Element root) {
+        List<Filter> filters = buildRecursiveFilter(root);
+        switch (filters.size()) {
+            case  0: return FixingsOverview.ACCEPT;
+            case  1: return filters.get(0);
+            default: return new AndFilter(filters);
+        }
+    }
+
+    private static final Date parseDate(String text) {
+        SimpleDateFormat format =
+            new SimpleDateFormat(FixingsOverview.DATE_FORMAT);
+        return format.parse(text, new ParsePosition(0));
+    }
+
+    public static List<Filter> buildRecursiveFilter(Element root) {
+        List<Filter> filters = new ArrayList<Filter>();
+
+        NodeList children = root.getChildNodes();
+
+        for (int i = 0, N = children.getLength(); i < N; ++i) {
+            Node child = children.item(i);
+            if (child.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+
+            Element element = (Element)child;
+            String name = element.getLocalName();
+
+            if ("and".equals(name)) {
+                filters.add(new AndFilter(buildRecursiveFilter(element)));
+            }
+            else if ("or".equals(name)) {
+                filters.add(new OrFilter(buildRecursiveFilter(element)));
+            }
+            else if ("not".equals(name)) {
+                List<Filter> childrenFilters = buildRecursiveFilter(element);
+                if (!childrenFilters.isEmpty()) {
+                    filters.add(new NotFilter(childrenFilters.get(0)));
+                }
+            }
+            else if ("column".equals(name)) {
+                String cid = element.getAttribute("cid").trim();
+                if (cid.length() > 0) {
+                    try {
+                        filters.add(new IdFilter(Integer.parseInt(cid)));
+                    }
+                    catch (NumberFormatException nfe) {
+                    }
+                }
+            }
+            else if ("date".equals(name)) {
+                String when = element.getAttribute("when").trim();
+                if (when.length() > 0) {
+                    Date date = parseDate(when);
+                    if (date != null) {
+                        filters.add(new DateFilter(date));
+                    }
+                }
+            }
+            else if ("date-range".equals(name)) {
+                String from = element.getAttribute("from").trim();
+                String to   = element.getAttribute("to"  ).trim();
+                if (from.length() > 0 && to.length() > 0) {
+                    Date start = parseDate(from);
+                    Date end   = parseDate(to);
+                    if (start != null && end != null) {
+                        filters.add(new DateRangeFilter(start, end));
+                    }
+                }
+            }
+            else if ("sector-range".equals(name)) {
+                String from = element.getAttribute("from").trim();
+                String to   = element.getAttribute("to"  ).trim();
+                if (from.length() > 0 && to.length() > 0) {
+                    try {
+                        filters.add(new SectorRangeFilter(
+                            Integer.parseInt(from),
+                            Integer.parseInt(to)));
+                    }
+                    catch (NumberFormatException nfe) {
+                    }
+                }
+            }
+        }
+
+        return filters;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org