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: }