view gwt-client/src/main/java/org/dive4elements/river/client/server/CapabilitiesParser.java @ 5948:d7b9b3e3c61a

Make instantiation of saml.User easier. Most of the parameters of the constructor can be taken from the Assertion object, so there's no reason to pass them separately. Also, trying to check the validity dates isn't useful for the single sign on case. See comments in the hasExpired method.
author Bernhard Herzog <bh@intevation.de>
date Wed, 08 May 2013 17:56:14 +0200
parents 172338b1407f
children ea9eef426962
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3) 
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details. 
 */

package org.dive4elements.river.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 org.dive4elements.artifacts.common.utils.XMLUtils;

import org.dive4elements.river.client.shared.exceptions.ServerException;
import org.dive4elements.river.client.shared.model.Capabilities;
import org.dive4elements.river.client.shared.model.ContactInformation;
import org.dive4elements.river.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