oheger      2004/11/19 11:26:48

  Modified:    configuration/xdocs changes.xml
               configuration/src/java/org/apache/commons/configuration
                        HierarchicalXMLConfiguration.java
                        ConfigurationKey.java
               configuration/src/test/org/apache/commons/configuration
                        TestHierarchicalXMLConfiguration.java
  Log:
  Implementation of save() method for HierarchicalXMLConfiguration
  
  Revision  Changes    Path
  1.72      +5 -2      jakarta-commons/configuration/xdocs/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v
  retrieving revision 1.71
  retrieving revision 1.72
  diff -u -r1.71 -r1.72
  --- changes.xml       19 Nov 2004 13:19:50 -0000      1.71
  +++ changes.xml       19 Nov 2004 19:26:47 -0000      1.72
  @@ -8,6 +8,9 @@
     <body>
   
       <release version="1.1-dev" date="in CVS">
  +       <action dev="oheger" type="add" issue="31130">
  +             Added implementation of a save() method for 
HierarchicalXMLConfiguration.
  +       </action>
         <action dev="ebourg" type="update">
           Constructing a file based configuration with a File no longer throws
           an exception when the file doesn't exist.
  @@ -25,12 +28,12 @@
           the configuration descriptor is in a JAR file (reported by Grant 
Ingersoll).
         </action>
          <action dev="oheger" type="fix" issue="32236">
  -             Fixed NPE that where caused in the constructors of file based
  +             Fixed NPE that were caused in the constructors of file based
                configurations if an invalid file name was specified.
          </action>
          <action dev="oheger" type="add" issue="31797">
                Added support for optional configuration sources in definition 
files for
  -             ConfigurationFactory. A new required attribute allows to 
specify whether a
  +             ConfigurationFactory. A new optional attribute allows to 
specify whether a
                configuration source is mandatory or optional.
          </action>
         <action dev="ebourg" type="fix">
  
  
  
  1.6       +124 -6    
jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalXMLConfiguration.java
  
  Index: HierarchicalXMLConfiguration.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalXMLConfiguration.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- HierarchicalXMLConfiguration.java 18 Oct 2004 15:45:10 -0000      1.5
  +++ HierarchicalXMLConfiguration.java 19 Nov 2004 19:26:48 -0000      1.6
  @@ -22,10 +22,22 @@
   import java.io.Reader;
   import java.io.Writer;
   import java.net.URL;
  +import java.util.Iterator;
  +
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
  +import javax.xml.parsers.ParserConfigurationException;
  +import javax.xml.transform.OutputKeys;
  +import javax.xml.transform.Result;
  +import javax.xml.transform.Source;
  +import javax.xml.transform.Transformer;
  +import javax.xml.transform.TransformerException;
  +import javax.xml.transform.TransformerFactory;
  +import javax.xml.transform.dom.DOMSource;
  +import javax.xml.transform.stream.StreamResult;
   
   import org.w3c.dom.Attr;
  +import org.w3c.dom.DOMException;
   import org.w3c.dom.Document;
   import org.w3c.dom.Element;
   import org.w3c.dom.NamedNodeMap;
  @@ -50,7 +62,32 @@
    */
   public class HierarchicalXMLConfiguration extends HierarchicalConfiguration 
implements FileConfiguration
   {
  +    /** Constant for the default root element name.*/
  +    private static final String DEFAULT_ROOT_NAME = "configuration";
  +    
       private FileConfiguration delegate = new FileConfigurationDelegate();
  +    
  +    /** Stores the name of the root element.*/
  +    private String rootElementName;
  +    
  +    /**
  +     * Returns the name of the root element.
  +     * @return the name of the root element
  +     */
  +    public String getRootElementName()
  +    {
  +        return (rootElementName == null) ? DEFAULT_ROOT_NAME : 
rootElementName;
  +    }
  +    
  +    /**
  +     * Sets the name of the root element. This name is used when this
  +     * configuration object is stored in an XML file.
  +     * @param name the name of the root element
  +     */
  +    public void setRootElementName(String name)
  +    {
  +        rootElementName = name;
  +    }
   
       /**
        * Initializes this configuration from an XML document.
  @@ -121,7 +158,69 @@
               }
           }
       }
  -
  +    
  +    /**
  +     * Creates a DOM document from the internal tree of configuration nodes.
  +     * @return the new document
  +     * @throws ConfigurationException if an error occurs
  +     */
  +    protected Document createDocument() throws ConfigurationException
  +    {
  +        try
  +        {
  +            DocumentBuilder builder = 
DocumentBuilderFactory.newInstance().newDocumentBuilder();
  +            Document document = builder.newDocument();
  +            Element rootElem = document.createElement(getRootElementName());
  +            document.appendChild(rootElem);
  +            constructDOM(document, getRoot(), rootElem);
  +            return document;
  +        }  /* try */
  +        catch(DOMException domEx)
  +        {
  +            throw new ConfigurationException(domEx);
  +        }
  +        catch(ParserConfigurationException pex)
  +        {
  +            throw new ConfigurationException(pex);
  +        }
  +    }
  +    
  +    /**
  +     * Creates a DOM from the tree of configuration nodes.
  +     * @param document the document
  +     * @param node the actual node
  +     * @param element the actual XML element
  +     * @throws DOMException if an error occurs
  +     */
  +    private void constructDOM(Document document, Node node, Element element)
  +    throws DOMException
  +    {
  +        for(Iterator it = node.getChildren().iterator(); it.hasNext();)
  +        {
  +            Node child = (Node) it.next();
  +            if(ConfigurationKey.isAttributeKey(child.getName()))
  +            {
  +                if (child.getValue() != null)
  +                {
  +                    
element.setAttribute(ConfigurationKey.removeAttributeMarkers(
  +                            child.getName()), child.getValue().toString());
  +                }
  +            }
  +            else
  +            {
  +                Element childElem = document.createElement(child.getName());
  +                if(child.getValue() != null)
  +                {
  +                    Text text = 
document.createTextNode(child.getValue().toString());
  +                    childElem.appendChild(text);
  +                    
  +                }
  +                constructDOM(document, child, childElem);
  +                element.appendChild(childElem);
  +            }
  +        }
  +    }
  +    
       public void load() throws ConfigurationException
       {
           delegate.load();
  @@ -195,10 +294,29 @@
           delegate.save(out, encoding);
       }
   
  -    public void save(Writer out) throws ConfigurationException
  -    {
  -        throw new UnsupportedOperationException("Can't save 
HierarchicalXMLConfigurations");
  -    }
  +        /**
  +         * Saves the configuration to the specified writer.
  +         * 
  +         * @param writer
  +         *            the writer used to save the configuration
  +         * @throws ConfigurationException if an error occurs
  +         */
  +        public void save(Writer writer) throws ConfigurationException
  +        {
  +            try 
  +            {
  +                Transformer transformer = 
TransformerFactory.newInstance().newTransformer();
  +                Source source = new DOMSource(createDocument());
  +                Result result = new StreamResult(writer);
  +    
  +                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
  +                transformer.transform(source, result);
  +            } 
  +            catch (TransformerException e) 
  +            {
  +                throw new ConfigurationException(e.getMessage(), e);
  +            }
  +         }
   
       public String getFileName()
       {
  
  
  
  1.6       +2 -2      
jakarta-commons/configuration/src/java/org/apache/commons/configuration/ConfigurationKey.java
  
  Index: ConfigurationKey.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/ConfigurationKey.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ConfigurationKey.java     14 Aug 2004 11:23:14 -0000      1.5
  +++ ConfigurationKey.java     19 Nov 2004 19:26:48 -0000      1.6
  @@ -172,7 +172,7 @@
        * @param key the key
        * @return the key with removed attribute markers
        */
  -    private static String removeAttributeMarkers(String key)
  +    static String removeAttributeMarkers(String key)
       {
           return key.substring(ATTRIBUTE_START.length(), key.length() - 
ATTRIBUTE_END.length());
       }
  
  
  
  1.3       +30 -2     
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestHierarchicalXMLConfiguration.java
  
  Index: TestHierarchicalXMLConfiguration.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestHierarchicalXMLConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestHierarchicalXMLConfiguration.java     6 Sep 2004 13:12:04 -0000       
1.2
  +++ TestHierarchicalXMLConfiguration.java     19 Nov 2004 19:26:48 -0000      
1.3
  @@ -45,6 +45,15 @@
   
       /** Test file path #2 **/
       private static final String TEST_FILE2 = TEST_DIR + File.separator + 
TEST_FILENAME2;
  +    
  +    /** Test file path #3.*/
  +    private static final String TEST_FILE3 = TEST_DIR + File.separator + 
"test.xml";
  +
  +    /** File name for saving.*/
  +    private static final String TEST_SAVENAME = "testhierarchicalsave.xml";
  +
  +    /** File path for saving.*/
  +    private static final String TEST_SAVE = TEST_DIR + File.separator + 
TEST_SAVENAME;
   
       /** Instance config used for tests. */
       private HierarchicalXMLConfiguration config;
  @@ -144,5 +153,24 @@
           }
           assertEquals("Config must contain only " + KEY_COUNT + " keys.", 
KEY_COUNT, count);
       }
  -
  +    
  +    public void testSave() throws Exception
  +    {
  +        config.setFileName(TEST_FILE3);
  +        config.load();
  +        File saveFile = new File(TEST_SAVE);
  +        config.setRootElementName("myconfig");
  +        config.save(saveFile);
  +        
  +        config = new HierarchicalXMLConfiguration();
  +        config.load(saveFile.toURL());
  +        assertEquals("value", config.getProperty("element"));
  +        assertEquals("I'm complex!", 
config.getProperty("element2.subelement.subsubelement"));
  +        assertEquals(8, config.getInt("test.short"));
  +        assertEquals("one", config.getString("list(0).item(0)[EMAIL 
PROTECTED]"));
  +        assertEquals("two", config.getString("list(0).item(1)"));
  +        assertEquals("six", config.getString("list(1).sublist.item(1)"));
  +        
  +        assertTrue(saveFile.delete());
  +    }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to