bjoern@3713: package de.intevation.flys.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: 
bjoern@3713: import de.intevation.artifacts.common.ArtifactNamespaceContext;
bjoern@3713: import de.intevation.artifacts.common.utils.XMLUtils;
bjoern@3713: import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
bjoern@3713: import de.intevation.artifacts.httpclient.http.HttpClient;
bjoern@3713: import de.intevation.artifacts.httpclient.http.HttpClientImpl;
bjoern@3713: 
bjoern@4250: import de.intevation.flys.client.client.services.RiverInfoService;
bjoern@3713: import de.intevation.flys.client.shared.exceptions.ServerException;
bjoern@3713: import de.intevation.flys.client.shared.model.DefaultGaugeInfo;
bjoern@4250: import de.intevation.flys.client.shared.model.DefaultMeasurementStation;
bjoern@3713: import de.intevation.flys.client.shared.model.DefaultRiverInfo;
bjoern@3713: import de.intevation.flys.client.shared.model.GaugeInfo;
bjoern@4250: import de.intevation.flys.client.shared.model.MeasurementStation;
bjoern@3713: import de.intevation.flys.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 <a href="mailto:bjoern.ricks@intevation.de">Björn Ricks</a>
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:             List<GaugeInfo>gauges = 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<MeasurementStation> 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<MeasurementStation> 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<MeasurementStation> mstations = new ArrayList<MeasurementStation>(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<GaugeInfo> 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<GaugeInfo> gauges = new ArrayList<GaugeInfo>(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: }