rrenkert@4298: package de.intevation.flys.client.server;
rrenkert@4298: 
rrenkert@4298: import java.util.ArrayList;
rrenkert@4298: import java.util.List;
rrenkert@4298: 
rrenkert@4298: import org.apache.log4j.Logger;
rrenkert@4298: import org.w3c.dom.Document;
rrenkert@4298: import org.w3c.dom.Element;
rrenkert@4298: import org.w3c.dom.NodeList;
rrenkert@4298: 
rrenkert@4298: import com.google.gwt.user.server.rpc.RemoteServiceServlet;
rrenkert@4298: 
rrenkert@4298: import de.intevation.artifacts.common.ArtifactNamespaceContext;
rrenkert@4298: import de.intevation.artifacts.common.utils.XMLUtils;
rrenkert@4298: import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
rrenkert@4298: import de.intevation.artifacts.httpclient.http.HttpClient;
rrenkert@4298: import de.intevation.artifacts.httpclient.http.HttpClientImpl;
rrenkert@4298: import de.intevation.flys.client.client.services.SedimentLoadInfoService;
rrenkert@4298: import de.intevation.flys.client.shared.exceptions.ServerException;
rrenkert@4298: import de.intevation.flys.client.shared.model.SedimentLoadInfoObject;
rrenkert@4298: import de.intevation.flys.client.shared.model.SedimentLoadInfoObjectImpl;
rrenkert@4298: 
rrenkert@4298: 
rrenkert@4298: public class SedimentLoadInfoServiceImpl
rrenkert@4298: extends RemoteServiceServlet
rrenkert@4298: implements SedimentLoadInfoService
rrenkert@4298: {
rrenkert@4298:     private static final Logger logger =
rrenkert@4298:         Logger.getLogger(SedimentLoadInfoServiceImpl.class);
rrenkert@4298: 
rrenkert@4298:     public static final String ERROR_NO_SEDIMENTLOADINFO_FOUND =
rrenkert@4298:         "error_no_sedimentloadinfo_found";
rrenkert@4298: 
rrenkert@4298:     @Override
rrenkert@4298:     public SedimentLoadInfoObject[] getSedimentLoadInfo(
rrenkert@4298:         String locale,
rrenkert@4298:         String river,
rrenkert@4298:         String type,
rrenkert@4298:         double startKm,
rrenkert@4298:         double endKm)
rrenkert@4298:     throws ServerException
rrenkert@4298:     {
rrenkert@4298:         logger.info("SedimentLoadInfoServiceImpl.getSedimentLoadInfo");
rrenkert@4298: 
rrenkert@4298:         String url  = getServletContext().getInitParameter("server-url");
rrenkert@4298: 
rrenkert@4298:         Document doc = XMLUtils.newDocument();
rrenkert@4298: 
rrenkert@4298:         XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
rrenkert@4298:             doc,
rrenkert@4298:             ArtifactNamespaceContext.NAMESPACE_URI,
rrenkert@4298:             ArtifactNamespaceContext.NAMESPACE_PREFIX);
rrenkert@4298: 
rrenkert@4298:         Element riverEl = ec.create("river");
rrenkert@4298:         Element location = ec.create("location");
rrenkert@4298:         Element from = ec.create("from");
rrenkert@4298:         Element to = ec.create("to");
rrenkert@4298:         Element typeEl = ec.create("type");
rrenkert@4298:         riverEl.setTextContent(river);
rrenkert@4298:         from.setTextContent(String.valueOf(startKm));
rrenkert@4298:         to.setTextContent(String.valueOf(endKm));
rrenkert@4298:         typeEl.setTextContent(type);
rrenkert@4298: 
rrenkert@4298:         location.appendChild(from);
rrenkert@4298:         location.appendChild(to);
rrenkert@4298:         riverEl.appendChild(location);
rrenkert@4298:         riverEl.appendChild(typeEl);
rrenkert@4298:         doc.appendChild(riverEl);
rrenkert@4298: 
rrenkert@4298:         HttpClient client = new HttpClientImpl(url, locale);
rrenkert@4298: 
rrenkert@4298:         try {
rrenkert@4298:             Document result = client.callService(url, "sedimentloadinfo", doc);
rrenkert@4298: 
rrenkert@4298:             logger.debug("Extract sedimentload info objects now.");
rrenkert@4298:             SedimentLoadInfoObject[] objects =
rrenkert@4298:                 extractSedimentLoadInfoObjects(result);
rrenkert@4298: 
rrenkert@4298:             if (objects != null && objects.length > 0) {
rrenkert@4298:                 return objects;
rrenkert@4298:             }
rrenkert@4298:         }
rrenkert@4298:         catch (ConnectionException ce) {
rrenkert@4298:             logger.error(ce, ce);
rrenkert@4298:         }
rrenkert@4298: 
rrenkert@4298:         throw new ServerException(ERROR_NO_SEDIMENTLOADINFO_FOUND);
rrenkert@4298:     }
rrenkert@4298: 
rrenkert@4298: 
rrenkert@4298:     /**
rrenkert@4298:      * Extracts all distance info objects from <i>result</i> document.
rrenkert@4298:      *
rrenkert@4298:      * @param result The document retrieved by the server.
rrenkert@4298:      *
rrenkert@4298:      * @return a list of DistanceInfoObjects.
rrenkert@4298:      */
rrenkert@4298:     protected SedimentLoadInfoObject[] extractSedimentLoadInfoObjects(
rrenkert@4298:         Document result)
rrenkert@4298:     throws ServerException
rrenkert@4298:     {
rrenkert@4298:         NodeList list = result.getElementsByTagName("sedimentload");
rrenkert@4298: 
rrenkert@4298:         if (list == null || list.getLength() == 0) {
rrenkert@4298:             logger.warn("No sedimentload info found.");
rrenkert@4298:             throw new ServerException(ERROR_NO_SEDIMENTLOADINFO_FOUND);
rrenkert@4298:         }
rrenkert@4298: 
rrenkert@4298:         int num = list.getLength();
rrenkert@4298:         logger.debug("Response contains " + num + " objects.");
rrenkert@4298: 
rrenkert@4298:         List<SedimentLoadInfoObject> objects =
rrenkert@4298:             new ArrayList<SedimentLoadInfoObject>(num);
rrenkert@4298: 
rrenkert@4298:         for (int i = 0; i < num; i++) {
rrenkert@4298:             SedimentLoadInfoObject obj = buildSedimentLoadInfoObject(
rrenkert@4298:                 (Element)list.item(i));
rrenkert@4298: 
rrenkert@4298:             if (obj != null) {
rrenkert@4298:                 objects.add(obj);
rrenkert@4298:             }
rrenkert@4298:         }
rrenkert@4298: 
rrenkert@4298:         logger.debug("Retrieved " + objects.size() + " sediment loads.");
rrenkert@4298: 
rrenkert@4298:         return (SedimentLoadInfoObject[])
rrenkert@4298:             objects.toArray(new SedimentLoadInfoObject[num]);
rrenkert@4298:     }
rrenkert@4298: 
rrenkert@4298: 
rrenkert@4298:     /**
rrenkert@4298:      * Extracts information for a single distance info object and intializes an
rrenkert@4298:      * DistanceInfoObject with them.
rrenkert@4298:      *
rrenkert@4298:      * @param node The node that contains the information.
rrenkert@4298:      *
rrenkert@4298:      * @return a valid DistanceInfoObject.
rrenkert@4298:      */
rrenkert@4298:     protected SedimentLoadInfoObject buildSedimentLoadInfoObject(Element node) {
rrenkert@4298: 
rrenkert@4298:         String desc      = node.getAttribute("description").trim();
rrenkert@4298:         String date      = node.getAttribute("date").trim();
rrenkert@4298: 
rrenkert@4298:         if (desc.length() > 0 && date.length() > 0) {
rrenkert@4298:             return new SedimentLoadInfoObjectImpl(desc, date);
rrenkert@4298:         }
rrenkert@4298: 
rrenkert@4298:         logger.warn("Invalid sediment load info object found.");
rrenkert@4298: 
rrenkert@4298:         return null;
rrenkert@4298:     }
rrenkert@4298: }