epugh       2004/01/16 06:56:45

  Modified:    configuration/xdocs changes.xml examples.xml overview.xml
               configuration/src/java/org/apache/commons/configuration
                        CompositeConfiguration.java
                        ConfigurationFactory.java
               configuration/conf testDigesterConfiguration2.xml
  Removed:     configuration/src/java/org/apache/commons/configuration
                        ConfigurationXMLDocument.java
               configuration/conf testConfigurationXMLDocument.xml
                        testDigesterCreateObject.xml
               configuration/src/test/org/apache/commons/configuration
                        TestConfigurationXMLDocument.java
  Log:
  - new class ConfigurationXMLDocument including test case
  - Removed className attribute in configuration definition file for
  ConfigurationFactory
  - New element <hierarchicalDom4j> in configuration definition file
  - Updates and enhancements of documentation
  
  Revision  Changes    Path
  1.3       +4 -0      jakarta-commons/configuration/xdocs/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- changes.xml       24 Dec 2003 14:28:21 -0000      1.2
  +++ changes.xml       16 Jan 2004 14:56:45 -0000      1.3
  @@ -7,6 +7,10 @@
   
     <body>
       <release version="1.0-dev-4" date="">
  +      <action dev="oheger" type="add">
  +             ConfigurationFactory now supports the hierarchicalDom4j element in 
configuration 
  +             definition file
  +     </action>       
         <action dev="ebourg" type="update">
                Change all Vector objects to List objects.
        </action>       
  
  
  
  1.3       +10 -545   jakarta-commons/configuration/xdocs/examples.xml
  
  Index: examples.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/xdocs/examples.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- examples.xml      24 Dec 2003 14:28:21 -0000      1.2
  +++ examples.xml      16 Jan 2004 14:56:45 -0000      1.3
  @@ -428,13 +428,14 @@
   <configuration>
     <properties fileName="usergui.properties"/>
     <dom4j fileName="gui.xml"/>
  -  <hierarchicalDom4j fileName="tables.xml"/>
  +  <dom4j className="org.apache.commons.configuration.HierarchicalDOM4JConfiguration"
  +   fileName="tables.xml"/>
   </configuration>
   ]]>
                        </source>
                        <p>
  -                             Note that one <code>dom4j</code> element was replaced 
by a
  -                             <code>hierarchicalDom4j</code> element. This element 
tells the configuration
  +                             Note the additional <code>className</code> attribute 
of the last
  +                             <code>dom4j</code> element. This attribute tells the 
configuration
                                factory that not the default class for processing XML 
documents
                                should be used, but the class 
<code>HierarchicalDOM4JConfiguration</code>.
                                As the name implies this class is capable of saving the
  @@ -506,7 +507,7 @@
                                and do not have a complex structure the default XML 
configuration
                                class is suitable. If documents are more complex and 
their structure
                                is important, the hierarchy aware class should be 
used, which is
  -                             selected by the <code>hierarchicalDom4j</code> element 
as
  +                             enabled by an additional <code>className</code> 
attribute as
                                shown in the example configuration definition file 
above.
                        </p>
                </subsection>
  @@ -604,8 +605,10 @@
     </override>
     
     <additional>
  -    <hierarchicalDom4j fileName="tables.xml"/>
  -    <hierarchicalDom4j fileName="tasktables.xml" at="tables"/>
  +    <dom4j 
className="org.apache.commons.configuration.HierarchicalDOM4JConfiguration"
  +     fileName="tables.xml"/>
  +    <dom4j 
className="org.apache.commons.configuration.HierarchicalDOM4JConfiguration"
  +     fileName="tasktables.xml" at="tables"/>
     </additional>
   </configuration>
   ]]>
  @@ -614,7 +617,7 @@
                        Compared to the older versions of this file a couple of 
changes has been
                        done. One major difference is that the elements for including 
configuration
                        sources are no longer direct children of the root element, but 
are now
  -                     contained in either an <code>override</code> or 
<code>additonal</code>
  +                     contained in either an <code>override</code> or 
<code>additional</code>
                        section. The names of these sections already imply their 
purpose.
                </p>
                <p>
  @@ -658,544 +661,6 @@
                        higher priority (otherwise they could not override the values 
of other
                        sources).
                </p>
  -     </section>
  -     
  -     <section name="XML processing">
  -             <p>
  -                     We have now loaded some configuration sources and accessed 
some of the
  -                     properties. What else can we do? One additional feature 
provided by
  -                     Configuration is its support for XML-like processing of 
<code>Configuration</code>
  -                     objects that is implemented by the 
<code>ConfigurationXMLDocument</code>
  -                     class. The XML format for data exchange has become very 
popular, so there
  -                     are many use cases why you may want a XML-like view for your 
configuration.
  -                     This section shows how to make use of these features.
  -             </p>
  -             <subsection name="Basic XML access">
  -                     <p>
  -                             When it comes to XML processing of configuration 
sources the
  -                             <code>ConfigurationXMLDocument</code> class is usually 
involved.
  -                             When an instance of this class is created a 
<code>Configuration</code>
  -                             object is passed to the constructor. All operations 
executed on the
  -                             instance are then related to this configuration or a 
subset of it.
  -                     </p>
  -                     <p>
  -                             The most fundamental operation for treating a 
configuration source
  -                             as a XML document is to request a 
<code>ConfigurationXMLReader</code>
  -                             object from the <code>ConfigurationXMLDocument</code> 
instance.
  -                             The object returned by this method implements the
  -                             <code>org.xml.sax.XMLReader</code> interface and thus 
is a SAX 2
  -                             conform XML parser. This parser can then be passed to 
components
  -                             that can deal with SAX events. The following snippet 
shows how such
  -                             a SAX parser can be obtained:
  -                     </p>
  -                     <source>
  -<![CDATA[
  -ConfigurationXMLDocument configDoc = new ConfigurationXMLDocument(config);
  -XMLReader reader = configDoc.createXMLReader();
  -
  -// or:
  -// XMLReader reader = configDoc.createXMLReader("tables");
  -// Now do something with the reader
  -...
  -]]>
  -                     </source>
  -                     <p>
  -                             As this example shows it is either possible to obtain 
a reader object
  -                             for the whole configuration or for a subset of it. The 
obtained object
  -                             can now be used where ever a SAX parser is supported. 
There is
  -                             only one thing to mention: The <code>XMLReader</code> 
returned
  -                             by <code>createXMLReader()</code> has been initialized 
with the
  -                             configuration source (or a subset of it) stored in the
  -                             <code>ConfigurationXMLDocument</code> instance. If now 
one of the
  -                             <code>parse()</code> methods is called, the passed in 
argument,
  -                             which usually specifies the input source to parse, is 
ignored. This
  -                             information is unnecessary because all parsing is 
always done on
  -                             the associated <code>Configuration</code> object. 
Later in this section
  -                             this fact should become clearer.
  -                     </p>
  -             </subsection>
  -             <subsection name="Working with documents">
  -                     <p>
  -                             SAX may be the most efficient, but it is surely not 
the most convenient
  -                             way of XML processing. If a document with a complex 
structure is to
  -                             be navigated, a DOM based approach is usually more 
suitable.
  -                     </p>
  -                     <p>
  -                             <code>ConfigurationXMLDocument</code> provides a 
couple of
  -                             overloaded <code>getDocument()</code> methods that 
return a dom4j
  -                             <code>Document</code> object. The arguments that can 
be passed to
  -                             these methods allow to select a subset of the 
configuration source and
  -                             to specify the name of the resulting document's root 
element. The following
  -                             code fragment provides an example:
  -                     </p>
  -                     <source>
  -<![CDATA[
  -ConfigurationXMLDocument configDoc = new ConfigurationXMLDocument(config);
  -Document doc = configDoc.getDocument("tables", "database");
  -...
  -]]>
  -                     </source>
  -                     <p>
  -                             The <code>Document</code> returned here contains all 
data below the
  -                             <em>tables</em> section, i.e. it will have the root 
element <em>database</em>
  -                             with three <em>table</em> elements as children. In 
addition to the
  -                             <code>getDocument()</code> methods there is also a set 
of
  -                             <code>getW3cDocument()</code> methods. These methods 
act in an
  -                             analogous way, but return a 
<code>org.w3c.dom.Document</code> object
  -                             rather than a dom4j document.
  -                     </p>
  -                     <p>
  -                             Once a DOM document has been obtained the whole world 
of DOM processing
  -                             is open. Especially dom4j allows for powerful and 
convenient manipulations,
  -                             e.g. the document could be transformed using a 
stylesheet or written to
  -                             a file. If a configuration source or parts of it 
should simply be saved as
  -                             a XML document, there is an even easier way: the 
<code>write()</code>
  -                             methods of <code>ConfigurationXMLDocument</code>. 
Let's assume our
  -                             example application wants to send its database table 
definitions to an
  -                             external tool, maybe to initialize the database 
schema. The following code
  -                             shows how an XML file with this information could be 
written:
  -                     </p>
  -                     <source>
  -<![CDATA[
  -ConfigurationXMLDocument configDoc = new ConfigurationXMLDocument(config);
  -Writer out = null;
  -try
  -{
  -    out = new BufferedWriter(new FileWriter("tabledef.xml"));
  -    configDoc.write(out, "tables", "database");
  -}
  -finally
  -{
  -    out.close();
  -}
  -]]>
  -                     </source>
  -             </subsection>
  -             <subsection name="Calling Digester">
  -                     <p>
  -                             <em>Commons Digester</em> is another Apache Jakarta 
project that
  -                             implements a powerful engine for processing XML 
documents. In this section
  -                             we will make use of Digester to transform the table 
definitions into a
  -                             corresponding object model. For this tutorial the 
interesting part is
  -                             the stuff related to the communication with Digester; 
more information
  -                             about Digester and its features can be found at the 
homepage of the
  -                             Digester project.
  -                     </p>
  -                     <p>
  -                             We start with with the definition of a set of beans 
that will later store
  -                             information about the database tables and their 
fields. To keep this
  -                             example short these are very simple classes with 
hardly more than
  -                             a couple of getter and setter methods. As you can see 
there are
  -                             corresponding properties for all elements that can 
appear in the
  -                             table configuration.
  -                     </p>
  -                     <source>
  -<![CDATA[
  -public class TestConfigurationXMLDocument
  -{
  -    /** Stores the tables.*/
  -    private ArrayList tables;
  -    
  -    /**
  -     * Adds a new table object. Called by Digester.
  -     * @param table the new table
  -     */
  -    public void addTable(Table table)
  -    {
  -        tables.add(table);
  -    }
  -
  -    /**
  -     * A simple bean class for storing information about a table field.
  -     * Used for the Digester test.
  -     */
  -    public static class TableField
  -    {
  -        private String name;
  -        private String type;
  -        
  -        public String getName()
  -        {
  -            return name;
  -        }
  -
  -        public String getType()
  -        {
  -            return type;
  -        }
  -
  -        public void setName(String string)
  -        {
  -            name = string;
  -        }
  -
  -        public void setType(String string)
  -        {
  -            type = string;
  -        }
  -    }
  -    
  -    /**
  -     * A simple bean class for storing information about a database table.
  -     * Used for the Digester test.
  -     */
  -    public static class Table
  -    {
  -        /** Stores the list of fields.*/
  -        private ArrayList fields;
  -        
  -        /** Stores the table name.*/
  -        private String name;
  -        
  -        /** Stores the table type.*/
  -        private String tableType;
  -        
  -        public Table()
  -        {
  -            fields = new ArrayList();
  -        }
  -        
  -        public String getName()
  -        {
  -            return name;
  -        }
  -
  -        public String getTableType()
  -        {
  -            return tableType;
  -        }
  -
  -        public void setName(String string)
  -        {
  -            name = string;
  -        }
  -
  -        public void setTableType(String string)
  -        {
  -            tableType = string;
  -        }
  -        
  -        /**
  -         * Adds a field.
  -         * @param field the new field
  -         */
  -        public void addField(TableField field)
  -        {
  -            fields.add(field);
  -        }
  -        
  -        /**
  -         * Returns the field with the given index.
  -         * @param idx the index
  -         * @return the field with this index
  -         */
  -        public TableField getField(int idx)
  -        {
  -            return (TableField) fields.get(idx);
  -        }
  -        
  -        /**
  -         * Returns the number of fields.
  -         * @return the number of fields
  -         */
  -        public int size()
  -        {
  -            return fields.size();
  -        }
  -    }
  -}
  -]]>
  -                     </source>
  -                     <p>
  -                             While <code>TableField</code> is almost trivial, 
<code>Table</code>
  -                             provides the ability of storing a number of field 
objects in an internal
  -                             collection. The test class also defines a collection 
that will later
  -                             store the <code>Table</code> objects created from the 
configuration.
  -                     </p>
  -                     <p>
  -                             To pass the table configuration to Digester we have to
  -                             <ol>
  -                                     <li>
  -                                             Ask our 
<code>ConfigurationXMLDocument</code> instance for
  -                                             a <code>XMLReader</code> for the 
<em>tables</em> section.
  -                                     </li>
  -                                     <li>
  -                                             Construct a new Digester object and 
pass this XML reader to
  -                                             the constructor.
  -                                     </li>
  -                                     <li>
  -                                             Initialize the Digester instance with 
the necessary processing rules
  -                                             to create a corresponding object 
hierarchy for the table definitions.
  -                                     </li>
  -                                     <li>
  -                                             Call the Digester's 
<code>parse()</code> method to initiate
  -                                             processing.
  -                                     </li>
  -                             </ol>
  -                             The following listing shows the implementation of 
these steps:
  -                     </p>
  -                     <source>
  -<![CDATA[
  -    public void testCallDigesterComplex() throws Exception
  -    {
  -        Digester digester = 
  -            new Digester(configDoc.createXMLReader("tables"));
  -        digester.addObjectCreate("config/table", Table.class);
  -        digester.addSetProperties("config/table");
  -        digester.addCallMethod("config/table/name", "setName", 0);
  -        digester.addObjectCreate("config/table/fields/field", TableField.class);
  -        digester.addCallMethod("config/table/fields/field/name",
  -            "setName", 0);
  -        digester.addCallMethod("config/table/fields/field/type",
  -            "setType", 0);
  -        digester.addSetNext("config/table/fields/field",
  -            "addField", TableField.class.getName());
  -        digester.addSetNext("config/table", "addTable", Table.class.getName());
  -        
  -        digester.push(this);
  -        digester.parse("config");
  -    }
  -]]>
  -                     </source>
  -                     <p>
  -                             At the beginning of this listing 
<code>createXMLReader()</code>
  -                             is called on the <code>ConfigurationXMLDocument</code> 
instance
  -                             to obtain a SAX parser for the configuration subset 
with the table
  -                             definitions. When the Digester object is created this 
parser is passed
  -                             to its constructor.
  -                     </p>
  -                     <p>
  -                             The major part of the fragment deals with setting up 
the necessary
  -                             Digester rules. Details for that can be found in the 
Digester documentation.
  -                             In short we define rules to create <code>Table</code> 
and
  -                             <code>TableField</code> objects when the corresponding 
XML elements
  -                             are detected. The newly created objects are 
initialized with the
  -                             properties defined in the XML code. Then it is ensured 
that a new
  -                             <code>TableField</code> object is added to a 
<code>Table</code>
  -                             and that for each new <code>Table</code> object the
  -                             <code>addTable()</code> method of the test class is 
invoked.
  -                             This all conforms to the default usage pattern of 
Digester, only two
  -                             points should be noticed:
  -                     </p>
  -                     <p>
  -                             <ul>
  -                                     <li>
  -                                             The match strings for all Digester 
rules have the prefix
  -                                             <em>config/table</em>. The reason for 
this is that the XML document
  -                                             that is generated by the SAX parser 
has a corresponding structure.
  -                                             Remember when we called 
<code>createXMLReader()</code>, we
  -                                             specified the string <em>tables</em> 
as argument. This means that
  -                                             the resulting document will have all 
the content that can be found
  -                                             in the configuration under the key 
<em>tables</em>, which happens
  -                                             to be three <em>table</em> elements 
with their corresponding
  -                                             children. The root element of this 
document is named <em>config</em>.
  -                                             This is the default name of the root 
element if no other name is
  -                                             specified. If we had called 
<code>createXMLReader("tables", "tabledef")</code>,
  -                                             the root element would have been named 
<em>tabledef</em> and
  -                                             we would have to use match strings of 
the form <em>tabledef/table</em>.
  -                                     </li>
  -                                     <li>
  -                                             The call of the Digester's 
<code>parse()</code> method is a little
  -                                             strange because we only pass in the 
string <em>config</em> as
  -                                             argument. Fact is that if a 
<code>XMLReader</code> obtained
  -                                             from 
<code>ConfigurationXMLDocument</code> is involved, the
  -                                             parameter of the <code>parse()</code> 
method is completely
  -                                             ignored. The reader always refers to 
the configuration source it
  -                                             was constructed for. So we could have 
used an arbitrary string.
  -                                     </li>
  -                             </ul>
  -                     </p>
  -                     <p>
  -                             After the <code>parse()</code> method returns the 
<code>tables</code>
  -                             collection of the test class contains three 
<code>Table</code> objects
  -                             with all information specified in the configuration.
  -                     </p>
  -             </subsection>
  -             <subsection name="Calling Digester for creating simple objects">
  -                     <p>
  -                             If an application's configuration defines complex 
objects that should
  -                             be instantiated using Digester it will usually be 
necessary to provide
  -                             specific Digester rules as shown in the last section. 
But another
  -                             use case is to create an object whose class name is 
defined in the
  -                             configuration and to perform some simple 
initialization on it.
  -                     </p>
  -                     <p>
  -                             Imagine the example database application wants to open 
a connection to
  -                             a database. Because it is a very sophisticated 
application it supports
  -                             lots of different databases. To achieve this there is 
an abstract
  -                             <code>ConnectionInfo</code> class that provides 
typical connect
  -                             properties (such as user name, password and the name 
of the database)
  -                             and an abstract <code>connect()</code> method, which 
establishes
  -                             the connection to the database:
  -                     </p>
  -                     <source>
  -<![CDATA[
  -    public abstract class ConnectionInfo
  -    {
  -        private String dsn;
  -        private String user;
  -        private String passwd;
  -        
  -        public String getDsn()
  -        {
  -            return dsn;
  -        }
  -
  -        public String getPasswd()
  -        {
  -            return passwd;
  -        }
  -
  -        public String getUser()
  -        {
  -            return user;
  -        }
  -
  -        public void setDsn(String string)
  -        {
  -            dsn = string;
  -        }
  -
  -        public void setPasswd(String string)
  -        {
  -            passwd = string;
  -        }
  -
  -        public void setUser(String string)
  -        {
  -            user = string;
  -        }
  -        
  -        /**
  -         * Creates a connection to a database.
  -         * Must be defined in sub classes.
  -         * @return the created connection
  -         */
  -        public abstract Connection createConnection() throws SQLException;
  -    }
  -]]>
  -                     </source>
  -                     <p>
  -                             There are now some sub classes of this class, one for 
each supported
  -                             database with a proper implementation of 
<code>createConnection()</code>.
  -                             When the example application is run it does not know 
from start,
  -                             which database it has to access. Instead it determines 
the database
  -                             driver class from a configuration property, creates an 
instance of it,
  -                             and uses it to obtain a connection. For this use case 
the
  -                             <code>callDigester()</code> method of 
<code>ConfigurationXMLDocument</code>
  -                             was designed.
  -                     </p>
  -                     <p>
  -                             To demonstrate this feature we start with an 
additional configuration source
  -                             that defines the connection of the database to be 
used. We call it
  -                             <code>connection.xml</code>.
  -                     </p>
  -                     <source>
  -<![CDATA[
  -<?xml version="1.0" encoding="UTF-8"?>
  -<configuration>
  -     <connection>
  -             <class name="myapp.ConnectionInfoOracle">
  -                     <property name="dsn" value="MyData"/>
  -                     <property name="user" value="scott"/>
  -                     <property name="passwd" value="tiger"/>
  -             </class>
  -     </connection>
  -</configuration>
  -]]>
  -                     </source>
  -                     <p>
  -                             This configuration file shows the typical structure of 
XML code
  -                             that defines an object to be created using Digester: 
There must be
  -                             a <code>class</code> element with a <code>name</code> 
attribute
  -                             defining the full qualified name of the class to be 
instantiated. In the
  -                             body of the <code>class</code> element there can be an 
arbitrary
  -                             number of <code>property</code> elements. Each element 
defines
  -                             the name and value of a property to be set, so 
Digester will call a
  -                             corresponding setter method on the bean just created. 
Here we set
  -                             properties with the names <em>dsn, user</em> and 
<em>passwd</em>.
  -                             As you can see, our <code>ConnectionInfo</code> base 
class has
  -                             getter and setter methods for exactly these 
properties. We have now to
  -                             include this additional configuration file in our 
configuration definition file:
  -                     </p>
  -                     <source>
  -<![CDATA[
  -<?xml version="1.0" encoding="ISO-8859-1" ?>
  -<!-- Configuration definition file that demonstrates the
  -     override and additional sections -->
  -
  -<configuration>
  -  <override>
  -    <properties fileName="usergui.properties"/>
  -    <dom4j fileName="gui.xml"/>
  -  </override>
  -  
  -  <additional>
  -    <hierarchicalDom4j fileName="tables.xml"/>
  -    <hierarchicalDom4j fileName="tasktables.xml" at="tables"/>
  -    <hierarchicalDom4j fileName="connection.xml"/>
  -  </additional>
  -</configuration>
  -]]>
  -                     </source>
  -                     <p>
  -                             After that it is now quite easy to obtain an object 
with information
  -                             about a database connection. The following code 
fragment shows
  -                             how a connection can be opened (it assumes that the 
<code>Configuration</code>
  -                             object obtained from the configuration factory is 
stored in a variable named
  -                             <code>config</code>).
  -                     </p>
  -                     <source>
  -<![CDATA[
  -ConfigurationXMLDocument configDoc = new ConfigurationXMLDocument(config);
  -ConnectionInfo connInfo = (ConnectionInfo) configDoc.callDigester("connection");
  -Connection conn = connInfo.createConnection();
  -]]>
  -                     </source>
  -             </subsection>
  -             <subsection name="Some caveats">
  -                     <p>
  -                             At the end of this section about 
<code>ConfigurationXMLDocument</code>
  -                             some notes about points a developer should be aware of 
are provided:
  -                     </p>
  -                     <p>
  -                             <ul>
  -                                     <li>
  -                                             The class should not be used on the 
<code>Configuration</code>
  -                                             object obtained from 
<code>ConfigurationFactory</code> as a
  -                                             whole. Because this configuration can 
contain multiple configuration
  -                                             sources including those that override 
other properties the results
  -                                             are probably not what you expect. You 
can of course pass such a
  -                                             composite configuration to the 
constructor of
  -                                             <code>ConfigurationXMLDocument</code>, 
but you should then,
  -                                             when you call methods on this 
instance, always provide a
  -                                             configuration key that selects certain 
parts of the configuration.
  -                                     </li>
  -                                     <li>
  -                                             The XML processing abilities of the 
class naturally work best
  -                                             when a 
<code>HierarchicalConfiguration</code> object is
  -                                             involved. There is also support for 
other types of configuration
  -                                             sources, but this will work well only 
for very simple properties.
  -                                             The problem here is the loss of 
information concerning the
  -                                             structure of the properties (as was 
explained in an earlier secion). 
  -                                             So if you read a configuration source
  -                                             using the <code>dom4j</code> element 
rather than the
  -                                             <code>hierarchicalDom4j</code> 
element, XML documents
  -                                             generated by 
<code>ConfigurationXMLDocument</code> may
  -                                             look wired; the same is true for 
<code>properties</code>
  -                                             elements.
  -                                     </li>
  -                                     <li>
  -                                             If you read a XML configuration file 
and then save it again
  -                                             using 
<code>ConfigurationXMLDocument.write()</code> the
  -                                             result is not guaranteed to be identic 
to the original file.
  -                                             While the document structure is kept 
(i.e. the relation between
  -                                             elements and their children), there 
may be differences in the
  -                                             order in which elements are written.
  -                                     </li>
  -                             </ul>
  -                     </p>
  -             </subsection>
        </section>
   </body>
   
  
  
  
  1.2       +6 -6      jakarta-commons/configuration/xdocs/overview.xml
  
  Index: overview.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/configuration/xdocs/overview.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- overview.xml      23 Dec 2003 15:09:05 -0000      1.1
  +++ overview.xml      16 Jan 2004 14:56:45 -0000      1.2
  @@ -67,9 +67,9 @@
   <?xml version="1.0" encoding="ISO-8859-1" ?>
   
   <configuration>
  -  <jndi prefix="java:comp/env"/>
  -  <properties fileName="conf/test.properties"/>
  -  <dom4j fileName="conf/test.xml"/>
  +  <jndi className="org.apache.commons.configuration.JNDIConfiguration" 
prefix="java:comp/env"/>
  +  <properties className="org.apache.commons.configuration.PropertiesConfiguration" 
fileName="conf/test.properties"/>
  +  <dom4j className="org.apache.commons.configuration.DOM4JConfiguration" 
fileName="conf/test.xml"/>
   </configuration>
   ]]>   
           </source>
  @@ -96,7 +96,7 @@
        <subsection name="Classic Properties File">
           <source>
   <![CDATA[       
  -  <properties fileName="conf/test.properties"/>
  +  <properties className="org.apache.commons.configuration.PropertiesConfiguration" 
fileName="conf/test.properties"/>
   ]]>   
           </source>
           <p>
  @@ -106,7 +106,7 @@
        <subsection name="XML Properties File">
           <source>
   <![CDATA[       
  -  <dom4j fileName="conf/test.xml"/>
  +  <dom4j className="org.apache.commons.configuration.DOM4JConfiguration" 
fileName="conf/test.xml"/>
   ]]>   
           </source>            
           <p>
  @@ -136,7 +136,7 @@
        <subsection name="JNDI Properties File">
           <source>
   <![CDATA[       
  -  <jndi prefix="java:comp/env"/>
  +  <jndi className="org.apache.commons.configuration.JNDIConfiguration" 
prefix="java:comp/env"/>
   ]]>   
           </source>            
           <p>
  
  
  
  1.3       +2 -6      
jakarta-commons/configuration/src/java/org/apache/commons/configuration/CompositeConfiguration.java
  
  Index: CompositeConfiguration.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/CompositeConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- CompositeConfiguration.java       24 Dec 2003 14:28:22 -0000      1.2
  +++ CompositeConfiguration.java       16 Jan 2004 14:56:45 -0000      1.3
  @@ -271,8 +271,6 @@
       {
           CompositeConfiguration subsetCompositeConfiguration =
               new CompositeConfiguration();
  -        Configuration subConf = null;
  -        int count = 0;
           for (ListIterator i = configList.listIterator(); i.hasNext();)
           {
               Configuration config = (Configuration) i.next();
  @@ -280,11 +278,9 @@
               if (subset != null)
               {
                   subsetCompositeConfiguration.addConfiguration(subset);
  -                subConf = subset;
  -                count++;
               }
           }
  -        return (count == 1) ? subConf : subsetCompositeConfiguration;
  +        return subsetCompositeConfiguration;
       }
       /**
       * Get a float associated with the given configuration key.
  
  
  
  1.3       +18 -11    
jakarta-commons/configuration/src/java/org/apache/commons/configuration/ConfigurationFactory.java
  
  Index: ConfigurationFactory.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/ConfigurationFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ConfigurationFactory.java 24 Dec 2003 14:28:22 -0000      1.2
  +++ ConfigurationFactory.java 16 Jan 2004 14:56:45 -0000      1.3
  @@ -291,12 +291,6 @@
               additional);
           setupDigesterInstance(
               digester,
  -            matchString + "hierarchicalDom4j",
  -            new BasePathConfigurationFactory(HierarchicalDOM4JConfiguration.class),
  -            METH_LOAD,
  -            additional);
  -        setupDigesterInstance(
  -            digester,
               matchString + "jndi",
               new JNDIConfigurationFactory(),
               null,
  @@ -418,13 +412,17 @@
   
       /**
        * A base class for digester factory classes. This base class maintains
  -     * a default class for the objects to be created.
  +     * a default class for the objects to be created. It also supports a
  +     * <code>className</code> attribute for specifying a different class.
        * There will be sub classes for specific configuration implementations.
        */
       public class DigesterConfigurationFactory
           extends AbstractObjectCreationFactory
           implements ObjectCreationFactory
       {
  +        /** Constant for the className attribute.*/
  +        protected static final String ATTR_CLASSNAME = "className";
  +
           /** Actual class to use. */
           private Class clazz;
   
  @@ -438,14 +436,23 @@
           }
   
           /**
  -         * Creates an instance of the specified class.
  -         * @param attribs the attributes (ignored)
  +         * Creates an instance of the specified class. If the passed in
  +         * attributes contain a <code>className</code> attribute, the value of
  +         * this attribute is interpreted as the full qualified class name of
  +         * the class to be instantiated. Otherwise the default class is used.
  +         * @param attribs the attributes
            * @return the new object
            * @exception Exception if object creation fails
            */
           public Object createObject(Attributes attribs) throws Exception
           {
  -            return clazz.newInstance();
  +            Class actCls;
  +            
  +            int idx = attribs.getIndex(ATTR_CLASSNAME);
  +            actCls = (idx < 0) ? clazz :
  +            Class.forName(attribs.getValue(idx));
  +
  +            return actCls.newInstance();
           }
       }
   
  
  
  
  1.2       +2 -2      
jakarta-commons/configuration/conf/testDigesterConfiguration2.xml
  
  Index: testDigesterConfiguration2.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/configuration/conf/testDigesterConfiguration2.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- testDigesterConfiguration2.xml    23 Dec 2003 15:09:05 -0000      1.1
  +++ testDigesterConfiguration2.xml    16 Jan 2004 14:56:45 -0000      1.2
  @@ -4,8 +4,8 @@
   
   <configuration>
     <additional>
  -    <hierarchicalDom4j fileName="testHierarchicalDOM4JConfiguration.xml"/>
  -    <hierarchicalDom4j fileName="testDigesterConfigurationInclude1.xml" 
at="tables"/>
  +    <dom4j 
className="org.apache.commons.configuration.HierarchicalDOM4JConfiguration" 
fileName="testHierarchicalDOM4JConfiguration.xml"/>
  +    <dom4j 
className="org.apache.commons.configuration.HierarchicalDOM4JConfiguration" 
fileName="testDigesterConfigurationInclude1.xml" at="tables"/>
       <properties fileName="testDigesterConfigurationInclude2.properties" at="mail"/>
     </additional>
   
  
  
  

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

Reply via email to