ingo@301: package de.intevation.flys.artifacts.services;
ingo@301: 
sascha@644: import java.util.Iterator;
ingo@301: 
ingo@301: import org.apache.log4j.Logger;
ingo@301: 
ingo@301: import org.w3c.dom.Document;
ingo@301: import org.w3c.dom.Element;
ingo@301: 
ingo@301: import de.intevation.artifacts.CallMeta;
sascha@966: import de.intevation.artifacts.GlobalContext;
ingo@301: 
ingo@301: import de.intevation.artifacts.common.ArtifactNamespaceContext;
ingo@301: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@301: 
sascha@2145: import de.intevation.flys.model.FastAnnotations;
ingo@301: 
sascha@2145: import de.intevation.flys.artifacts.model.LocationProvider;
ingo@301: 
sascha@644: 
ingo@301: /**
ingo@301:  * This service provides information about distances of a specified river.
ingo@301:  *
ingo@301:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@301:  */
ingo@1631: public class DistanceInfoService extends FLYSService {
ingo@301: 
felix@1070:     /** The logger used in this service. */
ingo@301:     private static Logger logger = Logger.getLogger(DistanceInfoService.class);
ingo@301: 
sascha@644:     public static final String RIVER_XPATH = "/art:river/text()";
sascha@644: 
ingo@922:     public static final String FILTER_XPATH = "/art:river/art:filter/text()";
ingo@922: 
ingo@301: 
ingo@301:     /**
ingo@301:      * The default constructor.
ingo@301:      */
ingo@301:     public DistanceInfoService() {
ingo@301:     }
ingo@301: 
ingo@301: 
sascha@966:     @Override
ingo@1631:     public Document doProcess(
sascha@966:         Document      data,
sascha@966:         GlobalContext globalContext,
sascha@966:         CallMeta      callMeta
sascha@966:     ) {
ingo@301:         logger.debug("DistanceInfoService.process");
ingo@301: 
ingo@301:         String river = XMLUtils.xpathString(
sascha@644:             data, RIVER_XPATH, ArtifactNamespaceContext.INSTANCE);
ingo@301: 
sascha@2145:         String filterName  = XMLUtils.xpathString(
ingo@922:             data, FILTER_XPATH, ArtifactNamespaceContext.INSTANCE);
ingo@922: 
sascha@644:         if (river == null || (river = river.trim()).length() == 0) {
ingo@301:             logger.warn("No river specified. Cannot return distance info!");
sascha@644:             return XMLUtils.newDocument();
ingo@301:         }
ingo@301: 
ingo@301:         logger.debug("Search distances for river: " + river);
ingo@301: 
sascha@2145:         FastAnnotations fas = LocationProvider.getAnnotations(river);
sascha@644: 
sascha@2145:         FastAnnotations.Filter filter = selectFilter(filterName);
sascha@644: 
sascha@2145:         return buildDocument(fas.filter(filter));
sascha@644:     }
sascha@644: 
sascha@2145:     protected Document buildDocument(
sascha@2145:         Iterator<FastAnnotations.Annotation> iter
sascha@2145:     ) {
sascha@644:         Document result = XMLUtils.newDocument();
sascha@644: 
ingo@1631:         Element all = result.createElement("distances");
ingo@922: 
ingo@1631:         while (iter.hasNext()) {
sascha@2145:             all.appendChild(buildNode(result, iter.next()));
ingo@301:         }
ingo@1631: 
ingo@1631:         result.appendChild(all);
ingo@301: 
ingo@301:         return result;
ingo@301:     }
ingo@301: 
sascha@2145:     protected static FastAnnotations.Filter selectFilter(String name) {
ingo@301: 
sascha@2145:         if (name != null) {
sascha@2145:             if ("locations".equals(name)) return FastAnnotations.IS_POINT;
sascha@2145:             if ("distances".equals(name)) return FastAnnotations.IS_RANGE;
raimund@3058:             if ("measuringpoint".equals(name))
raimund@3071:                 return new FastAnnotations.NameFilter("Messstelle");
ingo@922:         }
ingo@922: 
sascha@2145:         return FastAnnotations.ALL;
ingo@922:     }
ingo@922: 
ingo@301:     /**
felix@1070:      * Builds an Element for a distance info.
ingo@301:      *
sascha@2145:      * @param an The Annotation that provides information about the distance.
ingo@301:      *
ingo@301:      * @return an Element that contains information about a distance.
ingo@301:      */
sascha@2145:     protected static Element buildNode(
sascha@2145:         Document                   document,
sascha@2145:         FastAnnotations.Annotation an
ingo@686:     ) {
ingo@686:         Element distance = document.createElement("distance");
ingo@301: 
sascha@2145:         distance.setAttribute("description", an.getPosition());
ingo@686: 
sascha@2145:         String riverSide = an.getAttribute();
ingo@686: 
ingo@686:         if (riverSide != null && riverSide.length() > 0) {
ingo@686:             distance.setAttribute("riverside", riverSide);
ingo@686:         }
ingo@686: 
sascha@2145:         distance.setAttribute("from", String.valueOf(an.getA()));
sascha@2145: 
sascha@2145:         double b      = an.getB();
sascha@2145:         double bottom = an.getBottom();
sascha@2145:         double top    = an.getTop();
sascha@2145: 
sascha@2145:         if (!Double.isNaN(b)) {
sascha@2145:             distance.setAttribute("to", String.valueOf(b));
ingo@686:         }
sascha@2145: 
sascha@2145:         if (!Double.isNaN(bottom)) {
sascha@2145:             distance.setAttribute("bottom", String.valueOf(bottom));
sascha@2145:         }
sascha@2145: 
sascha@2145:         if (!Double.isNaN(top)) {
sascha@2145:             distance.setAttribute("top", String.valueOf(top));
ingo@686:         }
ingo@301: 
ingo@301:         return distance;
ingo@301:     }
ingo@301: }
ingo@301: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :