view flys-client/src/main/java/de/intevation/flys/client/server/CapabilitiesParser.java @ 5818:a4ff4167be1e

Request feature info on all layers and show it as html if the server does not return valid gml. Non queryable layers produce an error message when the request fails. This is good enough
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 24 Apr 2013 17:33:27 +0200
parents 40d02fbf414d
children
line wrap: on
line source
package de.intevation.flys.client.server;

import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.xpath.XPathConstants;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.apache.log4j.Logger;

import de.intevation.artifacts.common.utils.XMLUtils;

import de.intevation.flys.client.shared.exceptions.ServerException;
import de.intevation.flys.client.shared.model.Capabilities;
import de.intevation.flys.client.shared.model.ContactInformation;
import de.intevation.flys.client.shared.model.WMSLayer;


public class CapabilitiesParser {

    private static final Logger logger =
        Logger.getLogger(CapabilitiesParser.class);


    public static final String ERR_GC_REQUEST_FAILED =
        "error_gc_req_failed";

    public static final String ERR_GC_DOC_NOT_VALID =
        "error_gc_doc_not_valid";

    public static final String ERR_MALFORMED_URL =
        "error_malformed_url";


    public static final String XPATH_WMS_CAPS =
        "/WMS_Capabilities";

    public static final String XPATH_WMT_CAPS =
        "/WMT_MS_Capabilities";

    public static final String XPATH_TITLE =
        "Service/Title/text()";

    public static final String XPATH_ONLINE_RESOURCE =
        "Service/OnlineResource/@href";

    public static final String XPATH_CONTACT_INFORMATION =
        "Service/ContactInformation";

    public static final String XPATH_CI_PERSON =
        "ContactPersonPrimary/ContactPerson/text()";

    public static final String XPATH_CI_ORGANIZATION =
        "ContactPersonPrimary/ContactOrganization/text()";

    public static final String XPATH_CI_ADDRESS =
        "ContactAddress/Address/text()";

    public static final String XPATH_CI_CITY =
        "ContactAddress/City/text()";

    public static final String XPATH_CI_POSTCODE =
        "ContactAddress/PostCode/text()";

    public static final String XPATH_CI_PHONE =
        "ContactVoiceTelephone/text()";

    public static final String XPATH_CI_EMAIL =
        "ContactElectronicMailAddress/text()";

    public static final String XPATH_FEES =
        "Service/Fees/text()";

    public static final String XPATH_ACCESS_CONSTRAINTS =
        "Service/AccessConstraints/text()";

    public static final String XPATH_LAYERS =
        "Capability/Layer";

    public static final Pattern SRS_PATTERN = Pattern.compile("(EPSG:\\d+)*");


    private CapabilitiesParser() {
    }


    public static void main(String[] args) {
        logger.info("Do static Capabilities request/parsing.");

        String log4jProperties = System.getenv(BaseServletContextListener.LOG4J_PROPERTIES);
        LoggingConfigurator.init(log4jProperties);

        try {
            Capabilities caps = getCapabilities(System.getProperty("test.wms"));

            logger.debug(caps.toString());
        }
        catch (ServerException se) {
            se.printStackTrace();
        }

        logger.info("Finished fetching capabiltiies.");
    }


    public static Capabilities getCapabilities(String urlStr)
    throws ServerException
    {
        try {
            URL url = new URL(urlStr);

            logger.debug("Open connection to url: " + urlStr);

            URLConnection conn = url.openConnection();
            conn.connect();

            InputStream is = conn.getInputStream();

            return parse(is);
        }
        catch (MalformedURLException mue) {
            logger.warn(mue, mue);
            throw new ServerException(ERR_MALFORMED_URL);
        }
        catch (IOException ioe) {
            logger.warn(ioe, ioe);
        }

        throw new ServerException(ERR_GC_REQUEST_FAILED);
    }


    protected static Capabilities parse(InputStream is)
    throws ServerException
    {
        logger.debug("GCServiceImpl.parseCapabilitiesResponse");

        Document doc = XMLUtils.parseDocument(is, false);

        if (doc == null) {
            throw new ServerException(ERR_GC_DOC_NOT_VALID);
        }

        return CapabilitiesParser.parse(doc);
    }


    public static Capabilities parse(Document doc)
    throws ServerException
    {
        Node capabilities = getCapabilitiesNode(doc);

        String title = (String) XMLUtils.xpath(
            capabilities,
            XPATH_TITLE,
            XPathConstants.STRING);

        String onlineResource = (String) XMLUtils.xpath(
            capabilities,
            XPATH_ONLINE_RESOURCE,
            XPathConstants.STRING);

        String fees = (String) XMLUtils.xpath(
            capabilities,
            XPATH_FEES,
            XPathConstants.STRING);

        String accessConstraints = (String) XMLUtils.xpath(
            capabilities,
            XPATH_ACCESS_CONSTRAINTS,
            XPathConstants.STRING);

        Node contactInformation = (Node) XMLUtils.xpath(
            capabilities,
            XPATH_CONTACT_INFORMATION,
            XPathConstants.NODE);

        ContactInformation ci = parseContactInformation(contactInformation);

        logger.debug("Found fees: " + fees);
        logger.debug("Found access constraints: " + accessConstraints);

        NodeList layerNodes = (NodeList) XMLUtils.xpath(
            capabilities,
            XPATH_LAYERS,
            XPathConstants.NODESET);

        List<WMSLayer> layers = parseLayers(layerNodes, onlineResource);

        return new Capabilities(
            title,
            onlineResource,
            ci,
            fees,
            accessConstraints,
            layers);
    }


    protected static Node getCapabilitiesNode(Document doc)
    throws ServerException {
        Node capabilities = (Node) XMLUtils.xpath(
            doc,
            XPATH_WMS_CAPS,
            XPathConstants.NODE);

        if (capabilities == null) {
            logger.info("No '/WMS_Capabilities' node found.");
            logger.info("Try to find a '/WMT_MS_Capabilities' node.");

            capabilities = (Node) XMLUtils.xpath(
                doc,
                XPATH_WMT_CAPS,
                XPathConstants.NODE);
        }

        if (capabilities == null) {
            throw new ServerException(ERR_GC_DOC_NOT_VALID);
        }

        return capabilities;
    }


    protected static ContactInformation parseContactInformation(Node node) {
        String person = (String) XMLUtils.xpath(
            node,
            XPATH_CI_PERSON,
            XPathConstants.STRING);

        String organization = (String) XMLUtils.xpath(
            node,
            XPATH_CI_ORGANIZATION,
            XPathConstants.STRING);

        String address = (String) XMLUtils.xpath(
            node,
            XPATH_CI_ADDRESS,
            XPathConstants.STRING);

        String postcode = (String) XMLUtils.xpath(
            node,
            XPATH_CI_POSTCODE,
            XPathConstants.STRING);

        String city = (String) XMLUtils.xpath(
            node,
            XPATH_CI_CITY,
            XPathConstants.STRING);

        String phone = (String) XMLUtils.xpath(
            node,
            XPATH_CI_PHONE,
            XPathConstants.STRING);

        String email = (String) XMLUtils.xpath(
            node,
            XPATH_CI_EMAIL,
            XPathConstants.STRING);

        ContactInformation ci = new ContactInformation();
        ci.setPerson(person);
        ci.setOrganization(organization);
        ci.setAddress(address);
        ci.setPostcode(postcode);
        ci.setCity(city);
        ci.setPhone(phone);
        ci.setEmail(email);

        return ci;
    }


    /**
     * @param layersNode
     * @param onlineResource
     *
     * @return
     */
    protected static List<WMSLayer> parseLayers(
        NodeList layersNode,
        String   onlineResource
    ) {
        int len = layersNode != null ? layersNode.getLength() : 0;

        logger.debug("Node has " + len + " layers.");

        List<WMSLayer> layers = new ArrayList<WMSLayer>(len);

        for (int i = 0; i < len; i++) {
            layers.add(parseLayer(layersNode.item(i), onlineResource));
        }

        return layers;
    }


    protected static WMSLayer parseLayer(Node layerNode, String onlineResource) {
        String title = (String) XMLUtils.xpath(
            layerNode,
            "Title/text()",
            XPathConstants.STRING);

        String name = (String) XMLUtils.xpath(
            layerNode,
            "Name/text()",
            XPathConstants.STRING);

        logger.debug("Found layer: " + title + "(" + name + ")");

        List<String> srs = parseSRS(layerNode);

        NodeList layersNodes = (NodeList) XMLUtils.xpath(
            layerNode,
            "Layer",
            XPathConstants.NODESET);

        List<WMSLayer> layers = parseLayers(layersNodes, onlineResource);

        return new WMSLayer(onlineResource, title, name, srs, layers);
    }


    protected static List<String> parseSRS(Node layerNode) {
        NodeList srsNodes = ((Element) layerNode).getElementsByTagName("SRS");

        if (srsNodes.getLength() == 0) {
            srsNodes = ((Element) layerNode).getElementsByTagName("CRS");

            if (srsNodes.getLength() == 0) {
                logger.debug("No explicit SRS for this layer specified.");
                return null;
            }
        }

        List<String> allSRS = new ArrayList<String>();

        for (int i = 0, n = srsNodes.getLength(); i < n; i++) {
            List<String> srs = parseSRSItem(srsNodes.item(i).getTextContent());

            if (srs != null && srs.size() > 0) {
                allSRS.addAll(srs);
            }
        }

        return allSRS;
    }


    protected static List<String> parseSRSItem(String srsStr) {
        if (srsStr == null || srsStr.length() == 0) {
            return null;
        }

        List<String> allSRS = new ArrayList<String>();

        if (srsStr.indexOf(" ") <= 0) {
            String srs = getSRSFromString(srsStr);
            if (srs != null && srs.length() > 0) {
                allSRS.add(srs);
            }

            return allSRS;
        }

        String[] splittedSrs = srsStr.split(" ");

        for (String singleSrs: splittedSrs) {
            String srs = getSRSFromString(singleSrs);
            if (srs != null && srs.length() > 0) {
                allSRS.add(srs);
            }
        }

        return allSRS;
    }


    protected static String getSRSFromString(String singleSrs) {
        Matcher m = SRS_PATTERN.matcher(singleSrs);

        if (m.matches()) {
            logger.debug("Found SRS '" + m.group(1) + "'");
            return m.group(1);
        }

        return null;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org