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 2008/06/01 22:06:47 UTC

svn commit: r662278 - in /commons/proper/configuration/trunk: conf/test.xml src/java/org/apache/commons/configuration/XMLConfiguration.java src/test/org/apache/commons/configuration/TestXMLConfiguration.java

Author: oheger
Date: Sun Jun  1 13:06:47 2008
New Revision: 662278

URL: http://svn.apache.org/viewvc?rev=662278&view=rev
Log:
CONFIGURATION-307: XMLConfiguration now supports the xml:space attribute. This allows preserving whitespace in the content of XML elements.

Modified:
    commons/proper/configuration/trunk/conf/test.xml
    commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
    commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java

Modified: commons/proper/configuration/trunk/conf/test.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/conf/test.xml?rev=662278&r1=662277&r2=662278&view=diff
==============================================================================
--- commons/proper/configuration/trunk/conf/test.xml (original)
+++ commons/proper/configuration/trunk/conf/test.xml Sun Jun  1 13:06:47 2008
@@ -90,4 +90,12 @@
          splitting when delimiter parsing is disabled.
     -->
     <expressions value="a \|\| (b &amp;&amp; c)|!d"/>
+
+    <!-- Tests for handling of spaces -->
+    <space xml:space="preserve">
+      <blanc> </blanc>
+      <stars> * * </stars>
+      <description xml:space="default">     Some text      </description>
+      <testInvalid xml:space="invalid">     Some other text </testInvalid>
+    </space>
 </testconfig>

Modified: commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java?rev=662278&r1=662277&r2=662278&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java Sun Jun  1 13:06:47 2008
@@ -127,6 +127,24 @@
  * property is always consistent when you load and save a configuration file.
  * Otherwise the values of properties can become corrupted.</p>
  *
+ * <p>Whitespace in the content of XML documents is trimmed per default. In most
+ * cases this is desired. However, sometimes whitespace is indeed important and
+ * should be treated as part of the value of a property as in the following
+ * example:
+ * <pre>
+ *   &lt;indent&gt;    &lt;/indent&gt;
+ * </pre></p>
+ *
+ * <p>Per default the spaces in the <code>indent</code> element will be trimmed
+ * resulting in an empty element. To tell <code>XMLConfiguration</code> that
+ * spaces are relevant the <code>xml:space</code> attribute can be used, which is
+ * defined in the <a href="http://www.w3.org/TR/REC-xml/#sec-white-space">XML
+ * specification</a>. This will look as follows:
+ * <pre>
+ *   &lt;indent <strong>xml:space=&quot;preserve&quot;</strong>&gt;    &lt;/indent&gt;
+ * </pre>
+ * The value of the <code>indent</code> property will now contain the spaces.</p>
+ *
  * <p><code>XMLConfiguration</code> implements the <code>{@link FileConfiguration}</code>
  * interface and thus provides full support for loading XML documents from
  * different sources like files, URLs, or streams. A full description of these
@@ -154,6 +172,12 @@
     /** Constant for the default root element name. */
     private static final String DEFAULT_ROOT_NAME = "configuration";
 
+    /** Constant for the name of the space attribute.*/
+    private static final String ATTR_SPACE = "xml:space";
+
+    /** Constant for the xml:space value for preserving whitespace.*/
+    private static final String VALUE_PRESERVE = "preserve";
+
     /** Constant for the delimiter for multiple attribute values.*/
     private static final char ATTR_VALUE_DELIMITER = '|';
 
@@ -422,7 +446,7 @@
             setSystemID(document.getDoctype().getSystemId());
         }
 
-        constructHierarchy(getRoot(), document.getDocumentElement(), elemRefs);
+        constructHierarchy(getRoot(), document.getDocumentElement(), elemRefs, true);
         getRootNode().setName(document.getDocumentElement().getNodeName());
         if (elemRefs)
         {
@@ -437,9 +461,12 @@
      * @param node the actual node
      * @param element the actual XML element
      * @param elemRefs a flag whether references to the XML elements should be set
+     * @param trim a flag whether the text content of elements should be trimmed;
+     * this controls the whitespace handling
      */
-    private void constructHierarchy(Node node, Element element, boolean elemRefs)
+    private void constructHierarchy(Node node, Element element, boolean elemRefs, boolean trim)
     {
+        boolean trimFlag = shouldTrim(element, trim);
         processAttributes(node, element, elemRefs);
         StringBuffer buffer = new StringBuffer();
         NodeList list = element.getChildNodes();
@@ -451,9 +478,9 @@
                 Element child = (Element) w3cNode;
                 Node childNode = new XMLNode(child.getTagName(),
                         elemRefs ? child : null);
-                constructHierarchy(childNode, child, elemRefs);
+                constructHierarchy(childNode, child, elemRefs, trimFlag);
                 node.addChild(childNode);
-                handleDelimiters(node, childNode);
+                handleDelimiters(node, childNode, trimFlag);
             }
             else if (w3cNode instanceof Text)
             {
@@ -461,7 +488,12 @@
                 buffer.append(data.getData());
             }
         }
-        String text = buffer.toString().trim();
+
+        String text = buffer.toString();
+        if (trimFlag)
+        {
+            text = text.trim();
+        }
         if (text.length() > 0 || !node.hasChildren())
         {
             node.setValue(text);
@@ -506,8 +538,9 @@
      *
      * @param parent the parent element
      * @param child the child element
+     * @param trim flag whether texts of elements should be trimmed
      */
-    private void handleDelimiters(Node parent, Node child)
+    private void handleDelimiters(Node parent, Node child, boolean trim)
     {
         if (child.getValue() != null)
         {
@@ -520,7 +553,7 @@
             else
             {
                 values = PropertyConverter.split(child.getValue().toString(),
-                    getListDelimiter());
+                    getListDelimiter(), trim);
             }
 
             if (values.size() > 1)
@@ -558,6 +591,31 @@
     }
 
     /**
+     * Checks whether the content of the current XML element should be trimmed.
+     * This method checks whether a <code>xml:space</code> attribute is
+     * present and evaluates its value. See <a
+     * href="http://www.w3.org/TR/REC-xml/#sec-white-space">
+     * http://www.w3.org/TR/REC-xml/#sec-white-space</a> for more details.
+     *
+     * @param element the current XML element
+     * @param currentTrim the current trim flag
+     * @return a flag whether the content of this element should be trimmed
+     */
+    private boolean shouldTrim(Element element, boolean currentTrim)
+    {
+        Attr attr = element.getAttributeNode(ATTR_SPACE);
+
+        if (attr == null)
+        {
+            return currentTrim;
+        }
+        else
+        {
+            return !VALUE_PRESERVE.equals(attr.getValue());
+        }
+    }
+
+    /**
      * Creates the <code>DocumentBuilder</code> to be used for loading files.
      * This implementation checks whether a specific
      * <code>DocumentBuilder</code> has been set. If this is the case, this

Modified: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?rev=662278&r1=662277&r2=662278&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java Sun Jun  1 13:06:47 2008
@@ -1387,6 +1387,36 @@
     }
 
     /**
+     * Tests whether spaces are preserved when the xml:space attribute is set.
+     */
+    public void testPreserveSpace()
+    {
+        assertEquals("Wrong value of blanc", " ", conf.getString("space.blanc"));
+        assertEquals("Wrong value of stars", " * * ", conf
+                .getString("space.stars"));
+    }
+
+    /**
+     * Tests whether the xml:space attribute can be overridden in nested
+     * elements.
+     */
+    public void testPreserveSpaceOverride()
+    {
+        assertEquals("Not trimmed", "Some text", conf
+                .getString("space.description"));
+    }
+
+    /**
+     * Tests an xml:space attribute with an invalid value. This will be
+     * interpreted as default.
+     */
+    public void testPreserveSpaceInvalid()
+    {
+        assertEquals("Invalid not trimmed", "Some other text", conf
+                .getString("space.testInvalid"));
+    }
+
+    /**
      * Prepares a configuration object for testing a reload operation.
      *
      * @return the initialized configuration