view gwt-client/src/main/java/org/dive4elements/river/client/server/AbstractMainValuesServiceImpl.java @ 9409:38201f5b0dd9

Changed bundu bzws workflow to stop in case of missing daily discharge values and other minor changes
author mschaefer
date Thu, 16 Aug 2018 08:47:41 +0200
parents bc9a45d2b1fa
children
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.client.server;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.List;

import javax.xml.xpath.XPathConstants;

import org.apache.log4j.Logger;
import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
import org.dive4elements.artifacts.common.utils.XMLUtils;
import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
import org.dive4elements.artifacts.httpclient.http.HttpClient;
import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
import org.dive4elements.river.client.shared.exceptions.ServerException;
import org.dive4elements.river.client.shared.model.WQInfoObject;
import org.dive4elements.river.client.shared.model.WQInfoObjectImpl;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
abstract class AbstractMainValuesServiceImpl extends RemoteServiceServlet {

    private static final Logger log = Logger.getLogger(AbstractMainValuesServiceImpl.class);

    private static final Comparator<WQInfoObject> WQ_INFO_OBJECT_CMP = new Comparator<WQInfoObject>() {
        @Override
        public int compare(final WQInfoObject a, final WQInfoObject b) {

            // Descending by type: Qs before Ds
            final int cmp = a.getType().compareTo(b.getType());
            if (cmp < 0)
                return +1;
            if (cmp > 0)
                return -1;

            // Ascending by value
            final double diff = a.getValue() - b.getValue();
            if (diff < 0d)
                return -1;
            if (diff > 0d)
                return +1;
            return 0;
        }
    };

    private static final String ERROR_NO_WQINFO_FOUND = "error_no_wqinfo_found";

    private static final String XPATH_WQS = "art:service/art:mainvalues/art:mainvalue";

    private static final long serialVersionUID = 1L;

    public static final Document createInput(final String river, final double from, final double to, final java.util.Date startDate,
            final java.util.Date endDate) {

        final Document input = XMLUtils.newDocument();

        final XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(input, ArtifactNamespaceContext.NAMESPACE_URI,
                ArtifactNamespaceContext.NAMESPACE_PREFIX);

        final Element mainvalues = ec.create("mainvalues");

        final Element riverEl = ec.create("river");
        riverEl.setTextContent(river);
        mainvalues.appendChild(riverEl);

        final Element startEl = ec.create("start");
        startEl.setTextContent(Double.valueOf(from).toString());
        mainvalues.appendChild(startEl);

        final Element endEl = ec.create("end");
        endEl.setTextContent(Double.valueOf(to).toString());
        mainvalues.appendChild(endEl);

        if (startDate != null) { // IMPORTANT, MainValueService and DynamicMainValueService share this method. MainvalueService does not have Dates
            final Element startDateElement = ec.create("startDate");
            startDateElement.setTextContent(String.valueOf(startDate.getTime()));
            mainvalues.appendChild(startDateElement);
        }
        if (endDate != null) {// IMPORTANT, MainValueService and DynamicMainValueService share this method. MainvalueService does not have Dates
            final Element endDateElement = ec.create("endDate");
            endDateElement.setTextContent(String.valueOf(endDate.getTime()));
            mainvalues.appendChild(endDateElement);
        }

        input.appendChild(mainvalues);

        return input;
    }

    protected final WQInfoObject[] callService(final String serviceName, final Document input, final String locale) throws ServerException {
        final String url = getServletContext().getInitParameter("server-url");

        final HttpClient client = new HttpClientImpl(url, locale);

        try {
            final Document result = client.callService(url, serviceName, input);

            log.debug("Extract wq info objects now.");
            final WQInfoObject[] objects = extractWQInfoObjects(result);

            if (objects.length > 0) {
                return objects;
            }
        }
        catch (final ConnectionException ce) {
            log.error(ce, ce);
        }

        throw new ServerException(ERROR_NO_WQINFO_FOUND);
    }

    /**
     * Extracts all wq info objects from <i>result</i> document.
     *
     * @param result
     *            The document retrieved by the server.
     *
     * @return a list of WQInfoObjects.
     */
    private WQInfoObject[] extractWQInfoObjects(final Document result) throws ServerException {
        final NodeList list = (NodeList) XMLUtils.xpath(result, XPATH_WQS, XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);

        if (list == null || list.getLength() == 0) {
            log.warn("No wq info found.");

            throw new ServerException(ERROR_NO_WQINFO_FOUND);
        }

        final boolean debug = log.isDebugEnabled();

        final int num = list.getLength();
        if (debug) {
            log.debug("Response contains " + num + " objects.");
        }

        final List<WQInfoObject> objects = new ArrayList<WQInfoObject>(num);

        for (int i = 0; i < num; i++) {
            final WQInfoObject obj = buildWQInfoObject(list.item(i));

            if (obj != null) {
                objects.add(obj);
            }
        }

        if (debug) {
            log.debug("Retrieved " + objects.size() + " wq values");
        }

        final WQInfoObject[] array = objects.toArray(new WQInfoObject[objects.size()]);

        Arrays.sort(array, WQ_INFO_OBJECT_CMP);

        return array;
    }

    /**
     * Extracts information for a single wq info object and intializes an
     * WQInfoObject with them.
     *
     * @param node
     *            The node that contains the information.
     *
     * @return a valid WQInfoObject.
     */
    private static WQInfoObject buildWQInfoObject(final Node node) {

        final String name = XMLUtils.xpathString(node, "@name", ArtifactNamespaceContext.INSTANCE);

        final String type = XMLUtils.xpathString(node, "@type", ArtifactNamespaceContext.INSTANCE);

        final String value = XMLUtils.xpathString(node, "@value", ArtifactNamespaceContext.INSTANCE);

        final String official = XMLUtils.xpathString(node, "@official", ArtifactNamespaceContext.INSTANCE);

        final String starttime = XMLUtils.xpathString(node, "@starttime", ArtifactNamespaceContext.INSTANCE);

        final String stoptime = XMLUtils.xpathString(node, "@stoptime", ArtifactNamespaceContext.INSTANCE);

        if (name != null && type != null) {
            try {
                final Calendar cal = Calendar.getInstance();
                java.util.Date start = null;
                java.util.Date stop = null;
                if (!starttime.equals("")) {
                    cal.setTimeInMillis(Long.parseLong(starttime));
                    start = cal.getTime();
                }
                if (!stoptime.equals("")) {
                    cal.setTimeInMillis(Long.parseLong(stoptime));
                    stop = cal.getTime();
                }
                return new WQInfoObjectImpl(name, type, new Double(value), official != null && official.equalsIgnoreCase("true"), start, stop);
            }
            catch (final NumberFormatException nfe) {
                log.warn(nfe.getLocalizedMessage());
            }
        }

        log.warn("Invalid wq info object found.");

        return null;
    }
}

http://dive4elements.wald.intevation.org