ingo@1058: package de.intevation.flys.artifacts.services;
ingo@1058: 
ingo@1774: import com.vividsolutions.jts.geom.Envelope;
ingo@1058: 
christian@4801: import de.intevation.artifactdatabase.XMLService;
ingo@1058: import de.intevation.artifacts.CallMeta;
ingo@1058: import de.intevation.artifacts.GlobalContext;
ingo@1058: import de.intevation.artifacts.common.ArtifactNamespaceContext;
ingo@1058: import de.intevation.artifacts.common.utils.Config;
ingo@1058: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@1058: import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
christian@4801: import de.intevation.flys.utils.GeometryUtils;
ingo@1058: 
christian@4801: import java.util.HashMap;
christian@4801: import java.util.Map;
ingo@1058: 
christian@4801: import javax.xml.xpath.XPathConstants;
christian@4801: 
christian@4801: import org.apache.log4j.Logger;
christian@4801: import org.w3c.dom.Document;
christian@4801: import org.w3c.dom.Element;
christian@4801: import org.w3c.dom.Node;
ingo@1058: 
ingo@1058: /**
ingo@1058:  * This service provides information about the supported rivers by this
ingo@1058:  * application.
ingo@1058:  *
ingo@1058:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@1058:  */
sascha@2607: public class MapInfoService extends XMLService {
ingo@1058: 
ingo@1058:     /** XPath that points to the river.*/
ingo@1058:     public static final String XPATH_RIVER = "/mapinfo/river/text()";
ingo@1058: 
christian@4810:     public static final String XPATH_MAPTYPE = "/mapinfo/maptype/text()";
christian@4810: 
christian@4810:     private static final String XPATH_RIVER_PROJECTION =
teichmann@4811:         "/artifact-database/*[local-name()=$maptype]/river[@name=$river]/srid/@value";
ingo@1058: 
christian@4810:     private static final String XPATH_RIVER_BACKGROUND =
teichmann@4811:         "/artifact-database/*[local-name()=$maptype]/river[@name=$river]/background-wms";
ingo@1058: 
christian@4810:     private static final String XPATH_RIVER_WMS =
teichmann@4811:         "/artifact-database/*[local-name()=$maptype]/river[@name=$river]/river-wms";
ingo@1058: 
ingo@1058: 
ingo@1058:     /** The logger used in this service.*/
ingo@1058:     private static Logger logger = Logger.getLogger(MapInfoService.class);
ingo@1058: 
ingo@1058: 
ingo@1058:     /**
ingo@1058:      * The default constructor.
ingo@1058:      */
ingo@1058:     public MapInfoService() {
ingo@1058:     }
ingo@1058: 
sascha@2098:     protected static String getStringXPath(
sascha@3076:         String              query,
sascha@2098:         Map<String, String> variables
sascha@2098:     ) {
sascha@2098:         return (String)XMLUtils.xpath(
sascha@2098:             Config.getConfig(), query, XPathConstants.STRING,
sascha@2098:             null, variables);
sascha@2098:     }
sascha@2098: 
sascha@2098:     protected static Node getNodeXPath(
sascha@3076:         String              query,
sascha@2098:         Map<String, String> variables
sascha@2098:     ) {
sascha@2098:         return (Node)XMLUtils.xpath(
sascha@2098:             Config.getConfig(), query, XPathConstants.NODE,
sascha@2098:             null, variables);
sascha@2098:     }
ingo@1058: 
sascha@2607:     @Override
sascha@2607:     public Document processXML(
ingo@1058:         Document      data,
ingo@1058:         GlobalContext globalContext,
ingo@1058:         CallMeta      callMeta
ingo@1058:     ) {
ingo@1058:         logger.debug("MapInfoService.process");
ingo@1058: 
ingo@1058:         Document result   = XMLUtils.newDocument();
ingo@1058:         ElementCreator cr = new ElementCreator(result, null, null);
ingo@1058: 
ingo@1058:         Element mapinfo = cr.create("mapinfo");
ingo@1058:         result.appendChild(mapinfo);
ingo@1058: 
ingo@1058:         String river = extractRiver(data);
ingo@1058:         if (river == null || river.length() == 0) {
ingo@1058:             logger.warn("Cannot generate information: river is empty!");
ingo@1058:             return result;
ingo@1058:         }
ingo@1058: 
teichmann@4811:         String mapType = extractMaptype(data);
teichmann@4811:         if (mapType == null
teichmann@4811:         || !(mapType.equals("floodmap") || mapType.equals("rivermap"))) {
teichmann@4811:             mapType = "floodmap";
teichmann@4811:         }
teichmann@4811: 
ingo@1058:         Element root = cr.create("river");
ingo@1058:         cr.addAttr(root, "name", river);
ingo@1058:         mapinfo.appendChild(root);
ingo@1058: 
ingo@2078:         Envelope env = GeometryUtils.getRiverBoundary(river);
ingo@2078:         if (env != null) {
ingo@2078:             String bounds = GeometryUtils.jtsBoundsToOLBounds(env);
teichmann@4811:             if (logger.isDebugEnabled()) {
teichmann@4811:                 logger.debug("River '" + river + "' bounds: " + bounds);
teichmann@4811:             }
ingo@1058: 
ingo@1058:             Element bbox = cr.create("bbox");
ingo@1058:             cr.addAttr(bbox, "value", bounds);
ingo@1058:             root.appendChild(bbox);
ingo@1058:         }
ingo@1058: 
sascha@2098:         Map<String, String> vars = new HashMap<String, String>();
teichmann@4811:         vars.put("maptype", mapType);
sascha@2098:         vars.put("river", river);
sascha@2098: 
teichmann@4811:         String sridStr = getStringXPath(XPATH_RIVER_PROJECTION, vars);
sascha@2098: 
ingo@1058:         if (sridStr != null && sridStr.length() > 0) {
ingo@1058:             Element srid = cr.create("srid");
ingo@1058:             cr.addAttr(srid, "value", sridStr);
ingo@1058:             root.appendChild(srid);
ingo@1058:         }
ingo@1058: 
teichmann@4811:         if (logger.isDebugEnabled()) {
teichmann@4811:             logger.debug("processXML: " + XMLUtils.toString(root));
teichmann@4811:         }
teichmann@4811: 
christian@4801:         root.appendChild(
teichmann@4811:             createWMSElement("background-wms",
teichmann@4811:                 XPATH_RIVER_BACKGROUND, vars, cr));
teichmann@4811: 
christian@4801:         root.appendChild(
teichmann@4811:             createWMSElement("river-wms",
teichmann@4811:                 XPATH_RIVER_WMS, vars, cr));
christian@4801: 
christian@4801:         return result;
christian@4801:     }
christian@4801: 
christian@4801: 
christian@4801:     protected Element createWMSElement(
teichmann@4811:         String elementName,
teichmann@4811:         String xpath,
teichmann@4811:         Map<String, String> vars,
teichmann@4811:         ElementCreator cr)
christian@4801:     {
christian@4801:         logger.debug("createWMSElement()");
christian@4801: 
christian@4801:         Element el = cr.create(elementName);
christian@4801:         Element wms = (Element)getNodeXPath(xpath, vars);
christian@4801: 
christian@4801:         if (wms != null) {
christian@4801:             cr.addAttr(el, "url", wms.getAttribute("url"));
christian@4801:             cr.addAttr(el, "layers", wms.getAttribute("layers"));
christian@4801: 
christian@4801:             logger.debug("createWMSElement: " + XMLUtils.toString(el));
christian@4801:         }
christian@4801:         else {
christian@4801:             logger.debug("createWMSElement: wms == null");
ingo@1058:         }
ingo@1058: 
christian@4801:         return el;
ingo@1058:     }
ingo@1058: 
ingo@1058: 
teichmann@4811:     private static String extractRiver(Document data) {
ingo@1058:         return XMLUtils.xpathString(
ingo@1058:             data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE);
ingo@1058:     }
christian@4810: 
teichmann@4811:     private static String extractMaptype(Document data) {
christian@4810:         return XMLUtils.xpathString(
christian@4810:             data, XPATH_MAPTYPE, ArtifactNamespaceContext.INSTANCE);
christian@4810:     }
ingo@1058: }
ingo@1058: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :