teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5863: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5863: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.model; sascha@2608: teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.AndFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.DateFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.DateRangeFilter; sascha@2608: teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.Fixing.Filter; teichmann@5831: teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.IdFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.IdsFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.KmFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.NotFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.OrFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.SectorFilter; teichmann@5831: import org.dive4elements.river.artifacts.model.FixingsOverview.SectorRangeFilter; sascha@2608: sascha@2608: import java.text.ParsePosition; sascha@2608: import java.text.SimpleDateFormat; sascha@2608: sascha@2608: import java.util.ArrayList; sascha@2608: import java.util.Date; sascha@2608: import java.util.List; sascha@2608: sascha@2608: import org.apache.log4j.Logger; sascha@2608: sascha@2608: import org.w3c.dom.Document; sascha@2608: import org.w3c.dom.Element; sascha@2608: import org.w3c.dom.Node; sascha@2608: import org.w3c.dom.NodeList; sascha@2608: sascha@2608: public class FixingsFilterBuilder sascha@2608: { sascha@2608: private static Logger log = Logger.getLogger(FixingsFilterBuilder.class); sascha@2608: sascha@2608: protected Filter filter; sascha@2608: protected Range range; sascha@2608: sascha@2608: protected Document document; sascha@2608: sascha@2608: public FixingsFilterBuilder() { sascha@2608: } sascha@2608: sascha@2608: public FixingsFilterBuilder(Document document) { sascha@2608: this.document = document; sascha@2608: } sascha@2608: sascha@2608: public Filter getFilter() { sascha@2608: if (filter == null) { sascha@2608: filter = buildFilter(); sascha@2608: } sascha@2608: return filter; sascha@2608: } sascha@2608: sascha@2608: public Range getRange() { sascha@2613: if (range == null) { sascha@2608: range = buildRange(); sascha@2608: } sascha@2608: return range; sascha@2608: } sascha@2608: sascha@2608: public Document getDocument() { sascha@2608: return document; sascha@2608: } sascha@2608: sascha@2608: protected Range buildRange() { sascha@2608: sascha@2608: NodeList ranges = document.getElementsByTagName("range"); sascha@2608: sascha@2608: if (ranges.getLength() < 1) { sascha@2608: return FixingsOverview.FULL_EXTENT; sascha@2608: } sascha@2608: sascha@2608: Element range = (Element)ranges.item(0); sascha@2608: sascha@2608: String from = range.getAttribute("from").trim(); sascha@2608: String to = range.getAttribute("to" ).trim(); sascha@2608: sascha@2608: double start = -Double.MAX_VALUE; sascha@2608: double end = Double.MAX_VALUE; sascha@2608: sascha@2608: if (from.length() > 0) { sascha@2608: try { sascha@2608: start = Double.parseDouble(from); sascha@2608: } sascha@2608: catch (NumberFormatException nfe) { sascha@2608: log.warn("Invalid from value: " + from); sascha@2608: } sascha@2608: } sascha@2608: sascha@2608: if (to.length() > 0) { sascha@2608: try { sascha@2608: end = Double.parseDouble(to); sascha@2608: } sascha@2608: catch (NumberFormatException nfe) { sascha@2608: log.warn("Invalid to value: " + to); sascha@2608: } sascha@2608: } sascha@2608: sascha@2608: if (start > end) { sascha@2608: double t = start; sascha@2608: start = end; sascha@2608: end = t; sascha@2608: } sascha@2608: sascha@2608: return new Range(start, end); sascha@2608: } sascha@2608: sascha@2608: protected Filter buildFilter() { sascha@2608: NodeList filters = document.getElementsByTagName("filter"); sascha@2608: sascha@2608: return filters.getLength() < 1 sascha@2608: ? FixingsOverview.ACCEPT sascha@2608: : buildFilter((Element)filters.item(0)); sascha@2608: } sascha@2608: sascha@2608: protected static Filter buildFilter(Element root) { sascha@2608: List filters = buildRecursiveFilter(root); sascha@2608: switch (filters.size()) { sascha@2608: case 0: return FixingsOverview.ACCEPT; sascha@2608: case 1: return filters.get(0); sascha@2608: default: return new AndFilter(filters); sascha@2608: } sascha@2608: } sascha@2608: sascha@2608: protected static final Date parseDate(String text) { sascha@2608: SimpleDateFormat format = sascha@2608: new SimpleDateFormat(FixingsOverview.DATE_FORMAT); sascha@2608: return format.parse(text, new ParsePosition(0)); sascha@2608: } sascha@2608: sascha@2608: protected static List buildRecursiveFilter(Element root) { sascha@2608: List filters = new ArrayList(); sascha@2608: sascha@2608: NodeList children = root.getChildNodes(); sascha@2608: sascha@2608: for (int i = 0, N = children.getLength(); i < N; ++i) { sascha@2608: Node child = children.item(i); sascha@2608: if (child.getNodeType() != Node.ELEMENT_NODE) { sascha@2608: continue; sascha@2608: } sascha@2608: sascha@2608: Element element = (Element)child; sascha@2608: String name = element.getLocalName(); sascha@2608: sascha@2608: if ("and".equals(name)) { sascha@2608: filters.add(new AndFilter(buildRecursiveFilter(element))); sascha@2608: } sascha@2608: else if ("or".equals(name)) { sascha@2608: filters.add(new OrFilter(buildRecursiveFilter(element))); sascha@2608: } sascha@2608: else if ("not".equals(name)) { sascha@2608: List childrenFilters = buildRecursiveFilter(element); sascha@2608: if (!childrenFilters.isEmpty()) { sascha@2608: filters.add(new NotFilter(childrenFilters.get(0))); sascha@2608: } sascha@2608: } sascha@2608: else if ("column".equals(name)) { sascha@2608: String cid = element.getAttribute("cid").trim(); sascha@2608: if (cid.length() > 0) { sascha@2608: try { sascha@2608: filters.add(new IdFilter(Integer.parseInt(cid))); sascha@2608: } sascha@2608: catch (NumberFormatException nfe) { sascha@2608: log.warn(nfe); sascha@2608: } sascha@2608: } sascha@2608: } sascha@3121: else if ("columns".equals(name)) { sascha@3121: String cidsS = element.getAttribute("cids").trim(); sascha@3121: String [] parts = cidsS.split("\\s+"); sascha@3121: List ids = new ArrayList(); sascha@3121: for (String part: parts) { sascha@3121: try { sascha@3121: ids.add(Integer.valueOf(part)); sascha@3121: } sascha@3121: catch (NumberFormatException nfe) { sascha@3121: log.warn(nfe); sascha@3121: } sascha@3121: } sascha@3121: int [] cids = new int[ids.size()]; sascha@3121: for (int j = 0; j < cids.length; ++j) { sascha@3136: cids[j] = ids.get(j); sascha@3121: } sascha@3121: filters.add(new IdsFilter(cids)); sascha@3121: } sascha@2608: else if ("date".equals(name)) { sascha@2608: String when = element.getAttribute("when").trim(); sascha@2608: if (when.length() > 0) { sascha@2608: Date date = parseDate(when); sascha@2608: if (date != null) { sascha@2608: filters.add(new DateFilter(date)); sascha@2608: } sascha@2608: } sascha@2608: } sascha@2608: else if ("date-range".equals(name)) { sascha@2608: String from = element.getAttribute("from").trim(); sascha@2608: String to = element.getAttribute("to" ).trim(); sascha@2608: if (from.length() > 0 && to.length() > 0) { sascha@2608: Date start = parseDate(from); sascha@2608: Date end = parseDate(to); sascha@2608: if (start != null && end != null) { sascha@2608: filters.add(new DateRangeFilter(start, end)); sascha@2608: } sascha@2608: } sascha@2608: } sascha@2608: else if ("sector-range".equals(name)) { sascha@2608: String from = element.getAttribute("from").trim(); sascha@2608: String to = element.getAttribute("to" ).trim(); sascha@2608: if (from.length() > 0 && to.length() > 0) { sascha@2608: try { sascha@2608: filters.add(new SectorRangeFilter( sascha@2608: Integer.parseInt(from), sascha@2608: Integer.parseInt(to))); sascha@2608: } sascha@2608: catch (NumberFormatException nfe) { sascha@2608: log.warn(nfe); sascha@2608: } sascha@2608: } sascha@2608: } sascha@3008: else if ("sector".equals(name)) { sascha@3008: String value = element.getAttribute("value").trim(); sascha@3008: if (value.length() > 0) { sascha@3008: try { sascha@3008: filters.add(new SectorFilter(Integer.parseInt(value))); sascha@3008: } sascha@3008: catch (NumberFormatException nfe) { sascha@3008: log.warn(nfe); sascha@3008: } sascha@3008: } sascha@3008: } sascha@3006: else if ("position".equals(name)) { sascha@3006: String km = element.getAttribute("km").trim(); sascha@3006: if (km.length() > 0) { sascha@3006: try { sascha@3006: filters.add(new KmFilter(Double.parseDouble(km))); sascha@3006: } sascha@3006: catch (NumberFormatException nfe) { sascha@3006: log.warn(nfe); sascha@3006: } sascha@3006: } sascha@3006: } sascha@2608: } sascha@2608: sascha@2608: return filters; sascha@2608: } sascha@2608: } sascha@2608: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :