You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2013/02/23 20:52:13 UTC

svn commit: r1449399 - in /commons/proper/configuration/trunk/src: changes/changes.xml main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java

Author: oheger
Date: Sat Feb 23 19:52:12 2013
New Revision: 1449399

URL: http://svn.apache.org/r1449399
Log:
[CONFIGURATION-526] XMLPropertiesConfiguration now supports loading from and saving to DOM nodes. Thanks to Oliver Kopp for the patch.

Modified:
    commons/proper/configuration/trunk/src/changes/changes.xml
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java

Modified: commons/proper/configuration/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/changes/changes.xml?rev=1449399&r1=1449398&r2=1449399&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/changes/changes.xml (original)
+++ commons/proper/configuration/trunk/src/changes/changes.xml Sat Feb 23 19:52:12 2013
@@ -27,6 +27,10 @@
   <body>
     <release version="2.0" date="in SVN"
       description="TBD">
+      <action dev="oheger" type="update" issue="CONFIGURATION-526" due-to="Oliver Kopp">
+        XMLPropertiesConfiguration now supports loading from and saving to DOM
+        nodes.
+      </action>
       <action dev="oheger" type="update" issue="CONFIGURATION-521" due-to="Oliver Kopp">
         ConfigurationUtils.fileFromUrl() now correctly handles URL containing
         encoded percent characters.

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java?rev=1449399&r1=1449398&r2=1449399&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java Sat Feb 23 19:52:12 2013
@@ -30,6 +30,10 @@ import javax.xml.parsers.SAXParserFactor
 
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.Attributes;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
@@ -73,6 +77,11 @@ public class XMLPropertiesConfiguration 
      */
     private static final String DEFAULT_ENCODING = "UTF-8";
 
+    /**
+     * Default string used when the XML is malformed
+     */
+    private static final String MALFORMED_XML_EXCEPTION = "Malformed XML";
+
     // initialization block to set the encoding before loading the file in the constructors
     {
         setEncoding(DEFAULT_ENCODING);
@@ -129,6 +138,19 @@ public class XMLPropertiesConfiguration 
         super(url);
     }
 
+    /**
+     * Creates and loads the xml properties from the specified DOM node.
+     *
+     * @param element The DOM element
+     * @throws ConfigurationException Error while loading the properties file
+     * @since 2.0
+     */
+    public XMLPropertiesConfiguration(Element element) throws ConfigurationException
+    {
+        super();
+        this.load(element);
+    }
+
     @Override
     public void load(Reader in) throws ConfigurationException
     {
@@ -159,6 +181,44 @@ public class XMLPropertiesConfiguration 
         // todo: support included properties ?
     }
 
+    /**
+     * Parses a DOM element containing the properties. The DOM element has to follow
+     * the XML properties format introduced in Java 5.0,
+     * see http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html
+     *
+     * @param element The DOM element
+     * @throws ConfigurationException Error while interpreting the DOM
+     * @since 2.0
+     */
+    public void load(Element element) throws ConfigurationException
+    {
+        if (!element.getNodeName().equals("properties"))
+        {
+            throw new ConfigurationException(MALFORMED_XML_EXCEPTION);
+        }
+        NodeList childNodes = element.getChildNodes();
+        for (int i = 0; i < childNodes.getLength(); i++)
+        {
+            Node item = childNodes.item(i);
+            if (item instanceof Element)
+            {
+                if (item.getNodeName().equals("comment"))
+                {
+                    setHeader(item.getTextContent());
+                }
+                else if (item.getNodeName().equals("entry"))
+                {
+                    String key = ((Element) item).getAttribute("key");
+                    addProperty(key, item.getTextContent());
+                }
+                else
+                {
+                    throw new ConfigurationException(MALFORMED_XML_EXCEPTION);
+                }
+            }
+        }
+    }
+
     @Override
     public void save(Writer out) throws ConfigurationException
     {
@@ -236,6 +296,67 @@ public class XMLPropertiesConfiguration 
     }
 
     /**
+     * Writes the configuration as child to the given DOM node
+     *
+     * @param document The DOM document to add the configuration to
+     * @param parent The DOM parent node
+     * @since 2.0
+     */
+    public void save(Document document, Node parent)
+    {
+        Element properties = document.createElement("properties");
+        parent.appendChild(properties);
+        if (getHeader() != null)
+        {
+            Element comment = document.createElement("comment");
+            properties.appendChild(comment);
+            comment.setTextContent(StringEscapeUtils.escapeXml(getHeader()));
+        }
+
+        Iterator<String> keys = getKeys();
+        while (keys.hasNext())
+        {
+            String key = keys.next();
+            Object value = getProperty(key);
+
+            if (value instanceof List)
+            {
+                writeProperty(document, properties, key, (List<?>) value);
+            }
+            else
+            {
+                writeProperty(document, properties, key, value);
+            }
+        }
+    }
+
+    private void writeProperty(Document document, Node properties, String key, Object value)
+    {
+        Element entry = document.createElement("entry");
+        properties.appendChild(entry);
+
+        // escape the key
+        String k = StringEscapeUtils.escapeXml(key);
+        entry.setAttribute("key", k);
+
+        if (value != null)
+        {
+            // escape the value
+            String v = StringEscapeUtils.escapeXml(String.valueOf(value));
+            v = StringUtils.replace(v, String.valueOf(getListDelimiter()), "\\" + getListDelimiter());
+            entry.setTextContent(v);
+        }
+    }
+
+    private void writeProperty(Document document, Node properties, String key, List<?> values)
+    {
+        for (Object value : values)
+        {
+            writeProperty(document, properties, key, value);
+        }
+    }
+
+    /**
      * SAX Handler to parse a XML properties file.
      *
      * @author Alistair Young

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java?rev=1449399&r1=1449398&r2=1449399&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java Sat Feb 23 19:52:12 2013
@@ -22,8 +22,18 @@ import static org.junit.Assert.assertFal
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
 
 import org.junit.Test;
+import org.w3c.dom.Document;
 
 /**
  * @author Emmanuel Bourg
@@ -45,6 +55,24 @@ public class TestXMLPropertiesConfigurat
     }
 
     @Test
+    public void testDOMLoad() throws Exception
+    {
+        URL location = ConfigurationUtils.locate(FileSystem.getDefaultFileSystem(), null, "test.properties.xml");
+        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+        File file = new File(location.toURI());
+        Document doc = dBuilder.parse(file);
+        XMLPropertiesConfiguration conf = new XMLPropertiesConfiguration(doc.getDocumentElement());
+
+        assertEquals("header", "Description of the property list", conf.getHeader());
+
+        assertFalse("The configuration is empty", conf.isEmpty());
+        assertEquals("'key1' property", "value1", conf.getProperty("key1"));
+        assertEquals("'key2' property", "value2", conf.getProperty("key2"));
+        assertEquals("'key3' property", "value3", conf.getProperty("key3"));
+    }
+
+    @Test
     public void testSave() throws Exception
     {
         // load the configuration
@@ -74,4 +102,45 @@ public class TestXMLPropertiesConfigurat
         assertEquals("'key3' property", "value3", conf2.getProperty("key3"));
         assertEquals("'key4' property", "value4", conf2.getProperty("key4"));
     }
+
+    @Test
+    public void testDOMSave() throws Exception
+    {
+        // load the configuration
+        XMLPropertiesConfiguration conf = new XMLPropertiesConfiguration("test.properties.xml");
+
+        // update the configuration
+        conf.addProperty("key4", "value4");
+        conf.clearProperty("key2");
+        conf.setHeader("Description of the new property list");
+
+        // save the configuration
+        File saveFile = new File("target/test2.properties.xml");
+        if (saveFile.exists())
+        {
+            assertTrue(saveFile.delete());
+        }
+
+        // save as DOM into saveFile
+        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+        Document document = dBuilder.newDocument();
+        conf.save(document, document);
+        TransformerFactory tFactory = TransformerFactory.newInstance();
+        Transformer transformer = tFactory.newTransformer();
+        DOMSource source = new DOMSource(document);
+        Result result = new StreamResult(saveFile);
+        transformer.transform(source, result);
+
+        // reload the configuration
+        XMLPropertiesConfiguration conf2 = new XMLPropertiesConfiguration(saveFile);
+
+        // test the configuration
+        assertEquals("header", "Description of the new property list", conf2.getHeader());
+
+        assertFalse("The configuration is empty", conf2.isEmpty());
+        assertEquals("'key1' property", "value1", conf2.getProperty("key1"));
+        assertEquals("'key3' property", "value3", conf2.getProperty("key3"));
+        assertEquals("'key4' property", "value4", conf2.getProperty("key4"));
+    }
 }