You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by eb...@apache.org on 2005/01/03 19:32:47 UTC

cvs commit: jakarta-commons/configuration/src/java/org/apache/commons/configuration XMLPropertiesConfiguration.java

ebourg      2005/01/03 10:32:47

  Modified:    configuration/xdocs changes.xml
               configuration project.xml
  Added:       configuration/conf properties.dtd test.properties.xml
               configuration/src/test/org/apache/commons/configuration
                        TestXMLPropertiesConfiguration.java
               configuration/src/java/org/apache/commons/configuration
                        XMLPropertiesConfiguration.java
  Log:
  Added XMLPropertiesConfiguration to support the new XML format for java.util.Properties introduced in Java 1.5
  
  Revision  Changes    Path
  1.81      +5 -0      jakarta-commons/configuration/xdocs/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v
  retrieving revision 1.80
  retrieving revision 1.81
  diff -u -r1.80 -r1.81
  --- changes.xml	3 Jan 2005 16:51:29 -0000	1.80
  +++ changes.xml	3 Jan 2005 18:32:46 -0000	1.81
  @@ -8,6 +8,11 @@
     <body>
   
       <release version="1.1-dev" date="in CVS">
  +      <action dev="ebourg" type="add" issue="32318">
  +        Added a new configuration, XMLPropertiesConfiguration, supporting the
  +        new XML format for java.util.Properties introduced in Java 1.5.
  +        A 1.5 runtime is not required to use this class.
  +      </action>
         <action dev="ebourg" type="add" issue="26092">
           Added a comment header to PropertiesConfiguration. The header is not
           parsed when the file is loaded yet.
  
  
  
  1.42      +6 -2      jakarta-commons/configuration/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/project.xml,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- project.xml	1 Jan 2005 14:02:16 -0000	1.41
  +++ project.xml	3 Jan 2005 18:32:46 -0000	1.42
  @@ -60,6 +60,7 @@
       <connection>scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-commons/${pom.artifactId.substring(8)}</connection>
       <url>http://cvs.apache.org/viewcvs/jakarta-commons/${pom.artifactId.substring(8)}/</url>
     </repository>
  +
     <versions>
       <version>
         <id>1.0-rc1</id>
  @@ -77,6 +78,7 @@
         <tag>CONFIGURATION_1_0</tag>
       </version>
     </versions>
  +    
     <mailingLists>
       <mailingList>
         <name>Commons Dev List</name>
  @@ -357,7 +359,7 @@
       <!-- Unit test classes -->
       <unitTest>
         <includes>
  -        <include>**/Test*.java</include>
  +        <include>**/*Test*.java</include>
         </includes>
         <excludes>
           <exclude>**/TestBasePropertiesConfiguration.java</exclude>
  @@ -377,6 +379,7 @@
               <include>testClasspath.properties</include>
               <include>testdb.script</include>
               <include>*.properties</include>
  +            <include>*.dtd</include>
             </includes>
           </resource>
           <resource>
  @@ -402,6 +405,7 @@
           <directory>conf</directory>
           <includes>
             <include>digesterRules.xml</include>
  +          <include>properties.dtd</include>
           </includes>
         </resource>
       </resources>
  
  
  
  1.1                  jakarta-commons/configuration/conf/properties.dtd
  
  Index: properties.dtd
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  
  <!-- DTD for properties -->
  
  <!ELEMENT properties ( comment?, entry* ) >
  
  <!ATTLIST properties version CDATA #FIXED "1.0">
  
  <!ELEMENT comment (#PCDATA)>
  
  <!ELEMENT entry (#PCDATA)>
  
  <!ATTLIST entry key CDATA #REQUIRED>
  
  
  
  1.1                  jakarta-commons/configuration/conf/test.properties.xml
  
  Index: test.properties.xml
  ===================================================================
  <?xml version="1.0"?>
  <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
  <properties>
    <comment>Description of the property list</comment>
    <entry key="key1">value1</entry>
    <entry key="key2">value2</entry>
    <entry key="key3">value3</entry>
  </properties>
  
  
  
  1.1                  jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestXMLPropertiesConfiguration.java
  
  Index: TestXMLPropertiesConfiguration.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License")
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.commons.configuration;
  
  import junit.framework.TestCase;
  
  /**
   * @author Emmanuel Bourg
   * @version $Revision: 1.1 $, $Date: 2005/01/03 18:32:46 $
   */
  public class TestXMLPropertiesConfiguration extends TestCase
  {
      public void testLoad() throws Exception
      {
          XMLPropertiesConfiguration conf = new XMLPropertiesConfiguration("test.properties.xml");
  
          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"));
      }
  
      public void testSave() 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
          conf.save("target/test2.properties.xml");
  
          // reload the configuration
          XMLPropertiesConfiguration conf2 = new XMLPropertiesConfiguration("target/test2.properties.xml");
  
          // 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"));
      }
  }
  
  
  
  1.1                  jakarta-commons/configuration/src/java/org/apache/commons/configuration/XMLPropertiesConfiguration.java
  
  Index: XMLPropertiesConfiguration.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License")
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.commons.configuration;
  
  import java.io.File;
  import java.io.PrintWriter;
  import java.io.Reader;
  import java.io.Writer;
  import java.net.URL;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.commons.digester.Digester;
  import org.apache.commons.lang.StringEscapeUtils;
  import org.apache.commons.lang.StringUtils;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  
  /**
   * This configuration implements the XML properties format introduced in Java
   * 5.0, see http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html.
   * An XML properties file looks like this:
   *
   * <pre>
   * &lt;?xml version="1.0"?>
   * &lt;!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
   * &lt;properties>
   *   &lt;comment>Description of the property list&lt;/comment>
   *   &lt;entry key="key1">value1&lt;/entry>
   *   &lt;entry key="key2">value2&lt;/entry>
   *   &lt;entry key="key3">value3&lt;/entry>
   * &lt;/properties>
   * &lt;/pre>
   *
   * The Java 5.0 runtime is not required to use this class. The default encoding
   * for this configuration format is UTF-8. Note that unlike
   * <code>PropertiesConfiguration</code>, <code>XMLPropertiesConfiguration</code>
   * does not support includes.
   *
   * @since 1.1
   *
   * @author Emmanuel Bourg
   * @version $Revision: 1.1 $, $Date: 2005/01/03 18:32:46 $
   */
  public class XMLPropertiesConfiguration extends PropertiesConfiguration
  {
      /**
       * The default encoding (UTF-8 as specified by http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html)
       */
      private static final String DEFAULT_ENCODING = "UTF-8";
  
      // initialization block to set the encoding before loading the file in the constructors
      {
          setEncoding(DEFAULT_ENCODING);
      }
  
      /**
       * Creates an empty XMLPropertyConfiguration object which can be
       * used to synthesize a new Properties file by adding values and
       * then saving(). An object constructed by this C'tor can not be
       * tickled into loading included files because it cannot supply a
       * base for relative includes.
       */
      public XMLPropertiesConfiguration()
      {
          super();
      }
  
      /**
       * Creates and loads the xml properties from the specified file.
       * The specified file can contain "include" properties which then
       * are loaded and merged into the properties.
       *
       * @param fileName The name of the properties file to load.
       * @throws ConfigurationException Error while loading the properties file
       */
      public XMLPropertiesConfiguration(String fileName) throws ConfigurationException
      {
          super(fileName);
      }
  
      /**
       * Creates and loads the xml properties from the specified file.
       * The specified file can contain "include" properties which then
       * are loaded and merged into the properties.
       *
       * @param file The properties file to load.
       * @throws ConfigurationException Error while loading the properties file
       */
      public XMLPropertiesConfiguration(File file) throws ConfigurationException
      {
          super(file);
      }
  
      /**
       * Creates and loads the xml properties from the specified URL.
       * The specified file can contain "include" properties which then
       * are loaded and merged into the properties.
       *
       * @param url The location of the properties file to load.
       * @throws ConfigurationException Error while loading the properties file
       */
      public XMLPropertiesConfiguration(URL url) throws ConfigurationException
      {
          super(url);
      }
  
      public void load(Reader in) throws ConfigurationException
      {
          // todo: replace with a pure SAX implementation to reduce the dependencies
  
          // set up the digester
          Digester digester = new Digester();
          digester.setEntityResolver(new EntityResolver(){
              public InputSource resolveEntity(String publicId, String systemId)
              {
                  return new InputSource(getClass().getClassLoader().getResourceAsStream("properties.dtd"));
              }
          });
  
          digester.addCallMethod("properties/comment", "setHeader", 0);
  
          digester.addCallMethod("properties/entry", "addProperty", 2);
          digester.addCallParam("properties/entry", 0, "key");
          digester.addCallParam("properties/entry", 1);
  
          // todo: support included properties ?
  
          // parse the file
          digester.push(this);
          try
          {
              digester.parse(in);
          }
          catch (Exception e)
          {
              throw new ConfigurationException("Unable to parse the configuration file", e);
          }
      }
  
      public void save(Writer out) throws ConfigurationException
      {
          PrintWriter writer = new PrintWriter(out);
  
          String encoding = getEncoding() != null ? getEncoding() : DEFAULT_ENCODING;
          writer.println("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>");
          writer.println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
          writer.println("<properties>");
  
          if (getHeader() != null)
          {
              writer.println("  <comment>" + StringEscapeUtils.escapeXml(getHeader()) + "</comment>");
          }
  
          Iterator keys = getKeys();
          while (keys.hasNext())
          {
              String key = (String) keys.next();
              Object value = getProperty(key);
  
              if (value instanceof List)
              {
                  writeProperty(writer, key, (List) value);
              }
              else
              {
                  writeProperty(writer, key, value);
              }
          }
  
          writer.println("</properties>");
          writer.flush();
      }
  
      /**
       * Write a property.
       */
      private void writeProperty(PrintWriter out, String key, Object value)
      {
          // escape the key
          String k = StringEscapeUtils.escapeXml(key);
  
          if (value != null)
          {
              // escape the value
              String v = StringEscapeUtils.escapeXml(String.valueOf(value));
              v = StringUtils.replace(v, String.valueOf(getDelimiter()), "\\" + getDelimiter());
  
              out.println("  <entry key=\"" + k + "\">" + v + "</entry>");
          }
          else
          {
              out.println("  <entry key=\"" + k + "\"/>");
          }
      }
  
      /**
       * Write a list property.
       */
      private void writeProperty(PrintWriter out, String key, List values)
      {
          for (int i = 0; i < values.size(); i++)
          {
              writeProperty(out, key, values.get(i));
          }
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org