You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2004/12/18 17:33:03 UTC

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

oheger      2004/12/18 08:33:03

  Modified:    configuration/src/java/org/apache/commons/configuration
                        HierarchicalXMLConfiguration.java
                        HierarchicalConfiguration.java
               configuration/src/test/org/apache/commons/configuration
                        TestHierarchicalXMLConfiguration.java
  Log:
  Made HierarchicalXMLConfiguration fully compatible with XMLConfiguration: fixed an issue with attribute handling, implemented the auto save feature, added the constructors for file based configurations.
  
  Revision  Changes    Path
  1.8       +160 -43   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.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- HierarchicalXMLConfiguration.java	13 Dec 2004 16:40:13 -0000	1.7
  +++ HierarchicalXMLConfiguration.java	18 Dec 2004 16:33:03 -0000	1.8
  @@ -25,6 +25,7 @@
   import java.util.ArrayList;
   import java.util.Collection;
   import java.util.Iterator;
  +import java.util.List;
   
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
  @@ -63,13 +64,15 @@
    * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger </a>
    * @version $Revision$, $Date$
    */
  -public class HierarchicalXMLConfiguration extends HierarchicalConfiguration implements
  -        FileConfiguration
  +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();
  +    /** Delimiter character for attributes. */
  +    private static char ATTR_DELIMITER = ',';
  +
  +    private FileConfigurationDelegate delegate = new FileConfigurationDelegate();
   
       /** The document from this configuration's data source. */
       private Document document;
  @@ -78,6 +81,59 @@
       private String rootElementName;
   
       /**
  +     * Creates a new instance of <code>HierarchicalXMLConfiguration</code>.
  +     */
  +    public HierarchicalXMLConfiguration()
  +    {
  +        super();
  +    }
  +
  +    /**
  +     * Creates a new instance of <code>HierarchicalXMLConfiguration</code>.
  +     * The configuration is loaded from the specified file
  +     * 
  +     * @param fileName the name of the file to load
  +     * @throws ConfigurationException if the file cannot be loaded
  +     */
  +    public HierarchicalXMLConfiguration(String fileName) throws ConfigurationException
  +    {
  +        this();
  +        setFileName(fileName);
  +        load();
  +    }
  +
  +    /**
  +     * Creates a new instance of <code>HierarchicalXMLConfiguration</code>.
  +     * The configuration is loaded from the specified file.
  +     * 
  +     * @param file the file
  +     * @throws ConfigurationException if an error occurs while loading the file
  +     */
  +    public HierarchicalXMLConfiguration(File file) throws ConfigurationException
  +    {
  +        this();
  +        setFile(file);
  +        if (file.exists())
  +        {
  +            load();
  +        }
  +    }
  +
  +    /**
  +     * Creates a new instance of <code>HierarchicalXMLConfiguration</code>.
  +     * The configuration is loaded from the specified URL.
  +     * 
  +     * @param url the URL
  +     * @throws ConfigurationException if loading causes an error
  +     */
  +    public HierarchicalXMLConfiguration(URL url) throws ConfigurationException
  +    {
  +        this();
  +        setURL(url);
  +        load();
  +    }
  +
  +    /**
        * Returns the name of the root element.
        * 
        * @return the name of the root element
  @@ -89,8 +145,8 @@
   
       /**
        * Sets the name of the root element. This name is used when this
  -     * configuration object is stored in an XML file. Note that setting the
  -     * name of the root element works only if this configuration has been newly
  +     * configuration object is stored in an XML file. Note that setting the name
  +     * of the root element works only if this configuration has been newly
        * created. If the configuration was loaded from an XML file, the name
        * cannot be changed.
        * 
  @@ -102,6 +158,33 @@
       }
   
       /**
  +     * @inheritDoc
  +     */
  +    protected void addPropertyDirect(String key, Object obj)
  +    {
  +        super.addPropertyDirect(key, obj);
  +        delegate.possiblySave();
  +    }
  +
  +    /**
  +     * @inheritDoc
  +     */
  +    public void clearProperty(String key)
  +    {
  +        super.clearProperty(key);
  +        delegate.possiblySave();
  +    }
  +
  +    /**
  +     * @inheritDoc
  +     */
  +    public void setProperty(String key, Object value)
  +    {
  +        super.setProperty(key, value);
  +        delegate.possiblySave();
  +    }
  +
  +    /**
        * Initializes this configuration from an XML document.
        * 
        * @param document the document to be parsed
  @@ -120,6 +203,7 @@
        */
       private void constructHierarchy(Node node, Element element)
       {
  +        processAttributes(node, element);
           StringBuffer buffer = new StringBuffer();
           NodeList list = element.getChildNodes();
           for (int i = 0; i < list.getLength(); i++)
  @@ -131,7 +215,6 @@
                   Node childNode = new XMLNode(child.getTagName(), child);
                   constructHierarchy(childNode, child);
                   node.addChild(childNode);
  -                processAttributes(childNode, child);
               }
               else if (w3cNode instanceof Text)
               {
  @@ -162,10 +245,12 @@
               if (w3cNode instanceof Attr)
               {
                   Attr attr = (Attr) w3cNode;
  -                Node child = new XMLNode(ConfigurationKey.constructAttributeKey(attr.getName()),
  -                        element);
  -                child.setValue(attr.getValue());
  -                node.addChild(child);
  +                for (Iterator it = PropertyConverter.split(attr.getValue(), ATTR_DELIMITER).iterator(); it.hasNext();)
  +                {
  +                    Node child = new XMLNode(ConfigurationKey.constructAttributeKey(attr.getName()), element);
  +                    child.setValue(it.next());
  +                    node.addChild(child);
  +                }
               }
           }
       }
  @@ -423,7 +508,7 @@
               {
                   if (ConfigurationKey.isAttributeKey(getName()))
                   {
  -                    updateAttribute(value);
  +                    updateAttribute();
                   }
                   else
                   {
  @@ -442,7 +527,7 @@
                   Element element = (Element) getReference();
                   if (ConfigurationKey.isAttributeKey(getName()))
                   {
  -                    element.removeAttribute(ConfigurationKey.removeAttributeMarkers(getName()));
  +                    updateAttribute();
                   }
                   else
                   {
  @@ -478,8 +563,7 @@
                       txtNode = document.createTextNode(value.toString());
                       if (((Element) getReference()).getFirstChild() != null)
                       {
  -                        ((Element) getReference()).insertBefore(txtNode, ((Element) getReference())
  -                                .getFirstChild());
  +                        ((Element) getReference()).insertBefore(txtNode, ((Element) getReference()).getFirstChild());
                       }
                       else
                       {
  @@ -495,21 +579,11 @@
   
           /**
            * Updates the node's value if it represents an attribute.
  -         * 
  -         * @param value the new value
  +         *  
            */
  -        private void updateAttribute(Object value)
  +        private void updateAttribute()
           {
  -            Element elem = (Element) getReference();
  -            if (value == null)
  -            {
  -                elem.removeAttribute(ConfigurationKey.removeAttributeMarkers(getName()));
  -            }
  -            else
  -            {
  -                elem.setAttribute(ConfigurationKey.removeAttributeMarkers(getName()), value
  -                        .toString());
  -            }
  +            XMLBuilderVisitor.updateAttribute(getParent(), getName());
           }
   
           /**
  @@ -595,17 +669,8 @@
           {
               if (ConfigurationKey.isAttributeKey(newNode.getName()))
               {
  -                if (newNode.getValue() != null)
  -                {
  -                    getElement(parent).setAttribute(
  -                            ConfigurationKey.removeAttributeMarkers(newNode.getName()),
  -                            newNode.getValue().toString());
  -                    return getElement(parent);
  -                }
  -                else
  -                {
  -                    return null;
  -                }
  +                updateAttribute(parent, getElement(parent), newNode.getName());
  +                return null;
               }
   
               else
  @@ -632,6 +697,61 @@
           }
   
           /**
  +         * Helper method for updating the value of the specified node's
  +         * attribute with the given name.
  +         * 
  +         * @param node the affected node
  +         * @param elem the element that is associated with this node
  +         * @param name the name of the affected attribute
  +         */
  +        private static void updateAttribute(Node node, Element elem, String name)
  +        {
  +            if (node != null && elem != null)
  +            {
  +                List attrs = node.getChildren(name);
  +                StringBuffer buf = new StringBuffer();
  +                for (Iterator it = attrs.iterator(); it.hasNext();)
  +                {
  +                    Node attr = (Node) it.next();
  +                    if (attr.getValue() != null)
  +                    {
  +                        if (buf.length() > 0)
  +                        {
  +                            buf.append(ATTR_DELIMITER);
  +                        }
  +                        buf.append(attr.getValue());
  +                    }
  +                    attr.setReference(elem);
  +                }
  +
  +                if (buf.length() < 1)
  +                {
  +                    elem.removeAttribute(ConfigurationKey.removeAttributeMarkers(name));
  +                }
  +                else
  +                {
  +                    elem.setAttribute(ConfigurationKey.removeAttributeMarkers(name), buf.toString());
  +                }
  +            }
  +        }
  +
  +        /**
  +         * Updates the value of the specified attribute of the given node.
  +         * Because there can be multiple child nodes representing this attribute
  +         * the new value is determined by iterating over all those child nodes.
  +         * 
  +         * @param node the affected node
  +         * @param name the name of the attribute
  +         */
  +        static void updateAttribute(Node node, String name)
  +        {
  +            if (node != null)
  +            {
  +                updateAttribute(node, (Element) node.getReference(), name);
  +            }
  +        }
  +
  +        /**
            * Helper method for accessing the element of the specified node.
            * 
            * @param node the node
  @@ -640,14 +760,12 @@
           private Element getElement(Node node)
           {
               // special treatement for root node of the hierarchy
  -            return (node.getName() != null) ? (Element) node.getReference() : document
  -                    .getDocumentElement();
  +            return (node.getName() != null) ? (Element) node.getReference() : document.getDocumentElement();
           }
       }
   
       private class FileConfigurationDelegate extends AbstractFileConfiguration
       {
  -
           public void load(Reader in) throws ConfigurationException
           {
               HierarchicalXMLConfiguration.this.load(in);
  @@ -657,6 +775,5 @@
           {
               HierarchicalXMLConfiguration.this.save(out);
           }
  -
       }
   }
  
  
  
  1.17      +18 -16    jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
  
  Index: HierarchicalConfiguration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- HierarchicalConfiguration.java	14 Dec 2004 17:03:50 -0000	1.16
  +++ HierarchicalConfiguration.java	18 Dec 2004 16:33:03 -0000	1.17
  @@ -496,8 +496,7 @@
        * @param node the actual node
        * @param data here the found nodes are stored
        */
  -    protected void findPropertyNodes(ConfigurationKey.KeyIterator keyPart, Node node,
  -            Collection data)
  +    protected void findPropertyNodes(ConfigurationKey.KeyIterator keyPart, Node node, Collection data)
       {
           if (!keyPart.hasNext())
           {
  @@ -511,16 +510,15 @@
               {
                   if (keyPart.getIndex() < children.size() && keyPart.getIndex() >= 0)
                   {
  -                    findPropertyNodes((ConfigurationKey.KeyIterator) keyPart.clone(),
  -                            (Node) children.get(keyPart.getIndex()), data);
  +                    findPropertyNodes((ConfigurationKey.KeyIterator) keyPart.clone(), (Node) children.get(keyPart
  +                            .getIndex()), data);
                   }
               }
               else
               {
                   for (Iterator it = children.iterator(); it.hasNext();)
                   {
  -                    findPropertyNodes((ConfigurationKey.KeyIterator) keyPart.clone(), (Node) it
  -                            .next(), data);
  +                    findPropertyNodes((ConfigurationKey.KeyIterator) keyPart.clone(), (Node) it.next(), data);
                   }
               }
           }
  @@ -685,9 +683,10 @@
   
           /** Stores the children of this node. */
           private LinkedMap children; // Explict type here or we
  -							        // will get a findbugs error
  -							        // because Map doesn't imply
  -							        // Serializable
  +
  +        // will get a findbugs error
  +        // because Map doesn't imply
  +        // Serializable
   
           /**
            * Creates a new instance of <code>Node</code>.
  @@ -930,11 +929,12 @@
           {
               if (children != null)
               {
  -                for (Iterator it = children.values().iterator(); it.hasNext();)
  +                Iterator it = children.values().iterator();
  +                children = null;
  +                while (it.hasNext())
                   {
                       nodesRemoved((Collection) it.next());
                   }
  -                children = null;
               }
           }
   
  @@ -965,8 +965,7 @@
   
               if (children != null)
               {
  -                for (Iterator it = children.values().iterator(); it.hasNext()
  -                        && !visitor.terminate();)
  +                for (Iterator it = children.values().iterator(); it.hasNext() && !visitor.terminate();)
                   {
                       Collection col = (Collection) it.next();
                       for (Iterator it2 = col.iterator(); it2.hasNext() && !visitor.terminate();)
  @@ -1325,10 +1324,13 @@
                       for (Iterator it = newNodes.iterator(); it.hasNext();)
                       {
                           Node insertNode = (Node) it.next();
  -                        Object ref = insert(insertNode, node, sibling1, sibling2);
  -                        if (ref != null)
  +                        if (insertNode.getReference() == null)
                           {
  -                            insertNode.setReference(ref);
  +                            Object ref = insert(insertNode, node, sibling1, sibling2);
  +                            if (ref != null)
  +                            {
  +                                insertNode.setReference(ref);
  +                            }
                           }
                       }
                   }
  
  
  
  1.5       +6 -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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestHierarchicalXMLConfiguration.java	13 Dec 2004 16:40:14 -0000	1.4
  +++ TestHierarchicalXMLConfiguration.java	18 Dec 2004 16:33:03 -0000	1.5
  @@ -53,7 +53,7 @@
       private static final String TEST_SAVENAME = "testhierarchicalsave.xml";
   
       /** File path for saving.*/
  -    private static final String TEST_SAVE = TEST_DIR + File.separator + TEST_SAVENAME;
  +    private static final String TEST_SAVE = "target" + File.separator + TEST_SAVENAME;
   
       /** Instance config used for tests. */
       private HierarchicalXMLConfiguration config;
  @@ -247,6 +247,8 @@
           config.addProperty("list(1).sublist.item", "seven");
           config.setProperty("clear", "yes");
           config.setProperty("mean", "now it's simple");
  +        config.addProperty("[@topattr]", "available");
  +        config.addProperty("[@topattr]", "successfull");
   
           removeTestSaveFile();
           try
  @@ -264,6 +266,8 @@
               assertEquals("seven", config.getProperty("list(1).sublist.item(2)"));
               assertEquals("yes", config.getProperty("clear"));
               assertEquals("now it's simple", config.getString("mean"));
  +            assertEquals("available", config.getString("[@topattr](0)"));
  +            assertEquals("successfull", config.getString("[@topattr](1)"));
           }
           finally
           {
  
  
  

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