Mercurial > mxd2map
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 :