I had a short glance at your code (not much time ATM). This seems to be similar to my own ideas. Comments inline.

Emmanuel Bourg wrote:
[snip]

- a ConfigurationNode interface is introduced, it's an abstract node with basic navigation methods like getElements(), createNode(), getName(). Its implementations will wrap a real node, that's a JNDI Context or a DOM Element for example.
If this ConfigurationNode interface was more powerful, it would support generalized update methods (like setProperty(), addProperty()), too. I attach my version from my hierarchical design, which has some more methods. The methods dealing with attributes are a bit XML specific, but I think it can't be wrong to use XML as a model for a generic design. So the features of this format can be fully supported and other configuration sources that have no attributes can provide dummy implementations.


- JNDIConfiguration implements a TreeConfiguration interface. This interface exposes the getRootNode() method returning the root ConfigurationNode. We may put in this interface some methods defining the variations of behaviour between the hierarchical configurations (supportsXXX():boolean). For example with an XMLConfiguration, several child nodes can have the same name, this is not true for JNDIConfiguration or WindowsConfiguration, that means the search algorithm is slightly different.
I think a generic search algorithm should be implemented to deal with multiple occurences of child nodes. I don't like the idea of having if-clauses based on supportsXXX() flags. If a configuration source is restricted in this area, the specific implementation of the addChild() method could ensure that no douplicated entries are created.

The code in HierarchicalConfiguration could serve as an example for both the search and the add/update algorithm. With a generic node interface that also provides a method for creating new child nodes this code can be made generic.

One more point: Should we have a TreeConfiguration interface or add the few additional methods to Configuration? I think the major part of configuration sources will be hierarchical and the other ones can be seen as hierarchical structures with only one layer. If all Configuration classes provided a hierarchical view, there would be no need to make distinctions later when implementing features that make use of that (e.g. enhanced XML processing).


- JNDIConfiguration has a private implementation of ConfigurationNode, that's JNDIConfigurationNode.


- the search methods of JNDIConfiguration have been moved to TreeConfigurationUtils and now use the ConfigurationNode instead of the JNDI context.

- JNDIConfiguration delegates to TreeConfigurationUtils its implementations for getKeys and isEmpty.
I think it makes sense to have such a class like TreeConfigurationUtils. An alternative would be to create a base class AbstractTreeConfiguration, but the approach with the utility class is probably more flexible.


I'm attaching the resulting classes, the test cases still pass. I started looking at XMLConfiguration but it's a bit more complex.


Emmanuel Bourg

Oliver
package org.apache.commons.configuration.hierarchy;

/*
 * Copyright 2001-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.
 */

import java.util.List;

/**
 * <p>Definition of an interface that allows hierarchical access to a
 * configuration.</p>
 * <p>This interface defines a tree like structure for configuration data. Each
 * <code>Configuration</code> implementation must provide such a tree like view
 * on its data.</p>
 *
 * @author Oliver Heger
 */
public interface ConfigurationNode 
{
    /**
     * Returns the name of this node.
     * @return the node name
     */
    String getName();
    
    /**
     * Sets the name of this node.
     * @param name the node name
     */
    void setName(String name);
    
    /**
     * Returns the value of this node.
     * @return the node's value
     */
    Object getValue();
    
    /**
     * Sets the value of this node.
     * @param val the node's value
     */
    void setValue(Object val);
    
    /**
     * Returns this node's parent. Can be <b>null</b>, then this node is the
     * top level node.
     * @return the parent of this node
     */
    ConfigurationNode getParent();
    
    /**
     * Sets the parent of this node.
     * @param parent the parent of this node
     */
    void setParent(ConfigurationNode parent);
    
    /**
     * Adds a child to this node.
     * @param node the new child
     */
    void addChild(ConfigurationNode node);
    
    /**
     * Returns a list with the child nodes of this node.
     * @return a list with the children of this node (never <b>null</b>)
     */
    List getChildren();
    
    /**
     * Returns the number of this node's children.
     * @return the number of the children of this node
     */
    int getChildrenCount();
    
    /**
     * Returns a list with all children of this node with the given name.
     * @param name the name of the searched children
     * @return a list with all child nodes with this name (never <b>null</b>)
     */
    List getChildren(String name);
    
    /**
     * Returns the number of children with the given name.
     * @param name the name
     * @return the number of children with this name
     */
    int getChildrenCount(String name);
    
    /**
     * Removes the given node from this node's children.
     * @param child the child node to be removed
     * @return a flag if the node could be removed
     */
    boolean remove(ConfigurationNode child);
    
    /**
     * Removes all child nodes of this node with the given name.
     * @param childName the name of the children to be removed
     * @return a flag if at least one child was removed
     */
    boolean remove(String childName);
    
    /**
     * Removes all children from this node.
     */
    void removeChildren();
    
    /**
     * Returns a flag whether this node is an attribute.
     * @return a flag whether this node is an attribute
     */
    boolean isAttribute();
    
    /**
     * Sets a flag whether this node is an attribute.
     * @param f the attribute flag
     */
    void setAttribute(boolean f);
    
    /**
     * Returns a list with this node's attributes. Attributes are also modeled
     * by <code>ConfigurationNode</code> objects.
     * @return a list with the attributes
     */
    List getAttributes();
    
    /**
     * Returns the attribute node with the given name.
     * @param name the name of the attribute
     * @return the attribute node with this name or <b>null</b> if the
     * attribute was not found
     */
    ConfigurationNode getAttribute(String name);
    
    /**
     * Adds the specified attribute to this node
     * @param attr the attribute node
     */
    void addAttribute(ConfigurationNode attr);
    
    /**
     * Returns a flag if this node is defined. This means that the node 
     * contains some data.
     * @return a flag whether this node is defined
     */
    boolean isDefined();
    
    /**
     * Visits this node and all its sub nodes. This method provides a simple
     * mean for going through a hierarchical structure of configuration nodes.
     * @see ConfigurationNodeVisitor
     * @param visitor the visitor
     */
    void visit(ConfigurationNodeVisitor visitor);
}

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

Reply via email to