teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5861: * Software engineering by Intevation GmbH teichmann@5861: * teichmann@5861: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5861: * documentation coming with Dive4Elements River for details. teichmann@5861: */ teichmann@5861: teichmann@5835: package org.dive4elements.river.client.server; bjoern@3713: bjoern@4288: import java.text.DateFormat; bjoern@4288: import java.text.ParseException; bjoern@3713: import java.util.ArrayList; bjoern@4288: import java.util.Date; bjoern@4250: import java.util.List; bjoern@4288: import java.util.Locale; bjoern@3713: import javax.xml.xpath.XPathConstants; bjoern@3713: bjoern@3713: import org.apache.log4j.Logger; bjoern@3713: bjoern@3713: import org.w3c.dom.Document; bjoern@3713: import org.w3c.dom.Element; bjoern@3713: import org.w3c.dom.NodeList; bjoern@3713: teichmann@5835: import org.dive4elements.artifacts.common.ArtifactNamespaceContext; teichmann@5835: import org.dive4elements.artifacts.common.utils.XMLUtils; teichmann@5835: import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException; teichmann@5835: import org.dive4elements.artifacts.httpclient.http.HttpClient; teichmann@5835: import org.dive4elements.artifacts.httpclient.http.HttpClientImpl; bjoern@3713: teichmann@5835: import org.dive4elements.river.client.client.services.RiverInfoService; teichmann@5835: import org.dive4elements.river.client.shared.exceptions.ServerException; teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultGaugeInfo; teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultMeasurementStation; teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultRiverInfo; teichmann@5835: import org.dive4elements.river.client.shared.model.GaugeInfo; teichmann@5835: import org.dive4elements.river.client.shared.model.MeasurementStation; teichmann@5835: import org.dive4elements.river.client.shared.model.RiverInfo; bjoern@3713: bjoern@4250: bjoern@3713: /** felix@4436: * GWT Service to serve the gauge and measurement station info felix@4436: * bjoern@3713: * @author Björn Ricks bjoern@3713: */ bjoern@4250: public class RiverInfoServiceImpl bjoern@3713: extends RemoteServiceServlet bjoern@4250: implements RiverInfoService bjoern@3713: { bjoern@3713: private static final Logger logger = bjoern@4250: Logger.getLogger(RiverInfoServiceImpl.class); bjoern@3713: bjoern@4250: public static final String ERROR_NO_RIVER_INFO_FOUND = bjoern@4250: "error_no_riverinfo_found"; bjoern@3713: bjoern@4250: private static final String XPATH_RIVER = bjoern@4250: "/art:river-info/art:river"; bjoern@3713: bjoern@4250: private static final String XPATH_STATIONS = bjoern@4250: "/art:river-info/art:measurement-stations/art:measurement-station"; bjoern@4250: bjoern@4250: private static final String XPATH_GAUGES = "/art:river-info/art:gauges/art:gauge"; bjoern@4250: bjoern@4288: public static final DateFormat DATE_FORMAT = DateFormat.getDateInstance( bjoern@4288: DateFormat.SHORT, Locale.GERMANY); bjoern@4288: bjoern@4250: public RiverInfo getGauges(String river) throws ServerException { bjoern@3713: logger.info("RiverInfoServiceImpl.getRiverInfo"); bjoern@3713: bjoern@3713: String url = getServletContext().getInitParameter("server-url"); bjoern@3713: bjoern@3713: Document doc = XMLUtils.newDocument(); bjoern@3713: bjoern@3713: XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( bjoern@3713: doc, bjoern@3713: ArtifactNamespaceContext.NAMESPACE_URI, bjoern@3713: ArtifactNamespaceContext.NAMESPACE_PREFIX); bjoern@3713: bjoern@3713: Element riverele = ec.create("river"); bjoern@3713: riverele.setTextContent(river); bjoern@3713: bjoern@3713: doc.appendChild(riverele); bjoern@3713: bjoern@3713: HttpClient client = new HttpClientImpl(url); bjoern@3713: bjoern@3713: try { bjoern@3713: Document result = client.callService(url, "gaugeoverviewinfo", doc); bjoern@3713: bjoern@4250: DefaultRiverInfo riverinfo = getRiverInfo(result); bjoern@4250: Listgauges = createGauges(result, riverinfo.getName(), bjoern@4250: riverinfo.isKmUp(), riverinfo.getWstUnit()); bjoern@3713: bjoern@3713: bjoern@4250: riverinfo.setGauges(gauges); bjoern@3713: bjoern@4250: logger.debug("Finished RiverInfoService.getGauges."); bjoern@3713: bjoern@3713: return riverinfo; bjoern@3713: } bjoern@3713: catch (ConnectionException ce) { bjoern@3713: logger.error(ce, ce); bjoern@3713: } bjoern@3713: bjoern@3713: logger.warn("No gauge found"); bjoern@4250: throw new ServerException(ERROR_NO_RIVER_INFO_FOUND); bjoern@4250: } bjoern@4250: bjoern@4250: public RiverInfo getMeasurementStations(String river) throws ServerException { bjoern@4250: logger.info("RiverInfoServiceImpl.getMeasurementStations"); bjoern@4250: bjoern@4250: String url = getServletContext().getInitParameter("server-url"); bjoern@4250: bjoern@4250: Document doc = XMLUtils.newDocument(); bjoern@4250: bjoern@4250: XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( bjoern@4250: doc, bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, bjoern@4250: ArtifactNamespaceContext.NAMESPACE_PREFIX); bjoern@4250: bjoern@4250: Element riverele = ec.create("river"); bjoern@4250: riverele.setTextContent(river); bjoern@4250: bjoern@4250: doc.appendChild(riverele); bjoern@4250: bjoern@4250: HttpClient client = new HttpClientImpl(url); bjoern@4250: bjoern@4250: try { bjoern@4250: Document result = client.callService(url, "measurementstationinfo", doc); bjoern@4250: bjoern@4250: DefaultRiverInfo riverinfo = getRiverInfo(result); bjoern@4250: List mstations = createMeasurementStations( bjoern@4266: result, riverinfo.getName(), riverinfo.isKmUp()); bjoern@4250: bjoern@4250: riverinfo.setMeasurementStations(mstations); bjoern@4250: bjoern@4250: logger.debug("Finished MeasurementStationInfoService."); bjoern@4250: bjoern@4250: return riverinfo; bjoern@4250: } bjoern@4250: catch (ConnectionException ce) { bjoern@4250: logger.error(ce, ce); bjoern@4250: } bjoern@4250: bjoern@4250: logger.warn("No measurement station found"); bjoern@4250: throw new ServerException(ERROR_NO_RIVER_INFO_FOUND); bjoern@3713: } bjoern@3713: bjoern@3713: /** bjoern@3713: * Avoids NullPointerException when parsing double value bjoern@3713: */ bjoern@3713: private Double parseDouble(String value) { bjoern@3713: if (value == null || value.isEmpty()) { bjoern@3713: return null; bjoern@3713: } bjoern@3713: try { bjoern@3713: return Double.valueOf(value); bjoern@3713: } bjoern@3713: catch(NumberFormatException e) { bjoern@3713: logger.error(e, e); bjoern@3713: return null; bjoern@3713: } bjoern@3713: } bjoern@3843: bjoern@3843: private Long parseLong(String value) { bjoern@3843: if (value == null || value.isEmpty()) { bjoern@3843: return null; bjoern@3843: } bjoern@3843: try { bjoern@3843: return Long.valueOf(value); bjoern@3843: } bjoern@3843: catch(NumberFormatException e) { bjoern@3843: logger.error(e, e); bjoern@3843: return null; bjoern@3843: } bjoern@3843: } bjoern@4250: bjoern@4266: private Integer parseInteger(String value) { bjoern@4266: if (value == null || value.isEmpty()) { bjoern@4266: return null; bjoern@4266: } bjoern@4266: try { bjoern@4266: return Integer.valueOf(value); bjoern@4266: } bjoern@4266: catch(NumberFormatException e) { bjoern@4266: logger.error(e, e); bjoern@4266: return null; bjoern@4266: } bjoern@4266: } bjoern@4266: bjoern@4288: private Date parseDate(String value) { bjoern@4288: if (value == null || value.isEmpty()) { bjoern@4288: return null; bjoern@4288: } bjoern@4288: try { bjoern@4288: return DATE_FORMAT.parse(value); bjoern@4288: } bjoern@4288: catch(ParseException e) { bjoern@4288: logger.error(e, e); bjoern@4288: return null; bjoern@4288: } bjoern@4288: } bjoern@4288: bjoern@4250: private List createMeasurementStations( bjoern@4266: Document result, String rivername, boolean kmup) { bjoern@4266: bjoern@4250: NodeList stationnodes = (NodeList) XMLUtils.xpath( bjoern@4250: result, bjoern@4250: XPATH_STATIONS, bjoern@4250: XPathConstants.NODESET, bjoern@4250: ArtifactNamespaceContext.INSTANCE); bjoern@4250: bjoern@4250: int num = stationnodes == null ? 0 : stationnodes.getLength(); bjoern@4250: bjoern@4250: ArrayList mstations = new ArrayList(num); bjoern@4250: bjoern@4250: if (num == 0) { bjoern@4250: logger.warn("No measurement station found."); bjoern@4250: } bjoern@4250: else { bjoern@4250: logger.debug("Found " + num + " measurement stations."); bjoern@4250: bjoern@4250: for (int i = 0; i < num; i++) { bjoern@4250: Element stationele = (Element)stationnodes.item(i); bjoern@4250: bjoern@4250: String mname = stationele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "name"); bjoern@4250: String mstart = stationele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "start"); bjoern@4250: String mend = stationele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "end"); bjoern@4250: String mstation = stationele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "station"); bjoern@4250: String mtype = stationele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "type"); bjoern@4250: String riverside = stationele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "riverside"); bjoern@4266: String mid = stationele.getAttributeNS( bjoern@4266: ArtifactNamespaceContext.NAMESPACE_URI, "id"); bjoern@4266: String moperator = stationele.getAttributeNS( bjoern@4266: ArtifactNamespaceContext.NAMESPACE_URI, "operator"); bjoern@4288: String mstarttime = stationele.getAttributeNS( bjoern@4288: ArtifactNamespaceContext.NAMESPACE_URI, "starttime"); bjoern@4288: String mstoptime = stationele.getAttributeNS( bjoern@4288: ArtifactNamespaceContext.NAMESPACE_URI, "stoptime"); bjoern@4250: bjoern@4326: String gaugename = null; bjoern@4326: bjoern@4326: Element gaugeele = (Element)stationele.getFirstChild(); bjoern@4326: if (gaugeele != null) { bjoern@4326: gaugename = gaugeele.getAttributeNS( bjoern@4326: ArtifactNamespaceContext.NAMESPACE_URI, "name"); bjoern@4326: } bjoern@4326: bjoern@4326: bjoern@4250: logger.debug("Found measurement station with name " + mname); bjoern@4250: bjoern@4250: MeasurementStation station = new DefaultMeasurementStation( bjoern@4250: rivername, bjoern@4250: mname, bjoern@4266: parseInteger(mid), bjoern@4250: parseDouble(mstation), bjoern@4250: parseDouble(mstart), bjoern@4250: parseDouble(mend), bjoern@4266: kmup, bjoern@4250: riverside, bjoern@4266: mtype, bjoern@4288: moperator, bjoern@4288: parseDate(mstarttime), bjoern@4326: parseDate(mstoptime), bjoern@4326: gaugename bjoern@4250: ); bjoern@4250: bjoern@4250: mstations.add(station); bjoern@4250: } bjoern@4250: } bjoern@4250: return mstations; bjoern@4250: } bjoern@4250: bjoern@4250: private List createGauges( bjoern@4250: Document result, String rivername, Boolean kmup, String rwstunit) { bjoern@4250: NodeList gaugenodes = (NodeList) XMLUtils.xpath( bjoern@4250: result, bjoern@4250: XPATH_GAUGES, bjoern@4250: XPathConstants.NODESET, bjoern@4250: ArtifactNamespaceContext.INSTANCE); bjoern@4250: bjoern@4250: int num = gaugenodes == null ? 0 : gaugenodes.getLength(); bjoern@4250: bjoern@4250: ArrayList gauges = new ArrayList(num); bjoern@4250: bjoern@4250: if (num == 0) { bjoern@4250: logger.warn("No gauge info found."); bjoern@4250: } bjoern@4250: else { bjoern@4250: logger.debug("Found " + num + " gauges."); bjoern@4250: bjoern@4250: for (int i = 0; i < num; i++) { bjoern@4250: Element gaugeele = (Element)gaugenodes.item(i); bjoern@4250: bjoern@4250: String gname = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "name"); bjoern@4250: String gstart = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "start"); bjoern@4250: String gend = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "end"); bjoern@4250: String gdatum = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "datum"); bjoern@4250: String gaeo = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "aeo"); bjoern@4250: String gminq = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "minq"); bjoern@4250: String gminw = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "minw"); bjoern@4250: String gmaxq = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "maxq"); bjoern@4250: String gmaxw = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "maxw"); bjoern@4250: String gstation = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "station"); bjoern@4250: String gofficial = gaugeele.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "official"); bjoern@4250: bjoern@4250: logger.debug("Found gauge with name " + gname); bjoern@4250: bjoern@4250: GaugeInfo gaugeinfo = new DefaultGaugeInfo( bjoern@4250: rivername, bjoern@4250: gname, bjoern@4250: kmup, bjoern@4250: parseDouble(gstation), bjoern@4250: parseDouble(gstart), bjoern@4250: parseDouble(gend), bjoern@4250: parseDouble(gdatum), bjoern@4250: parseDouble(gaeo), bjoern@4250: parseDouble(gminq), bjoern@4250: parseDouble(gmaxq), bjoern@4250: parseDouble(gminw), bjoern@4250: parseDouble(gmaxw), bjoern@4250: rwstunit, bjoern@4250: parseLong(gofficial) bjoern@4250: ); bjoern@4250: bjoern@4250: gauges.add(gaugeinfo); bjoern@4250: } bjoern@4250: } bjoern@4250: return gauges; bjoern@4250: } bjoern@4250: bjoern@4250: private DefaultRiverInfo getRiverInfo(Document result) { bjoern@4250: Element riverresp = (Element) XMLUtils.xpath( bjoern@4250: result, bjoern@4250: XPATH_RIVER, bjoern@4250: XPathConstants.NODE, bjoern@4250: ArtifactNamespaceContext.INSTANCE); bjoern@4250: bjoern@4250: String rname = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "name"); bjoern@4250: String rkmup = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "kmup"); bjoern@4250: String rstart = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "start"); bjoern@4250: String rend = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "end"); bjoern@4250: String rwstunit = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "wstunit"); bjoern@4250: String rminq = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "minq"); bjoern@4250: String rmaxq = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "maxq"); bjoern@4250: String rofficial = riverresp.getAttributeNS( bjoern@4250: ArtifactNamespaceContext.NAMESPACE_URI, "official"); bjoern@4250: bjoern@4250: logger.debug("River is " + rname); bjoern@4250: bjoern@4250: boolean kmup = rkmup.equalsIgnoreCase("true"); bjoern@4250: DefaultRiverInfo riverinfo = new DefaultRiverInfo( bjoern@4250: rname, bjoern@4250: kmup, bjoern@4250: parseDouble(rstart), bjoern@4250: parseDouble(rend), bjoern@4250: rwstunit, bjoern@4250: parseDouble(rminq), bjoern@4250: parseDouble(rmaxq), bjoern@4250: parseLong(rofficial) bjoern@4250: ); bjoern@4250: bjoern@4250: return riverinfo; bjoern@4250: } bjoern@3713: }