changeset 27:e5fdc37f8f94

Added XMLUtils to store map information.
author Raimund Renkert <rrenkert@intevation.de>
date Fri, 08 Apr 2011 14:21:45 +0200
parents 3e24fffdf2bb
children 0e71a1f71ec0
files ChangeLog src/java/de/intevation/mxd/reader/IReader.java src/java/de/intevation/mxd/reader/MXDReader.java src/java/de/intevation/mxd/reader/MapReader.java src/java/de/intevation/mxd/utils/XMLUtils.java
diffstat 5 files changed, 432 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Apr 08 12:26:17 2011 +0200
+++ b/ChangeLog	Fri Apr 08 14:21:45 2011 +0200
@@ -1,3 +1,17 @@
+2011-04-08  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/java/de/intevation/mxd/reader/IReader.java: Added XML document to
+	  store map information.
+
+	* src/java/de/intevation/mxd/reader/MXDReader.java: Write the information to
+	  the XML document.
+
+	* src/java/de/intevation/mxd/reader/MapReader.java: Write map information to
+	  the XML document.
+
+	* src/java/de/intevation/mxd/utils/XMLUtils.java: New. Helper class to
+	  create and manipulate XML documents.
+
 2011-04-08  Raimund Renkert <raimund.renkert@intevation.de>
 
 	Moved reader components to reader folder.
--- a/src/java/de/intevation/mxd/reader/IReader.java	Fri Apr 08 12:26:17 2011 +0200
+++ b/src/java/de/intevation/mxd/reader/IReader.java	Fri Apr 08 14:21:45 2011 +0200
@@ -2,6 +2,8 @@
 
 import java.io.IOException;
 
+import org.w3c.dom.Document;
+
 /**
  * The interface to the MXD-Reader.
  *
@@ -31,6 +33,6 @@
     /**
      * Request DOM Document containing the map data.
      */
-    void getMapDocument();
+    Document getMapDocument();
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/src/java/de/intevation/mxd/reader/MXDReader.java	Fri Apr 08 12:26:17 2011 +0200
+++ b/src/java/de/intevation/mxd/reader/MXDReader.java	Fri Apr 08 14:21:45 2011 +0200
@@ -21,6 +21,9 @@
 import com.esri.arcgis.geometry.IProjection;
 import com.esri.arcgis.geometry.Projection;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
 /**
  * The MXD file reader.
  *
@@ -32,6 +35,7 @@
     private String filename = "";
     private ArcGISInitializer initializer = null;
     private IMap map;
+    private Document mapInfo;
 
     private static final Logger logger = Logger.getLogger(MXDReader.class);
 
@@ -39,6 +43,7 @@
     public MXDReader() throws IOException{
         logger.debug("constructor()");
         initializer = new ArcGISInitializer();
+        mapInfo = XMLUtils.newDocument();
     }
 
 
@@ -76,6 +81,15 @@
         filename = name;
     }
 
+
+    private void openMapDocument() throws IOException{
+        MapDocument m = new MapDocument();
+        if(!m.isMapDocument(filename)){
+            throw new IOException(filename + " is not a map!");
+        }
+        m.open(filename, null);
+        map = m.getMap(0);
+    }
     /**
      * Read the MXD file content.
      */
@@ -85,22 +99,19 @@
             throw new IOException("Please set filename!");
         }
         else{
-            MapDocument m = new MapDocument();
-            if(!m.isMapDocument(filename)){
-                throw new IOException(filename + " is not a map!");
-            }
-            m.open(filename, null);
-            map = m.getMap(0);
+            openMapDocument();
             MapReader mreader = new MapReader (map);
+            mreader.setDocument(mapInfo);
             mreader.read();
+
             for(int i = 0; i < map.getLayerCount();i++){
-                ILayer layer = map.getLayer(0);
-                ILayerReader lr = new FeatureLayerReader(layer);
-                lr.read();
-                if (layer instanceof FeatureLayer){
-                    IFeatureRenderer renderer = ((FeatureLayer)layer).getRenderer();
-                    IRendererReader rreader;
-                    try{
+                ILayer layer = map.getLayer(i);
+                try{
+                    ILayerReader lr = new FeatureLayerReader(layer);
+                    lr.read();
+                    if (layer instanceof FeatureLayer){
+                        IFeatureRenderer renderer = ((FeatureLayer)layer).getRenderer();
+                        IRendererReader rreader;
                         if(renderer instanceof SimpleRenderer){
                             rreader = new SimpleRendererReader(renderer);
                             rreader.read();
@@ -119,20 +130,22 @@
                                                renderer.getClass().toString());
                         }
                     }
-                    catch(Exception e){
-                        e.printStackTrace();
-                    }
+                }
+                catch(Exception e){
+                    e.printStackTrace();
                 }
             }
         }
         return true;
     }
 
+
     /**
      * Get the mapinformation as DOM document. TODO: implement me!
      */
-    public void getMapDocument(){
-        logger.debug("getMapDocument() -> not implemented jet.");
+    public Document getMapDocument(){
+        logger.debug("getMapDocument()");
+        return mapInfo;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/src/java/de/intevation/mxd/reader/MapReader.java	Fri Apr 08 12:26:17 2011 +0200
+++ b/src/java/de/intevation/mxd/reader/MapReader.java	Fri Apr 08 14:21:45 2011 +0200
@@ -11,6 +11,10 @@
 import com.esri.arcgis.geometry.GeographicCoordinateSystem;
 import com.esri.arcgis.geometry.IProjection;
 import com.esri.arcgis.geometry.Projection;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
 /**
  * Reads map information.
  *
@@ -19,7 +23,8 @@
 public class MapReader{
 
     //Member
-    IMap map;
+    private IMap map;
+    private Document document;
 
     private static final Logger logger = Logger.getLogger(MapReader.class);
 
@@ -37,17 +42,32 @@
      */
     public void read() throws IOException{
         logger.debug("read()");
+        if(document == null)
+            throw new IOException("Can not write to document.");
+
+        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(document,
+                                                                      "", "");
+        Element mapElement = creator.create("map");
         ISpatialReference sr = map.getSpatialReference();
         logger.debug("Instance: " + sr.getClass().toString());
         if(sr instanceof ProjectedCoordinateSystem){
             ProjectedCoordinateSystem pcs = (ProjectedCoordinateSystem)sr;
             Projection p = (Projection)pcs.getProjection();
-            System.out.println("Projection       = " + p.getName());
+            creator.addAttr(mapElement, "projection", p.getName());
         }
         else if(sr instanceof GeographicCoordinateSystem){
             GeographicCoordinateSystem gcs = (GeographicCoordinateSystem)sr;
-            System.out.println("Name             = " + gcs.getName());
+            creator.addAttr(mapElement, "projection", gcs.getName());
         }
+        else{
+            throw new IOException("Unknown SpatialReference: " +
+                                  sr.getClass().toString());
+        }
+        document.appendChild(mapElement);
+    }
+
+    public void setDocument(Document doc){
+        this.document = doc;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java/de/intevation/mxd/utils/XMLUtils.java	Fri Apr 08 14:21:45 2011 +0200
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2010 by Intevation GmbH
+ *
+ * This program is free software under the LGPL (>=v2.1)
+ * Read the file LGPL.txt coming with the software for details
+ * or visit http://www.gnu.org/licenses/ if it does not exist.
+ */
+
+//package de.intevation.mxd.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import javax.xml.transform.dom.DOMSource;
+
+import javax.xml.transform.stream.StreamResult;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Some helper functions to ease work with XML concering namespaces, XPATH
+ * and so on.
+ *  @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
+ */
+public final class XMLUtils
+{
+    /**
+     * W3C URL of XForms
+     */
+    public static final String XFORM_URL    = "http://www.w3.org/2002/xforms";
+    /**
+     * W3C prefix of XForms
+     */
+    public static final String XFORM_PREFIX = "xform";
+
+    private static Logger logger = Logger.getLogger(XMLUtils.class);
+
+    private XMLUtils() {
+    }
+
+    /**
+     * Helper class to generate elements and attributes with
+     * namespaces.
+     */
+    public static class ElementCreator
+    {
+        /**
+         * owner document of the elements to be created
+         */
+        protected Document document;
+        /**
+         * namespace to be used
+         */
+        protected String   ns;
+        /**
+         * prefix to be used
+         */
+        protected String   prefix;
+
+        /**
+         * Constructor to create an element/attribute creator
+         * with a given namespace and namespace prefix using a
+         * given owner document.
+         * @param document The owning document
+         * @param ns       The namespace
+         * @param prefix   The namespace prefix
+         */
+        public ElementCreator(Document document, String ns, String prefix) {
+            this.document = document;
+            this.ns       = ns;
+            this.prefix   = prefix;
+        }
+
+        /**
+         * Creates a new element using the owning document with
+         * the this creators namespace and namespace prefix.
+         * @param name The name of the element
+         * @return     The new element
+         */
+        public Element create(String name) {
+            Element element = document.createElementNS(ns, name);
+            element.setPrefix(prefix);
+            return element;
+        }
+
+        /**
+         * Adds a new attribute and its value to a given element.
+         * It does not set the namespace prefix.
+         * @param element The element to add the attribute to
+         * @param name    The name of the attribute
+         * @param value   The value of the attribute
+         */
+        public void addAttr(Element element, String name, String value) {
+            addAttr(element, name, value, false);
+        }
+
+        /**
+         * Adds a new attribute and its value to a given element.
+         * If the namespace prefix is used is decided by the 'addPrefix' flag.
+         * @param element The element to add the attribute to
+         * @param name    The name of the attribute
+         * @param value   The value of the attribute
+         * @param addPrefix If true the creators namespace prefix is
+         * set on the attribute.
+         */
+        public void addAttr(
+            Element element,
+            String  name,
+            String  value,
+            boolean addPrefix
+        ) {
+            if (addPrefix) {
+                Attr attr = document.createAttributeNS(ns, name);
+                attr.setValue(value);
+                attr.setPrefix(prefix);
+
+                element.setAttributeNode(attr);
+            }
+            else {
+                element.setAttribute(name, value);
+            }
+
+        }
+    } // class ElementCreator
+
+    /**
+     * Creates a new XML document
+     * @return the new XML document ot null if something went wrong during
+     * creation.
+     */
+    public static final Document newDocument() {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+
+        try {
+            return factory.newDocumentBuilder().newDocument();
+        }
+        catch (ParserConfigurationException pce) {
+            logger.error(pce.getLocalizedMessage(), pce);
+        }
+        return null;
+    }
+
+    /**
+     * Loads a XML document namespace aware from a file
+     * @param file The file to load.
+     * @return the XML document or null if something went wrong
+     * during loading.
+     */
+    public static final Document parseDocument(File file) {
+        InputStream inputStream = null;
+        try {
+            inputStream = new BufferedInputStream(new FileInputStream(file));
+            return parseDocument(inputStream);
+        }
+        catch (IOException ioe) {
+            logger.error(ioe.getLocalizedMessage(), ioe);
+        }
+        finally {
+            if (inputStream != null) {
+                try { inputStream.close(); }
+                catch (IOException ioe) {}
+            }
+        }
+        return null;
+    }
+
+    public static final Document parseDocument(InputStream inputStream) {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+
+        try {
+            return factory.newDocumentBuilder().parse(inputStream);
+        }
+        catch (ParserConfigurationException pce) {
+            logger.error(pce.getLocalizedMessage(), pce);
+        }
+        catch (SAXException se) {
+            logger.error(se.getLocalizedMessage(), se);
+        }
+        catch (IOException ioe) {
+            logger.error(ioe.getLocalizedMessage(), ioe);
+        }
+        return null;
+    }
+
+    /**
+     * Creates a new XPath without a namespace context.
+     * @return the new XPath.
+     */
+    public static final XPath newXPath() {
+        return newXPath(null);
+    }
+
+    /**
+     * Creates a new XPath with a given namespace context.
+     * @param namespaceContext The namespace context to be used or null
+     * if none should be used.
+     * @return The new XPath
+     */
+    public static final XPath newXPath(NamespaceContext namespaceContext) {
+        XPathFactory factory = XPathFactory.newInstance();
+        XPath        xpath   = factory.newXPath();
+        if (namespaceContext != null) {
+            xpath.setNamespaceContext(namespaceContext);
+        }
+        return xpath;
+    }
+
+    /**
+     * Evaluates an XPath query on a given object and returns the result
+     * as a given type. No namespace context is used.
+     * @param root  The object which is used as the root of the tree to
+     * be searched in.
+     * @param query The XPath query
+     * @param returnTyp The type of the result.
+     * @return The result of type 'returnTyp' or null if something
+     * went wrong during XPath evaluation.
+     */
+    public static final Object xpath(
+        Object root,
+        String query,
+        QName  returnTyp
+    ) {
+        return xpath(root, query, returnTyp, null);
+    }
+
+    /**
+     * Evaluates an XPath query on a given object and returns the result
+     * as a string. A given namespace context is used.
+     * @param root  The object which is used as the root of the tree to
+     * be searched in.
+     * @param query The XPath query
+     * @param namespaceContext The namespace context to be used or null
+     * if none should be used.
+     * @return The result of the query or null if something went wrong
+     * during XPath evaluation.
+     */
+    public static final String xpathString(
+        Object root, String query, NamespaceContext namespaceContext
+    ) {
+        return (String)xpath(
+            root, query, XPathConstants.STRING, namespaceContext);
+    }
+
+    /**
+     * Evaluates an XPath query on a given object and returns the result
+     * as a given type. Optionally a namespace context is used.
+     * @param root The object which is used as the root of the tree to
+     * be searched in.
+     * @param query The XPath query
+     * @param returnType The type of the result.
+     * @param namespaceContext The namespace context to be used or null
+     * if none should be used.
+     * @return The result of type 'returnTyp' or null if something
+     * went wrong during XPath evaluation.
+     */
+    public static final Object xpath(
+        Object           root,
+        String           query,
+        QName            returnType,
+        NamespaceContext namespaceContext
+    ) {
+        if (root == null) {
+            return null;
+        }
+
+        try {
+            XPath xpath = newXPath(namespaceContext);
+            if (xpath != null) {
+                return xpath.evaluate(query, root, returnType);
+            }
+        }
+        catch (XPathExpressionException xpee) {
+            logger.error(xpee.getLocalizedMessage(), xpee);
+        }
+
+        return null;
+    }
+
+    /**
+     * Streams out an XML document to a given output stream.
+     * @param document The document to be streamed out.
+     * @param out      The output stream to be used.
+     * @return true if operation succeeded else false.
+     */
+    public static boolean toStream(Document document, OutputStream out) {
+        try {
+            Transformer transformer =
+                TransformerFactory.newInstance().newTransformer();
+            DOMSource    source = new DOMSource(document);
+            StreamResult result = new StreamResult(out);
+            transformer.transform(source, result);
+            return true;
+        }
+        catch (TransformerConfigurationException tce) {
+            logger.error(tce.getLocalizedMessage(), tce);
+        }
+        catch (TransformerFactoryConfigurationError tfce) {
+            logger.error(tfce.getLocalizedMessage(), tfce);
+        }
+        catch (TransformerException te) {
+            logger.error(te.getLocalizedMessage(), te);
+        }
+
+        return false;
+    }
+
+    /**
+     * Transforms an XML document into a byte array.
+     * @param document The document to be streamed out.
+     * @return the byte array or null if operation failed or
+     * document is null.
+     */
+    public static byte [] toByteArray(Document document) {
+        if (document == null) {
+            return null;
+        }
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        return toStream(document, baos)
+            ? baos.toByteArray()
+            : null;
+    }
+
+    public static Document fromByteArray(byte [] data) {
+        if (data == null) {
+            return null;
+        }
+        return parseDocument(new ByteArrayInputStream(data));
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)