gernotbelger@9288: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde gernotbelger@9288: * Software engineering by Intevation GmbH gernotbelger@9288: * gernotbelger@9288: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9288: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9288: * documentation coming with Dive4Elements River for details. gernotbelger@9288: */ gernotbelger@9288: gernotbelger@9288: package org.dive4elements.river.client.server; gernotbelger@9288: gernotbelger@9288: import java.util.ArrayList; gernotbelger@9288: import java.util.Arrays; gernotbelger@9288: import java.util.Calendar; gernotbelger@9288: import java.util.Comparator; gernotbelger@9288: import java.util.List; gernotbelger@9288: gernotbelger@9288: import javax.xml.xpath.XPathConstants; gernotbelger@9288: gernotbelger@9288: import org.apache.log4j.Logger; gernotbelger@9288: import org.dive4elements.artifacts.common.ArtifactNamespaceContext; gernotbelger@9288: import org.dive4elements.artifacts.common.utils.XMLUtils; gernotbelger@9288: import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException; gernotbelger@9288: import org.dive4elements.artifacts.httpclient.http.HttpClient; gernotbelger@9288: import org.dive4elements.artifacts.httpclient.http.HttpClientImpl; gernotbelger@9288: import org.dive4elements.river.client.shared.exceptions.ServerException; gernotbelger@9288: import org.dive4elements.river.client.shared.model.WQInfoObject; gernotbelger@9288: import org.dive4elements.river.client.shared.model.WQInfoObjectImpl; gernotbelger@9288: import org.w3c.dom.Document; gernotbelger@9288: import org.w3c.dom.Element; gernotbelger@9288: import org.w3c.dom.Node; gernotbelger@9288: import org.w3c.dom.NodeList; gernotbelger@9288: gernotbelger@9288: import com.google.gwt.user.server.rpc.RemoteServiceServlet; gernotbelger@9288: gernotbelger@9288: /** gernotbelger@9288: * @author Ingo Weinzierl gernotbelger@9288: */ gernotbelger@9288: abstract class AbstractMainValuesServiceImpl extends RemoteServiceServlet { gernotbelger@9288: gernotbelger@9288: private static final Logger log = Logger.getLogger(DynamicMainValuesServiceImpl.class); gernotbelger@9288: gernotbelger@9288: private static final Comparator WQ_INFO_OBJECT_CMP = new Comparator() { gernotbelger@9288: @Override gernotbelger@9288: public int compare(final WQInfoObject a, final WQInfoObject b) { gernotbelger@9288: gernotbelger@9288: // Descending by type: Qs before Ds gernotbelger@9288: final int cmp = a.getType().compareTo(b.getType()); gernotbelger@9288: if (cmp < 0) gernotbelger@9288: return +1; gernotbelger@9288: if (cmp > 0) gernotbelger@9288: return -1; gernotbelger@9288: gernotbelger@9288: // Ascending by value gernotbelger@9288: final double diff = a.getValue() - b.getValue(); gernotbelger@9288: if (diff < 0d) gernotbelger@9288: return -1; gernotbelger@9288: if (diff > 0d) gernotbelger@9288: return +1; gernotbelger@9288: return 0; gernotbelger@9288: } gernotbelger@9288: }; gernotbelger@9288: gernotbelger@9288: private static final String ERROR_NO_WQINFO_FOUND = "error_no_wqinfo_found"; gernotbelger@9288: gernotbelger@9288: private static final String XPATH_WQS = "art:service/art:mainvalues/art:mainvalue"; gernotbelger@9288: gernotbelger@9288: private static final long serialVersionUID = 1L; gernotbelger@9288: gernotbelger@9288: protected final Document createInput(final String river, final double from, final double to, final Integer startYear, final Integer endYear) { gernotbelger@9288: gernotbelger@9288: final Document input = XMLUtils.newDocument(); gernotbelger@9288: gernotbelger@9288: final XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(input, ArtifactNamespaceContext.NAMESPACE_URI, gernotbelger@9288: ArtifactNamespaceContext.NAMESPACE_PREFIX); gernotbelger@9288: gernotbelger@9288: final Element mainvalues = ec.create("mainvalues"); gernotbelger@9288: gernotbelger@9288: final Element riverEl = ec.create("river"); gernotbelger@9288: riverEl.setTextContent(river); gernotbelger@9288: mainvalues.appendChild(riverEl); gernotbelger@9288: gernotbelger@9288: final Element startEl = ec.create("start"); gernotbelger@9288: startEl.setTextContent(Double.valueOf(from).toString()); gernotbelger@9288: mainvalues.appendChild(startEl); gernotbelger@9288: gernotbelger@9288: final Element endEl = ec.create("end"); gernotbelger@9288: endEl.setTextContent(Double.valueOf(to).toString()); gernotbelger@9288: mainvalues.appendChild(endEl); gernotbelger@9288: gernotbelger@9288: if (startYear != null) { gernotbelger@9288: final Element startYearElement = ec.create("startYear"); gernotbelger@9288: startYearElement.setTextContent(Integer.toString(startYear)); gernotbelger@9288: mainvalues.appendChild(startYearElement); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: if (endYear != null) { gernotbelger@9288: final Element endYearElement = ec.create("endYear"); gernotbelger@9288: endYearElement.setTextContent(Integer.toString(endYear)); gernotbelger@9288: mainvalues.appendChild(endYearElement); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: input.appendChild(mainvalues); gernotbelger@9288: gernotbelger@9288: return input; gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: protected final WQInfoObject[] callService(final String serviceName, final Document input, final String locale) throws ServerException { gernotbelger@9288: final String url = getServletContext().getInitParameter("server-url"); gernotbelger@9288: gernotbelger@9288: final HttpClient client = new HttpClientImpl(url, locale); gernotbelger@9288: gernotbelger@9288: try { gernotbelger@9288: final Document result = client.callService(url, serviceName, input); gernotbelger@9288: gernotbelger@9288: log.debug("Extract wq info objects now."); gernotbelger@9288: final WQInfoObject[] objects = extractWQInfoObjects(result); gernotbelger@9288: gernotbelger@9288: if (objects.length > 0) { gernotbelger@9288: return objects; gernotbelger@9288: } gernotbelger@9288: } gernotbelger@9288: catch (final ConnectionException ce) { gernotbelger@9288: log.error(ce, ce); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: throw new ServerException(ERROR_NO_WQINFO_FOUND); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: /** gernotbelger@9288: * Extracts all wq info objects from result document. gernotbelger@9288: * gernotbelger@9288: * @param result gernotbelger@9288: * The document retrieved by the server. gernotbelger@9288: * gernotbelger@9288: * @return a list of WQInfoObjects. gernotbelger@9288: */ gernotbelger@9288: private WQInfoObject[] extractWQInfoObjects(final Document result) throws ServerException { gernotbelger@9288: final NodeList list = (NodeList) XMLUtils.xpath(result, XPATH_WQS, XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: if (list == null || list.getLength() == 0) { gernotbelger@9288: log.warn("No wq info found."); gernotbelger@9288: gernotbelger@9288: throw new ServerException(ERROR_NO_WQINFO_FOUND); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: final boolean debug = log.isDebugEnabled(); gernotbelger@9288: gernotbelger@9288: final int num = list.getLength(); gernotbelger@9288: if (debug) { gernotbelger@9288: log.debug("Response contains " + num + " objects."); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: final List objects = new ArrayList(num); gernotbelger@9288: gernotbelger@9288: for (int i = 0; i < num; i++) { gernotbelger@9288: final WQInfoObject obj = buildWQInfoObject(list.item(i)); gernotbelger@9288: gernotbelger@9288: if (obj != null) { gernotbelger@9288: objects.add(obj); gernotbelger@9288: } gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: if (debug) { gernotbelger@9288: log.debug("Retrieved " + objects.size() + " wq values"); gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: final WQInfoObject[] array = objects.toArray(new WQInfoObject[objects.size()]); gernotbelger@9288: gernotbelger@9288: Arrays.sort(array, WQ_INFO_OBJECT_CMP); gernotbelger@9288: gernotbelger@9288: return array; gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: /** gernotbelger@9288: * Extracts information for a single wq info object and intializes an gernotbelger@9288: * WQInfoObject with them. gernotbelger@9288: * gernotbelger@9288: * @param node gernotbelger@9288: * The node that contains the information. gernotbelger@9288: * gernotbelger@9288: * @return a valid WQInfoObject. gernotbelger@9288: */ gernotbelger@9288: private static WQInfoObject buildWQInfoObject(final Node node) { gernotbelger@9288: gernotbelger@9288: final String name = XMLUtils.xpathString(node, "@name", ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: final String type = XMLUtils.xpathString(node, "@type", ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: final String value = XMLUtils.xpathString(node, "@value", ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: final String official = XMLUtils.xpathString(node, "@official", ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: final String starttime = XMLUtils.xpathString(node, "@starttime", ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: final String stoptime = XMLUtils.xpathString(node, "@stoptime", ArtifactNamespaceContext.INSTANCE); gernotbelger@9288: gernotbelger@9288: if (name != null && type != null) { gernotbelger@9288: try { gernotbelger@9288: final Calendar cal = Calendar.getInstance(); gernotbelger@9288: java.util.Date start = null; gernotbelger@9288: java.util.Date stop = null; gernotbelger@9288: if (!starttime.equals("")) { gernotbelger@9288: cal.setTimeInMillis(Long.parseLong(starttime)); gernotbelger@9288: start = cal.getTime(); gernotbelger@9288: } gernotbelger@9288: if (!stoptime.equals("")) { gernotbelger@9288: cal.setTimeInMillis(Long.parseLong(stoptime)); gernotbelger@9288: stop = cal.getTime(); gernotbelger@9288: } gernotbelger@9288: return new WQInfoObjectImpl(name, type, new Double(value), official != null && official.equalsIgnoreCase("true"), start, stop); gernotbelger@9288: } gernotbelger@9288: catch (final NumberFormatException nfe) { gernotbelger@9288: log.warn(nfe.getLocalizedMessage()); gernotbelger@9288: } gernotbelger@9288: } gernotbelger@9288: gernotbelger@9288: log.warn("Invalid wq info object found."); gernotbelger@9288: gernotbelger@9288: return null; gernotbelger@9288: } gernotbelger@9288: }