ingo@1022: /*
ingo@1022: * Copyright (c) 2010 by Intevation GmbH
ingo@1022: *
ingo@1022: * This program is free software under the LGPL (>=v2.1)
ingo@1022: * Read the file LGPL.txt coming with the software for details
ingo@1022: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@1022: */
ingo@1022:
tim@402: package de.intevation.gnv.action.mapviewer.parser;
tim@402:
tim@953: import java.io.InputStream;
tim@953: import java.util.ArrayList;
tim@953: import java.util.Collection;
tim@953:
tim@953: import org.apache.log4j.Logger;
tim@953: import org.w3c.dom.Document;
tim@953: import org.w3c.dom.Element;
tim@953: import org.w3c.dom.NodeList;
tim@953:
tim@402: import de.intevation.gnv.artifactdatabase.objects.map.DefaultLayer;
tim@402: import de.intevation.gnv.artifactdatabase.objects.map.DefaultMapService;
tim@402: import de.intevation.gnv.artifactdatabase.objects.map.Layer;
tim@402: import de.intevation.gnv.artifactdatabase.objects.map.MapService;
tim@402: import de.intevation.gnv.util.XMLUtils;
tim@402:
tim@402: /**
tim@953: * This class provides an XMl-Parser which try's to create an DOM from
tim@953: * an given Inputstream. Is this is possible it try to read the required
tim@953: * informations e.g. Mapservices, Layer, SRID and Geometry from the
tim@953: * document.
sascha@684: * @author Tim Englich
tim@402: */
tim@402: public class XMLExternalCallParser implements ExternalCallParser {
sascha@681:
tim@402: /**
tim@402: * the logger, used to log exceptions and additonaly information
tim@402: */
tim@402: private static Logger log = Logger.getLogger(XMLExternalCallParser.class);
sascha@681:
tim@402: private static String XPATH_GEOMETRY = "/gnviewer/location/data";
tim@402: private static String XPATH_SRS = "/gnviewer/location/srs";
tim@402: private static String XPATH_MAPSERVICES_NODESET = "/gnviewer/mapservices/mapservice";
tim@402: private static String XPATH_LAYER = "layer";
tim@402: private static String ATTRIBUTE_ID = "id";
tim@402: private static String ATTRIBUTE_NAME = "name";
tim@402: private static String ATTRIBUTE_TYPE = "type";
tim@402: private static String ATTRIBUTE_URL = "url";
sascha@681:
tim@953: /**
tim@953: * The geometry which was parsed from the document.
tim@953: */
tim@402: private String geometry = null;
tim@953:
tim@953: /**
tim@953: * The srid which was parsed from the document.
tim@953: */
tim@402: private String srs = null;
sascha@681:
tim@953: /**
tim@953: * The mapservices that were parsed from the document.
tim@953: */
tim@402: private Collection mapServices = null;
sascha@681:
tim@953: /**
tim@953: * The inputstream where the data should be read from.
tim@953: */
tim@402: private InputStream inputStream = null;
tim@402:
tim@402: /**
tim@402: * Constructor
tim@953: * @param inputStream The stream where the data should be read from
tim@402: */
tim@402: public XMLExternalCallParser(InputStream inputStream) {
tim@402: this.inputStream = inputStream;
tim@402: }
tim@402:
tim@402: public String getGeometry() {
tim@402: return this.geometry;
tim@402: }
tim@402:
tim@402: public Collection getMapServices() {
tim@402: return this.mapServices;
tim@402: }
tim@402:
tim@402: public void parse() throws ExternalCallParserException {
tim@402: if (inputStream != null){
tim@402: XMLUtils xmlUtils = new XMLUtils();
tim@402: Document document = xmlUtils.readDocument(this.inputStream);
tim@402: if (document != null){
sascha@681:
tim@953: this.geometry = xmlUtils.getStringXPath(document,
tim@953: XPATH_GEOMETRY);
tim@402: this.srs = xmlUtils.getStringXPath(document, XPATH_SRS);
sascha@681: NodeList mapservicesNodes =
tim@953: xmlUtils.getNodeSetXPath(document,
tim@953: XPATH_MAPSERVICES_NODESET);
tim@402: if (mapservicesNodes != null){
tim@402: this.mapServices = new ArrayList(mapservicesNodes.getLength());
tim@402: for (int i = 0; i < mapservicesNodes.getLength(); i++){
tim@402: Element mapserviceNode = (Element)mapservicesNodes.item(i);
tim@402: String mapserviceID = mapserviceNode.getAttribute(ATTRIBUTE_ID);
tim@402: String mapserviceType = mapserviceNode.getAttribute(ATTRIBUTE_TYPE);
tim@402: String mapserviceUrl = mapserviceNode.getAttribute(ATTRIBUTE_URL);
tim@402: NodeList layerNodes = xmlUtils.getNodeSetXPath(mapserviceNode, XPATH_LAYER);
tim@402: Collection layer = null;
tim@402: if (layerNodes != null && layerNodes.getLength() > 0){
tim@402: layer = new ArrayList(layerNodes.getLength());
tim@402: layer = this.extractLayer(layer, null, layerNodes);
tim@402: }else{
tim@402: log.debug("No Layer given for this Mapservice");
tim@402: }
sascha@681: MapService mapService =
tim@402: new DefaultMapService(mapserviceID, layer,
tim@402: mapserviceType, mapserviceUrl);
tim@402: this.mapServices.add(mapService);
tim@402: }
sascha@681:
tim@402: }else{
tim@953: String errMsg = "XML-Document does not contain any " +
tim@953: "Mapservices which are required.";
tim@402: log.error(errMsg);
tim@402: throw new ExternalCallParserException(errMsg);
tim@402: }
sascha@681:
tim@402: }else{
tim@953: String errMsg = "XML-Document could not " +
tim@953: "be read from InputStream.";
tim@402: log.error(errMsg);
tim@402: throw new ExternalCallParserException(errMsg);
tim@402: }
tim@402: }else{
tim@402: String errMsg = "No InputStream given for parsing the Call.";
tim@402: log.error(errMsg);
tim@402: throw new ExternalCallParserException(errMsg);
tim@402: }
tim@402: }
sascha@681:
tim@402: /**
tim@402: * This Method extracts all Layers and put them into the Collection.
tim@953: * @param layer the collection where the layer should be add to.
tim@953: * @param groupId the id of the group of the layers
tim@953: * @param layerNodes the Nodes which should contain the intormations
tim@953: * about layers
tim@953: * @return the layer
tim@402: */
tim@953: private Collection extractLayer(Collection layer,
tim@953: String groupId,
tim@953: NodeList layerNodes){
tim@402: for (int i = 0; i < layerNodes.getLength(); i++){
tim@402: Element layerNode = (Element)layerNodes.item(i);
tim@402: String id = layerNode.getAttribute(ATTRIBUTE_ID);
tim@402: String name = layerNode.getAttribute(ATTRIBUTE_NAME);
tim@953: NodeList localLayerNodes = XMLUtils.getNodeSetXPath(layerNode,
tim@953: XPATH_LAYER);
sascha@681: Layer tmpLayer = new DefaultLayer(id, name,
sascha@681: (localLayerNodes != null &&
sascha@681: localLayerNodes.getLength() > 0),
tim@402: groupId);
tim@402: layer.add(tmpLayer);
tim@402: if (localLayerNodes != null && localLayerNodes.getLength() > 0){
tim@402: layer = this.extractLayer(layer, id, localLayerNodes);
tim@402: }
tim@402: }
tim@402: return layer;
tim@402: }
tim@402:
tim@402: public String getSRS() {
tim@402: return this.srs;
tim@402: }
tim@402:
tim@402: }