view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/FixingsOverviewService.java @ 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 b3f6d49cdc80
children 938e2f6c0c9a
line wrap: on
line source
package de.intevation.flys.artifacts.services;

import de.intevation.artifacts.CallMeta;
import de.intevation.artifacts.GlobalContext;

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
extends      FLYSService
{
    private static Logger log =
        Logger.getLogger(FixingsOverviewService.class);

    public FixingsOverviewService() {
    }

    @Override
    public Document doProcess(
        Document      data,
        GlobalContext globalContext,
        CallMeta      callMeta
    ) {
        log.debug("FixingsOverviewService.doProcess");

        Document document = XMLUtils.newDocument();

        NodeList nodes = data.getElementsByTagName("river");

        String river = nodes.getLength() > 0
            ? ((Element)nodes.item(0)).getAttribute("name")
            : "";

        FixingsOverview overview = FixingsOverviewFactory.getOverview(river);

        if (overview != null) {
            Range  range  = getRange(data);
            Filter filter = getFilter(data);
            overview.generateOverview(document, range, filter);
        }
        else {
            log.warn("No overview for river '" + river + "' available.");
        }

        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