Author: henning
Date: Mon Oct 21 22:25:03 2013
New Revision: 1534399

URL: http://svn.apache.org/r1534399
Log:
Backport CONFIGURATION-526 from r1449399.


Modified:
    
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/RELEASE-NOTES.txt
    
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/changes/changes.xml
    
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
    
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestPropertiesConfiguration.java
    
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java

Modified: 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/RELEASE-NOTES.txt
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/RELEASE-NOTES.txt?rev=1534399&r1=1534398&r2=1534399&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/RELEASE-NOTES.txt
 (original)
+++ 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/RELEASE-NOTES.txt
 Mon Oct 21 22:25:03 2013
@@ -80,6 +80,11 @@ IMPROVEMENTS AND NEW FEATURES IN 1.10
   The includesAllowed property of PropertyConfiguration is now independent
   from the existence of a base path.
 
+* [CONFIGURATION-526] Support loading from and saving to DOM nodes
+
+  XMLPropertiesConfiguration now supports loading from and saving to DOM
+  nodes.
+
 * [CONFIGURATION-550] Missing conversion to char
 
   Conversion to Character is now supported.

Modified: 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/changes/changes.xml?rev=1534399&r1=1534398&r2=1534399&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/changes/changes.xml
 (original)
+++ 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/changes/changes.xml
 Mon Oct 21 22:25:03 2013
@@ -31,6 +31,10 @@
         XMLConfiguration now adds attributes of elements defining a list to
         all list nodes.
       </action>
+      <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-534">
         The includesAllowed property of PropertyConfiguration is now 
independent
         from the existence of a base path.

Modified: 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java?rev=1534399&r1=1534398&r2=1534399&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
 (original)
+++ 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/main/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
 Mon Oct 21 22:25:03 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/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestPropertiesConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestPropertiesConfiguration.java?rev=1534399&r1=1534398&r2=1534399&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestPropertiesConfiguration.java
 (original)
+++ 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestPropertiesConfiguration.java
 Mon Oct 21 22:25:03 2013
@@ -68,6 +68,9 @@ public class TestPropertiesConfiguration
     /** Constant for a test property value.*/
     private static final String PROP_VALUE = "value";
 
+    /** Constant for the line break character. */
+    private static final String CR = System.getProperty("line.separator");
+
     /** The configuration to be tested.*/
     private PropertiesConfiguration conf;
 
@@ -165,7 +168,7 @@ public class TestPropertiesConfiguration
                 new StringReader(PropertiesConfiguration.getInclude() + " = "
                         + 
ConfigurationAssert.getTestURL("include.properties"));
         conf = new PropertiesConfiguration();
-        conf.read(in);
+        conf.load(in);
         assertEquals("Include file not loaded", "true",
                 conf.getString("include.loaded"));
     }
@@ -184,7 +187,7 @@ public class TestPropertiesConfiguration
         StringReader in = new StringReader(content);
         conf = new PropertiesConfiguration();
         conf.setIncludesAllowed(false);
-        conf.read(in);
+        conf.load(in);
         assertEquals("Data not loaded", PROP_VALUE, conf.getString(PROP_NAME));
     }
 

Modified: 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java?rev=1534399&r1=1534398&r2=1534399&view=diff
==============================================================================
--- 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java
 (original)
+++ 
commons/proper/configuration/branches/CONFIGURATION_1_X_MAINTENANCE/src/test/java/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java
 Mon Oct 21 22:25:03 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"));
+    }
 }


Reply via email to