You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by js...@apache.org on 2002/02/19 07:10:27 UTC

cvs commit: jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/digester/rss Channel.betwixt Channel.betwixt.xml

jstrachan    02/02/18 22:10:27

  Modified:    betwixt  OVERVIEW.html build.xml
               betwixt/src/java/org/apache/commons/betwixt
                        ElementDescriptor.java XMLBeanInfo.java
                        XMLIntrospector.java
               betwixt/src/java/org/apache/commons/betwixt/digester
                        ElementRule.java InfoRule.java
                        XMLBeanInfoDigester.java
               betwixt/src/java/org/apache/commons/betwixt/expression
                        Context.java MethodUpdater.java
               betwixt/src/java/org/apache/commons/betwixt/io
                        BeanCreateRule.java BeanReader.java BeanWriter.java
               betwixt/src/test/org/apache/commons/betwixt
                        CustomerBean.java TestAll.java TestBeanReader.java
                        TestBeanWriter.java TestXMLBeanInfoDigester.java
               betwixt/src/test/org/apache/commons/betwixt/expression
                        TestEvaluation.java
  Added:       betwixt/src/java/org/apache/commons/betwixt
                        ElementDescriptor.betwixt XMLBeanInfo.betwixt
               betwixt/src/java/org/apache/commons/betwixt/digester
                        AddDefaultsRule.java AttributeRule.java
                        HideRule.java RuleSupport.java
                        XMLIntrospectorHelper.java
               betwixt/src/test/org/apache/commons/betwixt
                        TestRSSRoundTrip.java
               betwixt/src/test/org/apache/commons/digester/rss
                        Channel.betwixt
  Removed:     betwixt/src/test/org/apache/commons/digester/rss
                        Channel.betwixt.xml
  Log:
  Got the XML document customizing the XMLBeanInfo just about working properly now. For example the RSS output looks pretty close to the required output. Added an RSS round trip test so that we can ensure that round tripping via Digester and Betwixt actually works. Though a couple of tests are currently failing. Will fix ASAP.
  
  Revision  Changes    Path
  1.2       +56 -1     jakarta-commons-sandbox/betwixt/OVERVIEW.html
  
  Index: OVERVIEW.html
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/OVERVIEW.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- OVERVIEW.html	31 Jan 2002 19:56:02 -0000	1.1
  +++ OVERVIEW.html	19 Feb 2002 06:10:26 -0000	1.2
  @@ -27,8 +27,63 @@
   create a Channel bean and then write it out again as XML using the default 
   XMLIntrospector and the BeanWriter. You should see the XML come out from the 
   Channel bean which looks similar to a real RSS document.</p>
  +<h2>Customizing the mapping of a bean to XML</h2>
  +
  +<p>The XMLIntrospector will look for files of the form <i>className.betwixt</i> 
  +on the classpath using the same ClassLoader used to load the given class and use 
  +that document to specify a types mapping to XML. If this file does not exist 
  +then the default introspection rules are used.</p>
  +<p>The simplest possible file may just set the name of the element. e.g.</p>
  +
  +<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
  +&lt;info&gt;
  +  &lt;element name=&quot;channel&quot;/&gt;
  +  &lt;addDefaults/&gt;
  +&lt;/info&gt;</pre>
  +
  +<p>The above means to use the name 'foo' for the outer most element for the 
  +given type. The &lt;addDefaults&gt; means to add the defaults from the introspector. 
  +This allows you to just rename a few properties then let the introspector do the 
  +rest. There is also a &lt;hide&gt; element which allows one or more properties to be 
  +hidden. Also note that the &lt;element&gt; and &lt;attribute&gt; tags can be hidden to any 
  +kind of depth allowing whatever XML structure you wish. This can be useful if 
  +you wish to wrap collections in some arbitrary collectino tags e.g.</p>
  +
  +<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
  +&lt;info primitiveTypes=&quot;attribute&quot;&gt;
  +  &lt;element name=&quot;channel&quot;/&gt;
  +    &lt;element name=&quot;customerList&quot;&gt;
  +      &lt;element name=&quot;customer&quot; property=&quot;customers&quot;/&gt;
  +    &lt;/element&gt;
  +    &lt;element name=&quot;foo&quot;&gt;
  +      &lt;element name=&quot;bar&quot; property=&quot;xyz&quot;/&gt;
  +    &lt;hide property=&quot;something&quot;/&gt;
  +    &lt;addDefaults/&gt;
  +  &lt;/element&gt;
  +&lt;/info&gt;
  +</pre>
  +
  +<p>The primitiveTypes attribute in the &lt;info&gt; element is optional and can be 
  +used to specify whether primitive java types (strings, numbers, dates etc) are 
  +specified as attributes or elements by default.</p>
  +<p>Finally static text can be specified using a value attribute inside an 
  +&lt;element&gt; or &lt;attribute&gt; tag. e.g. to add a version label to the 
  +generated XML...</p>
  +
  +<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
  +&lt;info primitiveTypes=&quot;element&quot;&gt;
  +  &lt;element name=&quot;rss&quot;/&gt;
  +    &lt;attribute name=&quot;version&quot; value=&quot;0.91&quot;/&gt;
  +    &lt;element name=&quot;channel&quot/&gt;
  +    &lt;addDefaults/&gt;
  +  &lt;/element&gt;
  +&lt;/info&gt;
  +</pre>
  +
  +<p>&nbsp;</p>
  +<p>&nbsp;</p>
   <p>&nbsp;</p>
   
   </body>
   
  -</html>
  +</html>
  \ No newline at end of file
  
  
  
  1.12      +13 -4     jakarta-commons-sandbox/betwixt/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/build.xml,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- build.xml	9 Feb 2002 11:52:15 -0000	1.11
  +++ build.xml	19 Feb 2002 06:10:26 -0000	1.12
  @@ -3,7 +3,7 @@
   
   <!--
           "Digester" component of the Jakarta Commons Subproject
  -        $Id: build.xml,v 1.11 2002/02/09 11:52:15 rdonkin Exp $
  +        $Id: build.xml,v 1.12 2002/02/19 06:10:26 jstrachan Exp $
   -->
   
   
  @@ -247,6 +247,7 @@
      description="Run all unit test cases">
       <java classname="org.apache.commons.betwixt.TestAll" fork="yes" failonerror="${test.failonerror}">
         <classpath refid="test.classpath"/>
  +      <sysproperty key="org.apache.commons.logging.simplelog.defaultlog" value="error"/>
       </java>
     </target>
   
  @@ -264,7 +265,7 @@
       <java classname="org.apache.commons.betwixt.TestBeanReader" fork="yes">
         <classpath refid="test.classpath"/>
           <!-- this all seems a bit much to get some logging? -->
  -      <sysproperty key="org.apache.commons.logging.log" value="org.apache.commons.logging.SimpleLog"/>
  +      <sysproperty key="org.apache.commons.logging.log" value="org.apache.commons.logging.impl.SimpleLog"/>
         <sysproperty key="org.apache.commons.logging.simplelog.defaultlog" value="debug"/>
         <sysproperty key="org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester" value="warn"/>
         <sysproperty key="org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester.sax" value="warn"/>
  @@ -276,8 +277,8 @@
         description="Runs the test of the XMLBeanInfo digester">
       <java classname="org.apache.commons.betwixt.TestXMLBeanInfoDigester" fork="yes">
         <classpath refid="test.classpath"/>
  -        <!-- this all seems a bit much to get some logging? -->
  -      <sysproperty key="org.apache.commons.logging.log" value="org.apache.commons.logging.SimpleLog"/>
  +        <!-- this all seems a bit much to get some logging? maybe a properties file might help -->
  +      <sysproperty key="org.apache.commons.logging.log" value="org.apache.commons.logging.impl.SimpleLog"/>
         <sysproperty key="org.apache.commons.logging.simplelog.defaultlog" value="debug"/>
         <sysproperty key="org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester" value="warn"/>
         <sysproperty key="org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester.sax" value="warn"/>
  @@ -308,6 +309,14 @@
       <echo message="Running the RSS sample..."/>
       <java classname="org.apache.commons.betwixt.RSSBeanWriter" fork="yes">
         <classpath refid="test.classpath"/>
  +        <!-- this all seems a bit much to get some logging? maybe a properties file might help -->
  +<!--
  +      <sysproperty key="org.apache.commons.logging.impl.log" value="org.apache.commons.logging.impl.SimpleLog"/>
  +-->
  +      <sysproperty key="org.apache.commons.logging.simplelog.defaultlog" value="debug"/>
  +      <sysproperty key="org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester" value="warn"/>
  +      <sysproperty key="org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester.sax" value="warn"/>
  +      <sysproperty key="org.apache.commons.logging.simplelog.defaultlog" value="debug"/>
       </java>
      </target>
   
  
  
  
  1.9       +113 -18   jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.java
  
  Index: ElementDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ElementDescriptor.java	7 Feb 2002 19:17:26 -0000	1.8
  +++ ElementDescriptor.java	19 Feb 2002 06:10:26 -0000	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.java,v 1.8 2002/02/07 19:17:26 jstrachan Exp $
  - * $Revision: 1.8 $
  - * $Date: 2002/02/07 19:17:26 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.java,v 1.9 2002/02/19 06:10:26 jstrachan Exp $
  + * $Revision: 1.9 $
  + * $Date: 2002/02/19 06:10:26 $
    *
    * ====================================================================
    *
  @@ -57,10 +57,13 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: ElementDescriptor.java,v 1.8 2002/02/07 19:17:26 jstrachan Exp $
  + * $Id: ElementDescriptor.java,v 1.9 2002/02/19 06:10:26 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  +import java.util.ArrayList;
  +import java.util.List;
  +
   import org.apache.commons.betwixt.expression.Expression;
   
   /** <p><code>ElementDescriptor</code> describes the XML elements
  @@ -70,15 +73,33 @@
     * and <code>ElementDescriptor</code>'s for it's child elements.
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.8 $
  +  * @version $Revision: 1.9 $
     */
   public class ElementDescriptor extends NodeDescriptor {
   
  -    /** Descriptors for element attributes */
  +    /** 
  +     * Descriptors for attributes this element contains.
  +     * Constructed lazily on demand from a List
  +     */
       private AttributeDescriptor[] attributeDescriptors;
  -    /** Descriptors for child elements */
  +    /** 
  +     * Descriptors for child elements.
  +     * Constructed lazily on demand from a List
  +     */
       private ElementDescriptor[] elementDescriptors;
       
  +    /** 
  +     * The List used on construction. It will be GC'd
  +     * after initilization and the array is lazily constructed
  +     */
  +    private List attributeList;
  +    
  +    /** 
  +     * The List used on construction. It will be GC'd
  +     * after initilization and the array is lazily constructed
  +     */
  +    private List elementList;
  +        
       /** the expression used to evaluate the new context of this node 
        * or null if the same context is to be used */
       private Expression contextExpression;
  @@ -118,39 +139,67 @@
           return attributeDescriptors != null && attributeDescriptors.length > 0;
       }
       
  +    public void addAttributeDescriptor(AttributeDescriptor descriptor) {
  +        if ( attributeList == null ) {
  +            attributeList = new ArrayList();
  +        }
  +        getAttributeList().add( descriptor );
  +        attributeDescriptors = null;
  +    }
  +    
  +    
       /** Returns the attribute descriptors for this element */
       public AttributeDescriptor[] getAttributeDescriptors() {
  +        if ( attributeDescriptors == null ) {
  +            if ( attributeList == null ) {
  +                attributeDescriptors = new AttributeDescriptor[0];
  +            }
  +            else {
  +                attributeDescriptors = new AttributeDescriptor[ attributeList.size() ];
  +                attributeList.toArray( attributeDescriptors );
  +                
  +                // allow GC of List when initialized
  +                attributeList = null;
  +            }
  +        }
           return attributeDescriptors;
       }
       
       /** Set <code>AttributesDescriptors</code> for this element */
       public void setAttributeDescriptors(AttributeDescriptor[] attributeDescriptors) {
           this.attributeDescriptors = attributeDescriptors;
  +        this.attributeList = null;
       }
       
       public void addElementDescriptor(ElementDescriptor descriptor) {
  -        // XXX: not a very efficient way of doing it. Maybe keep an internal List implementation
  -        
  -        if ( elementDescriptors == null ) {
  -            elementDescriptors = new ElementDescriptor[] { descriptor };
  -        }
  -        else {
  -            int size = elementDescriptors.length;
  -            ElementDescriptor[] newValue = new ElementDescriptor[ size + 1 ];
  -            System.arraycopy( elementDescriptors, 0, newValue, 0, size );
  -            newValue[size] = descriptor;
  -            elementDescriptors = newValue;
  +        if ( elementList == null ) {
  +            elementList = new ArrayList();
           }
  +        getElementList().add( descriptor );
  +        elementDescriptors = null;
       }
       
       /** Returns the child element descriptors for this element */
       public ElementDescriptor[] getElementDescriptors() {
  +        if ( elementDescriptors == null ) {
  +            if ( elementList == null ) {
  +                elementDescriptors = new ElementDescriptor[0];
  +            }
  +            else {
  +                elementDescriptors = new ElementDescriptor[ elementList.size() ];
  +                elementList.toArray( elementDescriptors );
  +                
  +                // allow GC of List when initialized
  +                elementList = null;
  +            }
  +        }
           return elementDescriptors;
       }
   
       /** Set descriptors for child element of this element */
       public void setElementDescriptors(ElementDescriptor[] elementDescriptors) {
           this.elementDescriptors = elementDescriptors;
  +        this.elementList = null;
       }
       
       /** Returns the expression used to evaluate the new context of this element */
  @@ -172,4 +221,50 @@
       public void setPrimitiveType(boolean primitiveType) {
           this.primitiveType = primitiveType;
       }
  +    
  +    // Implementation methods
  +    //-------------------------------------------------------------------------    
  +        
  +    /** 
  +     * Lazily creates the mutable List, nullifiying the array so that
  +     * as items are added to the list the Array is ignored until it is
  +     * explicitly asked for
  +     */
  +    protected List getAttributeList() {
  +        if ( attributeList == null ) {
  +            if ( attributeDescriptors != null ) {
  +                int size = attributeDescriptors.length;
  +                attributeList = new ArrayList( size );
  +                for ( int i = 0; i < size; i++ ) {
  +                    attributeList.add( attributeDescriptors[i] );
  +                }
  +                // force lazy recreation later
  +                attributeDescriptors = null;
  +            }
  +            else {
  +                attributeList = new ArrayList();
  +            }            
  +        }
  +        return attributeList;
  +    }
  +    
  +    /** Lazily creates the mutable List */
  +    protected List getElementList() {
  +        if ( elementList == null ) {
  +            if ( elementDescriptors != null ) {
  +                int size = elementDescriptors.length;
  +                elementList = new ArrayList( size );
  +                for ( int i = 0; i < size; i++ ) {
  +                    elementList.add( elementDescriptors[i] );
  +                }
  +                // force lazy recreation later
  +                elementDescriptors = null;
  +            }
  +            else {
  +                elementList = new ArrayList();
  +            }            
  +        }
  +        return elementList;
  +    }
  +    
   }
  
  
  
  1.4       +20 -6     jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java
  
  Index: XMLBeanInfo.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLBeanInfo.java	30 Jan 2002 19:35:36 -0000	1.3
  +++ XMLBeanInfo.java	19 Feb 2002 06:10:26 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java,v 1.3 2002/01/30 19:35:36 rdonkin Exp $
  - * $Revision: 1.3 $
  - * $Date: 2002/01/30 19:35:36 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.java,v 1.4 2002/02/19 06:10:26 jstrachan Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/02/19 06:10:26 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: XMLBeanInfo.java,v 1.3 2002/01/30 19:35:36 rdonkin Exp $
  + * $Id: XMLBeanInfo.java,v 1.4 2002/02/19 06:10:26 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -68,14 +68,18 @@
     * or XSLT for example.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.3 $
  +  * @version $Revision: 1.4 $
     */
   public class XMLBeanInfo {
   
       private ElementDescriptor elementDescriptor;
       
  +    /** the beans class that this XML info refers to */
  +    private Class beanClass;
  +    
       /** Base constructor */
  -    public XMLBeanInfo() {
  +    public XMLBeanInfo( Class beanClass ) {
  +        this.beanClass = beanClass;        
       }
   
       /** Get descriptor for bean represention */
  @@ -87,4 +91,14 @@
       public void setElementDescriptor(ElementDescriptor elementDescriptor) {
           this.elementDescriptor = elementDescriptor;
       }    
  +    
  +    /** @return the beans class that this XML info refers to */
  +    public Class getBeanClass() {
  +        return beanClass;
  +    }
  +    
  +    /** Sets the beans class that this XML info refers to */
  +    public void setBeanClass(Class beanClass) {
  +        this.beanClass = beanClass;
  +    }
   }
  
  
  
  1.16      +61 -21    jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java
  
  Index: XMLIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- XMLIntrospector.java	9 Feb 2002 12:04:37 -0000	1.15
  +++ XMLIntrospector.java	19 Feb 2002 06:10:26 -0000	1.16
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java,v 1.15 2002/02/09 12:04:37 rdonkin Exp $
  - * $Revision: 1.15 $
  - * $Date: 2002/02/09 12:04:37 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLIntrospector.java,v 1.16 2002/02/19 06:10:26 jstrachan Exp $
  + * $Revision: 1.16 $
  + * $Date: 2002/02/19 06:10:26 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: XMLIntrospector.java,v 1.15 2002/02/09 12:04:37 rdonkin Exp $
  + * $Id: XMLIntrospector.java,v 1.16 2002/02/19 06:10:26 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -70,6 +70,7 @@
   import java.beans.ParameterDescriptor;
   import java.beans.PropertyDescriptor;
   import java.lang.reflect.Method;
  +import java.net.URL;
   import java.util.ArrayList;
   import java.util.Collection;
   import java.util.Date;
  @@ -79,7 +80,7 @@
   import java.util.Map;
   import java.util.HashMap;
   
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.commons.logging.Log;
   
   import org.apache.commons.betwixt.expression.EmptyExpression;
  @@ -88,6 +89,7 @@
   import org.apache.commons.betwixt.expression.MethodExpression;
   import org.apache.commons.betwixt.expression.MethodUpdater;
   import org.apache.commons.betwixt.expression.StringExpression;
  +import org.apache.commons.betwixt.digester.XMLBeanInfoDigester;
   
   /** <p><code>XMLIntrospector</code> an introspector of beans to create a XMLBeanInfo instance.</p>
     *
  @@ -97,19 +99,20 @@
     * Later requests for the same class will return the cached value.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.15 $
  +  * @version $Revision: 1.16 $
     */
   public class XMLIntrospector {
   
       /** should attributes or elements be used for primitive types */
       private boolean attributesForPrimitives = true;
       /** Log used for logging (Doh!) */
  -    protected Log log = LogSource.makeNewLogInstance("org.apache.commons.betwixt.XMLIntrospector");
  +    protected Log log = LogFactory.getLog( XMLIntrospector.class );
       /** Maps classes to <code>XMLBeanInfo</code>'s */
       protected HashMap cacheXMLBeanInfos = new HashMap();
       /** Is <code>XMLBeanInfo</code> caching enabled? */
       boolean cachingEnabled = true;
  -    
  +    /** Digester used to parse the XML descriptor files */
  +    private XMLBeanInfoDigester digester = new XMLBeanInfoDigester();
       /** Base constructor */
       public XMLIntrospector() {
       }
  @@ -165,22 +168,25 @@
           associated with the bean.        
         */
       public XMLBeanInfo introspect(Class aClass) throws IntrospectionException {
  -        // if caching is disabled, then create fresh each time
  -        if (!cachingEnabled) {
  -            BeanInfo info = Introspector.getBeanInfo( aClass );
  -            return introspect( info );
  +        XMLBeanInfo xmlInfo = null;
  +        if ( cachingEnabled ) {
  +            // if caching is enabled, try in caching first
  +            xmlInfo = (XMLBeanInfo) cacheXMLBeanInfos.get( aClass );
           }
  -    
  -        // if caching is enabled, try in caching first
  -        XMLBeanInfo xmlInfo = (XMLBeanInfo) cacheXMLBeanInfos.get( aClass );
           if (xmlInfo == null) {
  -            BeanInfo info = Introspector.getBeanInfo( aClass );
  -            xmlInfo =  introspect( info );
  +            // lets see if we can find an XML descriptor first
  +            log.info( "Attempting to lookup an XML descriptor for class: " + aClass );
  +            
  +            xmlInfo = findByXMLDescriptor( aClass );
  +            if ( xmlInfo == null ) {
  +                BeanInfo info = Introspector.getBeanInfo( aClass );
  +                xmlInfo = introspect( info );
  +            }
  +            
               if (xmlInfo != null) {
  -                cacheXMLBeanInfos.put( aClass, xmlInfo);
  +                cacheXMLBeanInfos.put( aClass, xmlInfo );
               }
  -        }
  -        
  +        }        
           return xmlInfo;
       }
       
  @@ -267,6 +273,40 @@
       
       // Implementation methods
       //-------------------------------------------------------------------------    
  +    
  +    /** 
  +     * Attempt to lookup the XML descriptor for the given class using the
  +     * classname + ".betwixt" using the same ClassLoader used to load the class
  +     * or return null if it could not be loaded
  +     */
  +    protected synchronized XMLBeanInfo findByXMLDescriptor( Class aClass ) {
  +        // trim the package name
  +        String name = aClass.getName();
  +        int idx = name.lastIndexOf( '.' );
  +        if ( idx >= 0 ) {
  +            name = name.substring( idx + 1 );
  +        }
  +        name += ".betwixt";
  +        
  +        URL url = aClass.getResource( name );
  +        if ( url != null ) {
  +            try {
  +                String urlText = url.toString();
  +                if ( log.isDebugEnabled( )) {
  +                    log.debug( "Parsing Betwixt XML descriptor: " + urlText );
  +                }
  +                // synchronized method so this digester is only used by
  +                // one thread at once
  +                digester.setBeanClass( aClass );
  +                return (XMLBeanInfo) digester.parse( urlText );
  +            }
  +            catch (Exception e) {
  +                log.warn( "Caught exception trying to parse: " + name, e );
  +            }
  +        }
  +        return null;
  +    }
  +            
       /** Loop through properties and process each one */
       protected void addProperties(
                                       BeanInfo beanInfo, 
  @@ -369,7 +409,7 @@
       
       /** Factory method to create XMLBeanInfo instances */
       protected XMLBeanInfo createXMLBeanInfo( BeanInfo beanInfo ) {
  -        XMLBeanInfo answer = new XMLBeanInfo();
  +        XMLBeanInfo answer = new XMLBeanInfo( beanInfo.getBeanDescriptor().getBeanClass() );
           return answer;
       }
   
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.betwixt
  
  Index: ElementDescriptor.betwixt
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <info primitiveTypes="attribute">
    <element name="element">
      <element name="attribute" property="attributeDescriptors"/>
      <element name="element" property="elementDescriptors"/>
      <addDefaults/>
    </element>
  </info>
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/XMLBeanInfo.betwixt
  
  Index: XMLBeanInfo.betwixt
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <info primitiveTypes="attribute">
    <element name="info">
      <element name="element" property="elementDescriptor"/>
      <addDefaults/>
    </element>
  </info>
  
  
  1.2       +44 -38    jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/ElementRule.java
  
  Index: ElementRule.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/ElementRule.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ElementRule.java	7 Feb 2002 19:17:27 -0000	1.1
  +++ ElementRule.java	19 Feb 2002 06:10:26 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/ElementRule.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/02/07 19:17:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/ElementRule.java,v 1.2 2002/02/19 06:10:26 jstrachan Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/19 06:10:26 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: ElementRule.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  + * $Id: ElementRule.java,v 1.2 2002/02/19 06:10:26 jstrachan Exp $
    */
   package org.apache.commons.betwixt.digester;
   
  @@ -70,6 +70,7 @@
   import org.apache.commons.betwixt.ElementDescriptor;
   import org.apache.commons.betwixt.XMLBeanInfo;
   import org.apache.commons.betwixt.XMLIntrospector;
  +import org.apache.commons.betwixt.expression.ConstantExpression;
   import org.apache.commons.betwixt.expression.Context;
   import org.apache.commons.betwixt.expression.Updater;
   import org.apache.commons.betwixt.expression.MethodExpression;
  @@ -79,7 +80,7 @@
   import org.apache.commons.digester.Digester;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   import org.xml.sax.Attributes;
   import org.xml.sax.SAXException;
  @@ -87,15 +88,17 @@
   /** <p><code>ElementRule</code> the digester Rule for parsing the &lt;element&gt; elements.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.1 $
  +  * @version $Revision: 1.2 $
     */
  -public class ElementRule extends Rule {
  +public class ElementRule extends RuleSupport {
   
       /** Logger */
  -    private static final Log log = LogSource.getInstance( ElementRule.class );
  +    private static final Log log = LogFactory.getLog( ElementRule.class );
       
       private ClassLoader classLoader;
       
  +    private Class beanClass;
  +    
       public ElementRule(Digester digester) {
           super(digester);
           this.classLoader = getClass().getClassLoader();
  @@ -110,25 +113,35 @@
        * @param attributes The attribute list of this element
        */
       public void begin(Attributes attributes) throws Exception {
  -        //log.debug( "Called with descriptor: " + descriptor + " propertyType: " + descriptor.getPropertyType() );
  +        String name = attributes.getValue( "name" );
           
           ElementDescriptor descriptor = new ElementDescriptor();
  -        
  -        descriptor.setQualifiedName( attributes.getValue( "name" ) );
  -        descriptor.setLocalName( attributes.getValue( "name" ) );
  +        descriptor.setQualifiedName( name );
  +        descriptor.setLocalName( name );
           String uri = attributes.getValue( "uri" );
           if ( uri != null ) {
               descriptor.setURI( uri );        
           }
  -        descriptor.setPropertyName( attributes.getValue( "property" ) );
  +        
  +        String propertyName = attributes.getValue( "property" );
  +        descriptor.setPropertyName( propertyName );
           descriptor.setPropertyType( loadClass( attributes.getValue( "type" ) ) );
           
  -        configureDescriptor(descriptor);
  +        if ( propertyName != null && propertyName.length() > 0 ) {
  +            configureDescriptor(descriptor);
  +        }
  +        else {
  +            String value = attributes.getValue( "value" );
  +            if ( value != null ) {
  +                descriptor.setTextExpression( new ConstantExpression( value ) );
  +            }
  +        }
           
           Object top = digester.peek();
           if ( top instanceof XMLBeanInfo ) {
               XMLBeanInfo beanInfo = (XMLBeanInfo) top;
               beanInfo.setElementDescriptor( descriptor );
  +            beanClass = beanInfo.getBeanClass();
           }
           else if ( top instanceof ElementDescriptor ) {
               ElementDescriptor parent = (ElementDescriptor) top;
  @@ -137,6 +150,7 @@
           else {
               throw new SAXException( "Invalid use of <element>. It should be nested inside <info> or other <element> nodes" );
           }            
  +
           digester.push(descriptor);        
       }
   
  @@ -165,34 +179,26 @@
       
       /** Set the Expression and Updater from a bean property name */
       protected void configureDescriptor(ElementDescriptor elementDescriptor) {
  -        Class beanClass = elementDescriptor.getPropertyType();
  +        Class beanClass = getBeanClass();
           if ( beanClass != null ) {
               String name = elementDescriptor.getPropertyName();
  -            if ( name != null ) {
  -                try {
  -                    BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
  -                    PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
  -                    if ( descriptors != null ) {
  -                        for ( int i = 0, size = descriptors.length; i < size; i++ ) {
  -                            PropertyDescriptor descriptor = descriptors[i];
  -                            if ( name.equals( descriptor.getName() ) ) {
  -                                Method readMethod = descriptor.getReadMethod();
  -                                Method writeMethod = descriptor.getWriteMethod();
  -                                if ( readMethod != null ) {
  -                                    elementDescriptor.setTextExpression( new MethodExpression( readMethod ) );
  -                                }
  -                                if ( writeMethod != null ) {
  -                                    elementDescriptor.setTextExpression( new MethodExpression( writeMethod ) );
  -                                }
  -                                break;
  -                            }
  +            try {
  +                BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
  +                PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
  +                if ( descriptors != null ) {
  +                    for ( int i = 0, size = descriptors.length; i < size; i++ ) {
  +                        PropertyDescriptor descriptor = descriptors[i];
  +                        if ( name.equals( descriptor.getName() ) ) {
  +                            XMLIntrospectorHelper.configureProperty( elementDescriptor, descriptor );
  +                            getProcessedPropertyNameSet().add( name );
  +                            break;
                           }
                       }
                   }
  -                catch (Exception e) {
  -                    log.info( "Caught introspection exception", e );
  -                }
  +            }
  +            catch (Exception e) {
  +                log.warn( "Caught introspection exception", e );
               }
           }
  -    }
  -}
  +    }    
  +}
  \ No newline at end of file
  
  
  
  1.2       +25 -15    jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/InfoRule.java
  
  Index: InfoRule.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/InfoRule.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- InfoRule.java	7 Feb 2002 19:17:27 -0000	1.1
  +++ InfoRule.java	19 Feb 2002 06:10:26 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/InfoRule.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/02/07 19:17:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/InfoRule.java,v 1.2 2002/02/19 06:10:26 jstrachan Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/19 06:10:26 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: InfoRule.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  + * $Id: InfoRule.java,v 1.2 2002/02/19 06:10:26 jstrachan Exp $
    */
   package org.apache.commons.betwixt.digester;
   
  @@ -72,19 +72,19 @@
   import org.apache.commons.digester.Digester;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   import org.xml.sax.Attributes;
   
   /** <p><code>InfoRule</code> the digester Rule for parsing the info element.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.1 $
  +  * @version $Revision: 1.2 $
     */
  -public class InfoRule extends Rule {
  +public class InfoRule extends RuleSupport {
   
       /** Logger */
  -    private static final Log log = LogSource.getInstance( InfoRule.class );
  +    private static final Log log = LogFactory.getLog( InfoRule.class );
       
       private XMLBeanInfo xmlBeanInfo;
       
  @@ -102,10 +102,25 @@
        * @param attributes The attribute list of this element
        */
       public void begin(Attributes attributes) throws Exception {
  -        xmlBeanInfo = new XMLBeanInfo();
  +        Class beanClass = getBeanClass();
           
  -        getDigester().push(xmlBeanInfo);
  +        xmlBeanInfo = new XMLBeanInfo( beanClass );
           
  +        String value = attributes.getValue( "primitiveTypes" );
  +        if ( value != null ) {
  +            if ( value.equalsIgnoreCase( "element" ) ) {
  +                getXMLInfoDigester().setAttributesForPrimitives( false );
  +            }
  +            else 
  +            if ( value.equalsIgnoreCase( "attribute" ) ) {
  +                getXMLInfoDigester().setAttributesForPrimitives( true );
  +            }
  +            else {
  +                throw new Exception( "Invalid value inside element <info> for attribute 'primitiveTypes'. Value should be 'element' or 'attribute'" );
  +            }
  +        }
  +        
  +        getDigester().push(xmlBeanInfo);       
       }
   
   
  @@ -115,9 +130,4 @@
       public void end() throws Exception {
           Object top = getDigester().pop();
       }
  -
  -    // Implementation methods
  -    //-------------------------------------------------------------------------    
  -    
  -    
   }
  
  
  
  1.2       +53 -7     jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/XMLBeanInfoDigester.java
  
  Index: XMLBeanInfoDigester.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/XMLBeanInfoDigester.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLBeanInfoDigester.java	7 Feb 2002 19:17:27 -0000	1.1
  +++ XMLBeanInfoDigester.java	19 Feb 2002 06:10:26 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/XMLBeanInfoDigester.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/02/07 19:17:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/XMLBeanInfoDigester.java,v 1.2 2002/02/19 06:10:26 jstrachan Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/19 06:10:26 $
    *
    * ====================================================================
    *
  @@ -57,17 +57,20 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: XMLBeanInfoDigester.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  + * $Id: XMLBeanInfoDigester.java,v 1.2 2002/02/19 06:10:26 jstrachan Exp $
    */
   package org.apache.commons.betwixt.digester;
   
  +import java.util.HashSet;
  +import java.util.Set;
  +
   import javax.xml.parsers.SAXParser;
   
   import org.apache.commons.digester.Rule;
   import org.apache.commons.digester.Digester;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   import org.xml.sax.XMLReader;
   
  @@ -75,12 +78,21 @@
     * containing XMLBeanInfo definitions for a JavaBean.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.1 $
  +  * @version $Revision: 1.2 $
     */
   public class XMLBeanInfoDigester extends Digester {
   
       /** Logger */
  -    private static final Log log = LogSource.getInstance( XMLBeanInfoDigester.class );
  +    private static final Log log = LogFactory.getLog( XMLBeanInfoDigester.class );
  +    
  +    /** the beans class for this XML descriptor */
  +    private Class beanClass;
  +    
  +    /** should attributes or elements be used for primitive types */
  +    private boolean attributesForPrimitives;
  +    
  +    /** the set of property names processed so far */
  +    private Set processedPropertyNameSet = new HashSet();
       
       /**
        * Construct a new XMLBeanInfoDigester with default properties.
  @@ -110,6 +122,33 @@
           super(reader);
       }
       
  +    /** @return the beans class for this XML descriptor */
  +    public Class getBeanClass() {
  +        return beanClass;
  +    }
  +    
  +    /** Sets the beans class for this XML descriptor */
  +    public void setBeanClass(Class beanClass) {
  +        this.beanClass = beanClass;
  +    }
  +    
  +    
  +    /** @return the set of property names that have been processed so far */
  +    public Set getProcessedPropertyNameSet() {
  +        return processedPropertyNameSet;
  +    }
  +    
  +    /** Should attributes (or elements) be used for primitive types.
  +     */
  +    public boolean isAttributesForPrimitives() {
  +        return attributesForPrimitives;
  +    }
  +
  +    /** Set whether attributes (or elements) should be used for primitive types. */
  +    public void setAttributesForPrimitives(boolean attributesForPrimitives) {
  +        this.attributesForPrimitives = attributesForPrimitives;
  +    }
  +
       // Implementation methods
       //-------------------------------------------------------------------------        
       protected void configure() {
  @@ -120,7 +159,14 @@
               
               addRule( "info", new InfoRule( this ) );
               addRule( "*/element", new ElementRule( this ) );
  +            addRule( "*/attribute", new AttributeRule( this ) );
  +            addRule( "*/hide", new HideRule( this ) );
  +            addRule( "*/addDefaults", new AddDefaultsRule( this ) );
           }
  +        
  +        // now initialize
  +        attributesForPrimitives = true;
  +        processedPropertyNameSet.clear();
       }
       
   }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/AddDefaultsRule.java
  
  Index: AddDefaultsRule.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/AddDefaultsRule.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/19 06:10:26 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: AddDefaultsRule.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   */
  package org.apache.commons.betwixt.digester;
  
  import java.beans.BeanInfo;
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  import java.util.Set;
  
  import org.apache.commons.betwixt.AttributeDescriptor;
  import org.apache.commons.betwixt.ElementDescriptor;
  import org.apache.commons.betwixt.NodeDescriptor;
  import org.apache.commons.betwixt.XMLBeanInfo;
  import org.apache.commons.betwixt.XMLIntrospector;
  import org.apache.commons.betwixt.expression.Context;
  import org.apache.commons.betwixt.expression.Updater;
  
  import org.apache.commons.digester.Rule;
  import org.apache.commons.digester.Digester;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  /** <p><code>AddDefaultsRule</code> appends all the default properties
    * to the current element.</p>
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision: 1.1 $
    */
  public class AddDefaultsRule extends RuleSupport {
  
      /** Logger */
      private static final Log log = LogFactory.getLog( AddDefaultsRule.class );
      
      
      public AddDefaultsRule(Digester digester) {
          super(digester);
      }
      
      // Rule interface
      //-------------------------------------------------------------------------    
      
      /**
       * Process the beginning of this element.
       *
       * @param attributes The attribute list of this element
       */
      public void begin(Attributes attributes) throws Exception {
          Class beanClass = getBeanClass();
          Set procesedProperties = getProcessedPropertyNameSet();
          if ( beanClass != null ) {
              try {
                  boolean attributesForPrimitives = getXMLInfoDigester().isAttributesForPrimitives();
                  BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
                  PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
                  if ( descriptors != null ) {
                      for ( int i = 0, size = descriptors.length; i < size; i++ ) {
                          PropertyDescriptor descriptor = descriptors[i];
                          // have we already created a property for this
                          String name = descriptor.getName();
                          if ( procesedProperties.contains( name ) ) {
                              continue;
                          }
                          NodeDescriptor nodeDescriptor = XMLIntrospectorHelper.createDescriptor( 
                              descriptor, attributesForPrimitives 
                          );
                          if ( nodeDescriptor != null ) {
                              addDescriptor( nodeDescriptor );
                          }
                      }
                  }
              }
              catch (Exception e) {
                  log.info( "Caught introspection exception", e );
              }
          }
      }
  
  
      // Implementation methods
      //-------------------------------------------------------------------------    
      protected void addDescriptor( NodeDescriptor nodeDescriptor ) throws SAXException {
          Object top = digester.peek();
          if ( top instanceof XMLBeanInfo ) {
              XMLBeanInfo beanInfo = (XMLBeanInfo) top;
              // if there is already a root element descriptor then use it
              // otherwise use this descriptor
              if ( nodeDescriptor instanceof ElementDescriptor ) {
                  ElementDescriptor elementDescriptor = (ElementDescriptor) nodeDescriptor;
                  ElementDescriptor root = beanInfo.getElementDescriptor() ;
                  if ( root == null ) {
                      beanInfo.setElementDescriptor( elementDescriptor );
                  }
                  else {
                      root.addElementDescriptor( elementDescriptor );
                  }
              }
              else { 
                  throw new SAXException( "the <addDefaults> element should be within an <element> tag" );
              }
          }
          else if ( top instanceof ElementDescriptor ) {
              ElementDescriptor parent = (ElementDescriptor) top;
              if ( nodeDescriptor instanceof ElementDescriptor ) {
                  parent.addElementDescriptor( (ElementDescriptor) nodeDescriptor );
              }
              else {
                  parent.addAttributeDescriptor( (AttributeDescriptor) nodeDescriptor );
              }
          }
          else {
              throw new SAXException( "Invalid use of <addDefaults>. It should be nested inside <element> element" );
          }            
      }     
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/AttributeRule.java
  
  Index: AttributeRule.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/AttributeRule.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/19 06:10:26 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: AttributeRule.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   */
  package org.apache.commons.betwixt.digester;
  
  import java.beans.BeanInfo;
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.Method;
  
  import org.apache.commons.betwixt.AttributeDescriptor;
  import org.apache.commons.betwixt.ElementDescriptor;
  import org.apache.commons.betwixt.XMLBeanInfo;
  import org.apache.commons.betwixt.XMLIntrospector;
  import org.apache.commons.betwixt.expression.ConstantExpression;
  import org.apache.commons.betwixt.expression.Context;
  import org.apache.commons.betwixt.expression.Updater;
  import org.apache.commons.betwixt.expression.MethodExpression;
  import org.apache.commons.betwixt.expression.MethodUpdater;
  
  import org.apache.commons.digester.Rule;
  import org.apache.commons.digester.Digester;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  /** <p><code>AttributeRule</code> the digester Rule for parsing the &lt;attribute&gt; elements.</p>
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision: 1.1 $
    */
  public class AttributeRule extends RuleSupport {
  
      /** Logger */
      private static final Log log = LogFactory.getLog( AttributeRule.class );
      
      private ClassLoader classLoader;
      
      private Class beanClass;
      
      public AttributeRule(Digester digester) {
          super(digester);
          this.classLoader = getClass().getClassLoader();
      }
      
      // Rule interface
      //-------------------------------------------------------------------------    
      
      /**
       * Process the beginning of this element.
       *
       * @param attributes The attribute list of this element
       */
      public void begin(Attributes attributes) throws Exception {
          
          AttributeDescriptor descriptor = new AttributeDescriptor();
          String name = attributes.getValue( "name" );
          descriptor.setQualifiedName( name );
          descriptor.setLocalName( name );
          String uri = attributes.getValue( "uri" );
          if ( uri != null ) {
              descriptor.setURI( uri );        
          }
          String propertyName = attributes.getValue( "property" );
          descriptor.setPropertyName( propertyName );
          descriptor.setPropertyType( loadClass( attributes.getValue( "type" ) ) );
          
          if ( propertyName != null && propertyName.length() > 0 ) {
              configureDescriptor(descriptor);
          }
          else {
              String value = attributes.getValue( "value" );
              if ( value != null ) {
                  descriptor.setTextExpression( new ConstantExpression( value ) );
              }
          }
  
          Object top = digester.peek();
          if ( top instanceof ElementDescriptor ) {
              ElementDescriptor parent = (ElementDescriptor) top;
              parent.addAttributeDescriptor( descriptor );
          }
          else {
              throw new SAXException( "Invalid use of <attribute>. It should be nested inside an <element> element" );
          }            
  
          digester.push(descriptor);        
      }
  
  
      /**
       * Process the end of this element.
       */
      public void end() throws Exception {
          Object top = digester.pop();
      }
  
      
      // Implementation methods
      //-------------------------------------------------------------------------    
      protected Class loadClass( String name ) {
          // XXX: should use a ClassLoader to handle complex class loading situations
          if ( name != null ) {
              try {
                  return classLoader.loadClass(name);
              }
              catch (Exception e) {
              }
          }
          return null;            
      }
      
      /** Set the Expression and Updater from a bean property name */
      protected void configureDescriptor(AttributeDescriptor attributeDescriptor) {
          String name = attributeDescriptor.getPropertyName();
          try {
              BeanInfo beanInfo = Introspector.getBeanInfo( getBeanClass());
              PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
              if ( descriptors != null ) {
                  for ( int i = 0, size = descriptors.length; i < size; i++ ) {
                      PropertyDescriptor descriptor = descriptors[i];
                      if ( name.equals( descriptor.getName() ) ) {
                          XMLIntrospectorHelper.configureProperty( attributeDescriptor, descriptor );
                          getProcessedPropertyNameSet().add( name );
                          break;
                      }
                  }
              }
          }
          catch (Exception e) {
              log.warn( "Caught introspection exception", e );
          }
      }    
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/HideRule.java
  
  Index: HideRule.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/HideRule.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/19 06:10:26 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: HideRule.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   */
  package org.apache.commons.betwixt.digester;
  
  import java.util.Set;
  
  import org.apache.commons.digester.Digester;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  /** <p><code>HideRule</code> hides the property of the given name.</p>
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision: 1.1 $
    */
  public class HideRule extends RuleSupport {
  
      /** Logger */
      private static final Log log = LogFactory.getLog( HideRule.class );
      
      
      public HideRule(Digester digester) {
          super(digester);
      }
      
      // Rule interface
      //-------------------------------------------------------------------------    
      
      /**
       * Process the beginning of this element.
       *
       * @param attributes The attribute list of this element
       */
      public void begin(Attributes attributes) throws Exception {
          String name = attributes.getValue( "property" );
          if ( name == null || name.length() == 0 ) {
              throw new SAXException( "<ignore> element is missing the mandatory attribute 'name'" );
          }
          Set propertySet = getProcessedPropertyNameSet();
          propertySet.add( name );
      }
  
  
      /**
       * Process the end of this element.
       */
      public void end() throws Exception {
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/RuleSupport.java
  
  Index: RuleSupport.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/RuleSupport.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/19 06:10:26 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: RuleSupport.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   */
  package org.apache.commons.betwixt.digester;
  
  import java.beans.BeanInfo;
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.Method;
  import java.util.Set;
  
  import org.apache.commons.betwixt.AttributeDescriptor;
  import org.apache.commons.betwixt.ElementDescriptor;
  import org.apache.commons.betwixt.XMLBeanInfo;
  import org.apache.commons.betwixt.XMLIntrospector;
  import org.apache.commons.betwixt.expression.Context;
  import org.apache.commons.betwixt.expression.Updater;
  import org.apache.commons.betwixt.expression.MethodExpression;
  import org.apache.commons.betwixt.expression.MethodUpdater;
  
  import org.apache.commons.digester.Rule;
  import org.apache.commons.digester.Digester;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  /** <p><code>RuleSupport</code> is an abstract base class containing useful
    * helper methods.</p>
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision: 1.1 $
    */
  public class RuleSupport extends Rule {
  
      /** Logger */
      private static final Log log = LogFactory.getLog( RuleSupport.class );
      
      public RuleSupport(Digester digester) {
          super(digester);
      }
      
      
  
      // Implementation methods
      //-------------------------------------------------------------------------    
      protected XMLBeanInfoDigester getXMLInfoDigester() {
          return (XMLBeanInfoDigester) getDigester();
      }
      
      protected Class getBeanClass() {
          return getXMLInfoDigester().getBeanClass();
      }
      
      protected Set getProcessedPropertyNameSet() {
          return getXMLInfoDigester().getProcessedPropertyNameSet();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/XMLIntrospectorHelper.java
  
  Index: XMLIntrospectorHelper.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/digester/XMLIntrospectorHelper.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/19 06:10:26 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: XMLIntrospectorHelper.java,v 1.1 2002/02/19 06:10:26 jstrachan Exp $
   */
  package org.apache.commons.betwixt.digester;
  
  import java.beans.BeanDescriptor;
  import java.beans.BeanInfo;
  import java.beans.FeatureDescriptor;
  import java.beans.Introspector;
  import java.beans.IntrospectionException;
  import java.beans.MethodDescriptor;
  import java.beans.ParameterDescriptor;
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Date;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.commons.logging.LogFactory;
  import org.apache.commons.logging.Log;
  
  import org.apache.commons.betwixt.AttributeDescriptor;
  import org.apache.commons.betwixt.ElementDescriptor;
  import org.apache.commons.betwixt.NodeDescriptor;
  import org.apache.commons.betwixt.XMLBeanInfo;
  import org.apache.commons.betwixt.expression.EmptyExpression;
  import org.apache.commons.betwixt.expression.Expression;
  import org.apache.commons.betwixt.expression.IteratorExpression;
  import org.apache.commons.betwixt.expression.MethodExpression;
  import org.apache.commons.betwixt.expression.MethodUpdater;
  import org.apache.commons.betwixt.expression.StringExpression;
  
  /** <p><code>XMLIntrospectorHelper</code> a helper class for 
    * common code shared between the digestor and introspector.</p>
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision: 1.1 $
    */
  public class XMLIntrospectorHelper {
  
      /** Log used for logging (Doh!) */
      protected static Log log = LogFactory.getLog( XMLIntrospectorHelper.class );
      
      /** Base constructor */
      public XMLIntrospectorHelper() {
      }
      
      /**
       * <p> Get the current logging implementation. </p>
       */ 
      public static Log getLog() {
          return log;
      }
  
      /**
       * <p> Set the current logging implementation. </p>
       */ 
      public static void setLog(Log aLog) {
          log = aLog;
      }
      
  
      /** 
       * Process a property. 
       * Go through and work out whether it's a loop property, a primitive or a standard.
       * The class property is ignored.
       */
      public static NodeDescriptor createDescriptor( 
          PropertyDescriptor propertyDescriptor,
          boolean useAttributesForPrimitives
      ) throws IntrospectionException {
          Class type = propertyDescriptor.getPropertyType();
          NodeDescriptor nodeDescriptor = null;
          Method readMethod = propertyDescriptor.getReadMethod();
          Method writeMethod = propertyDescriptor.getWriteMethod();
          
          if ( readMethod == null ) {
              log.trace( "No read method" );
              return null;
          }
          
          if ( log.isTraceEnabled() ) {
              log.trace( "Read method=" + readMethod.getName() );
          }
          
          // choose response from property type
          
          // XXX: ignore class property ??
          if ( Class.class.equals( type ) && "class".equals( propertyDescriptor.getName() ) ) {
              log.trace( "Ignoring class property" );
              return null;
          }
          if ( isPrimitiveType( type ) ) {
              log.trace( "Primative type" );
              if ( useAttributesForPrimitives ) {
                  log.trace( "Added attribute" );
                  nodeDescriptor = new AttributeDescriptor();
              }
              else {
                  log.trace( "Added element" );
                  nodeDescriptor = new ElementDescriptor(true);
              }
              nodeDescriptor.setTextExpression( new MethodExpression( readMethod ) );
              nodeDescriptor.setUpdater( new MethodUpdater( writeMethod ) );
          }
          else if ( isLoopType( type ) ) {
              log.trace("Loop type");
              ElementDescriptor loopDescriptor = new ElementDescriptor();
              loopDescriptor.setContextExpression(
                  new IteratorExpression( new MethodExpression( readMethod ) )
              );
              // XXX: need to support some kind of 'add' or handle arrays, Lists or indexed properties
              //loopDescriptor.setUpdater( new MethodUpdater( writeMethod ) );
              if ( Map.class.isAssignableFrom( type ) ) {
                  loopDescriptor.setQualifiedName( "entry" );
              }
              
              ElementDescriptor elementDescriptor = new ElementDescriptor();
              elementDescriptor.setElementDescriptors( new ElementDescriptor[] { loopDescriptor } );
              
              nodeDescriptor = elementDescriptor;            
          }
          else {
              log.trace( "Standard property" );
              ElementDescriptor elementDescriptor = new ElementDescriptor();
              elementDescriptor.setContextExpression( new MethodExpression( readMethod ) );
              elementDescriptor.setUpdater( new MethodUpdater( writeMethod ) );
              
              nodeDescriptor = elementDescriptor;            
          }
          nodeDescriptor.setLocalName( propertyDescriptor.getName() );
          nodeDescriptor.setPropertyType( type );        
          
          // XXX: associate more bean information with the descriptor?
          //nodeDescriptor.setDisplayName( propertyDescriptor.getDisplayName() );
          //nodeDescriptor.setShortDescription( propertyDescriptor.getShortDescription() );
          return nodeDescriptor;
      }
      
      
      public static void configureProperty( ElementDescriptor elementDescriptor, PropertyDescriptor propertyDescriptor ) {
          Class type = propertyDescriptor.getPropertyType();
          Method readMethod = propertyDescriptor.getReadMethod();
          Method writeMethod = propertyDescriptor.getWriteMethod();
          
          if ( readMethod == null ) {
              log.trace( "No read method" );
              return;
          }
          
          if ( log.isTraceEnabled() ) {
              log.trace( "Read method=" + readMethod.getName() );
          }
          
          // choose response from property type
          
          // XXX: ignore class property ??
          if ( Class.class.equals( type ) && "class".equals( propertyDescriptor.getName() ) ) {
              log.trace( "Ignoring class property" );
              return;
          }
          if ( isPrimitiveType( type ) ) {
              elementDescriptor.setTextExpression( new MethodExpression( readMethod ) );
              elementDescriptor.setUpdater( new MethodUpdater( writeMethod ) );
          }
          else if ( isLoopType( type ) ) {
              log.trace("Loop type");
              
              // don't wrap this in an extra element as its specified in the 
              // XML descriptor so no need.            
              elementDescriptor.setContextExpression(
                  new IteratorExpression( new MethodExpression( readMethod ) )
              );
          }
          else {
              log.trace( "Standard property" );
              elementDescriptor.setContextExpression( new MethodExpression( readMethod ) );
              elementDescriptor.setUpdater( new MethodUpdater( writeMethod ) );            
          }
          elementDescriptor.setLocalName( propertyDescriptor.getName() );
          elementDescriptor.setPropertyType( type );        
          
          // XXX: associate more bean information with the descriptor?
          //nodeDescriptor.setDisplayName( propertyDescriptor.getDisplayName() );
          //nodeDescriptor.setShortDescription( propertyDescriptor.getShortDescription() );
      }
      
      
      public static void configureProperty( AttributeDescriptor attributeDescriptor, PropertyDescriptor propertyDescriptor ) {
          Class type = propertyDescriptor.getPropertyType();
          Method readMethod = propertyDescriptor.getReadMethod();
          Method writeMethod = propertyDescriptor.getWriteMethod();
          
          if ( readMethod == null ) {
              log.trace( "No read method" );
              return;
          }
          
          if ( log.isTraceEnabled() ) {
              log.trace( "Read method=" + readMethod );
          }
          
          // choose response from property type
          
          // XXX: ignore class property ??
          if ( Class.class.equals( type ) && "class".equals( propertyDescriptor.getName() ) ) {
              log.trace( "Ignoring class property" );
              return;
          }
          if ( isLoopType( type ) ) {
              log.warn( "Using loop type for an attribute. Type = " + type.getName() + " attribute: " + attributeDescriptor.getQualifiedName() );
          }
  
          log.trace( "Standard property" );
          attributeDescriptor.setTextExpression( new MethodExpression( readMethod ) );
          attributeDescriptor.setUpdater( new MethodUpdater( writeMethod ) );
          
          attributeDescriptor.setLocalName( propertyDescriptor.getName() );
          attributeDescriptor.setPropertyType( type );        
          
          // XXX: associate more bean information with the descriptor?
          //nodeDescriptor.setDisplayName( propertyDescriptor.getDisplayName() );
          //nodeDescriptor.setShortDescription( propertyDescriptor.getShortDescription() );
      }
      
      
      /** Returns true if the type is a loop type */
      public static boolean isLoopType(Class type) {
          return type.isArray() 
              || Map.class.isAssignableFrom( type ) 
              || Collection.class.isAssignableFrom( type ) 
              || Enumeration.class.isAssignableFrom( type ) 
              || Iterator.class.isAssignableFrom( type );
      }
      
      
      /** Returns true for primitive types */
      public static boolean isPrimitiveType(Class type) {
          if ( type.equals( Object.class ) ) {
              return false;
          }
          return type.getName().startsWith( "java.lang." )
              || type.isAssignableFrom( Number.class ) 
              || type.isAssignableFrom( String.class ) 
              || type.isAssignableFrom( Date.class );
      }
  }
  
  
  
  1.7       +7 -7      jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/Context.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Context.java	31 Jan 2002 19:56:02 -0000	1.6
  +++ Context.java	19 Feb 2002 06:10:27 -0000	1.7
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/Context.java,v 1.6 2002/01/31 19:56:02 jstrachan Exp $
  - * $Revision: 1.6 $
  - * $Date: 2002/01/31 19:56:02 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/Context.java,v 1.7 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.7 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -56,7 +56,7 @@
    * individuals on behalf of the Apache Software Foundation.  For more
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
  - * $Id: Context.java,v 1.6 2002/01/31 19:56:02 jstrachan Exp $
  + * $Id: Context.java,v 1.7 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt.expression;
   
  @@ -64,7 +64,7 @@
   import java.util.Map;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   /** <p><code>Context</code> describes the context used to evaluate
     * bean expressions.
  @@ -86,7 +86,7 @@
     * If the child is a parent then that operation fails. </p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.6 $
  +  * @version $Revision: 1.7 $
     */
   public class Context {
   
  @@ -100,7 +100,7 @@
       private Context parent;
       
       public Context() {
  -        this.log = LogSource.getInstance( getClass() );
  +        this.log = LogFactory.getLog( getClass() );
       }
       
       /** Convenience constructor sets evaluted bean and log.
  
  
  
  1.3       +4 -4      jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/MethodUpdater.java
  
  Index: MethodUpdater.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/MethodUpdater.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MethodUpdater.java	31 Jan 2002 21:24:42 -0000	1.2
  +++ MethodUpdater.java	19 Feb 2002 06:10:27 -0000	1.3
  @@ -5,26 +5,26 @@
    * version 1.1, a copy of which has been included with this distribution in
    * the LICENSE file.
    * 
  - * $Id: MethodUpdater.java,v 1.2 2002/01/31 21:24:42 jstrachan Exp $
  + * $Id: MethodUpdater.java,v 1.3 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt.expression;
   
   import java.lang.reflect.Method;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   /** <p><code>MethodUpdater</code> updates the current bean context 
     * by calling a WriteMethod with the String value from the XML attribute 
     * or element.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.2 $
  +  * @version $Revision: 1.3 $
     */
   public class MethodUpdater implements Updater {
   
       /** Logger */
  -    private static final Log log = LogSource.getInstance( MethodUpdater.class );
  +    private static final Log log = LogFactory.getLog( MethodUpdater.class );
       
       /** The method to call on the bean */
       private Method method;
  
  
  
  1.3       +4 -4      jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanCreateRule.java
  
  Index: BeanCreateRule.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanCreateRule.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BeanCreateRule.java	31 Jan 2002 21:24:42 -0000	1.2
  +++ BeanCreateRule.java	19 Feb 2002 06:10:27 -0000	1.3
  @@ -5,7 +5,7 @@
    * version 1.1, a copy of which has been included with this distribution in
    * the LICENSE file.
    * 
  - * $Id: BeanCreateRule.java,v 1.2 2002/01/31 21:24:42 jstrachan Exp $
  + * $Id: BeanCreateRule.java,v 1.3 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt.io;
   
  @@ -24,7 +24,7 @@
   import org.apache.commons.digester.Digester;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   import org.xml.sax.Attributes;
   
  @@ -32,12 +32,12 @@
     * from the betwixt XML metadata.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.2 $
  +  * @version $Revision: 1.3 $
     */
   public class BeanCreateRule extends Rule {
   
       /** Logger */
  -    private static final Log log = LogSource.getInstance( BeanCreateRule.class );
  +    private static final Log log = LogFactory.getLog( BeanCreateRule.class );
       
       /** The descriptor of this element */
       private ElementDescriptor descriptor;
  
  
  
  1.3       +4 -4      jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanReader.java
  
  Index: BeanReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanReader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BeanReader.java	31 Jan 2002 21:24:42 -0000	1.2
  +++ BeanReader.java	19 Feb 2002 06:10:27 -0000	1.3
  @@ -5,7 +5,7 @@
    * version 1.1, a copy of which has been included with this distribution in
    * the LICENSE file.
    * 
  - * $Id: BeanReader.java,v 1.2 2002/01/31 21:24:42 jstrachan Exp $
  + * $Id: BeanReader.java,v 1.3 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt.io;
   
  @@ -25,21 +25,21 @@
   import org.apache.commons.digester.Rule;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   import org.xml.sax.XMLReader;
   
   /** <p><code>BeanReader</code> reads a tree of beans from an XML document.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.2 $
  +  * @version $Revision: 1.3 $
     */
   public class BeanReader extends Digester {
   
       /** Introspector used */
       private XMLIntrospector introspector = new XMLIntrospector();    
       /** Log used for logging (Doh!) */
  -    private Log log = LogSource.getInstance( BeanReader.class.getName() );
  +    private Log log = LogFactory.getLog( BeanReader.class.getName() );
       
       /**
        * Construct a new BeanReader with default properties.
  
  
  
  1.14      +7 -7      jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java
  
  Index: BeanWriter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- BeanWriter.java	10 Feb 2002 19:18:42 -0000	1.13
  +++ BeanWriter.java	19 Feb 2002 06:10:27 -0000	1.14
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java,v 1.13 2002/02/10 19:18:42 rdonkin Exp $
  - * $Revision: 1.13 $
  - * $Date: 2002/02/10 19:18:42 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/io/BeanWriter.java,v 1.14 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.14 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: BeanWriter.java,v 1.13 2002/02/10 19:18:42 rdonkin Exp $
  + * $Id: BeanWriter.java,v 1.14 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt.io;
   
  @@ -70,7 +70,7 @@
   import java.util.Iterator;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   import org.apache.commons.betwixt.AttributeDescriptor;
   import org.apache.commons.betwixt.ElementDescriptor;
  @@ -98,7 +98,7 @@
     * The indent string used is set by {@link #setIndent}.
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.13 $
  +  * @version $Revision: 1.14 $
     */
   public class BeanWriter {
   
  @@ -126,7 +126,7 @@
       /** should we flush after writing bean */
       private boolean autoFlush;
       /** Log used for logging (Doh!) */
  -    private Log log = LogSource.makeNewLogInstance("org.apache.commons.betwixt.BeanWriter");
  +    private Log log = LogFactory.getLog( BeanWriter.class );
       
       /**
        * <p> Constructor uses <code>System.out</code> for output.</p>
  
  
  
  1.9       +7 -7      jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/CustomerBean.java
  
  Index: CustomerBean.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/CustomerBean.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- CustomerBean.java	31 Jan 2002 21:24:42 -0000	1.8
  +++ CustomerBean.java	19 Feb 2002 06:10:27 -0000	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/CustomerBean.java,v 1.8 2002/01/31 21:24:42 jstrachan Exp $
  - * $Revision: 1.8 $
  - * $Date: 2002/01/31 21:24:42 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/CustomerBean.java,v 1.9 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.9 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: CustomerBean.java,v 1.8 2002/01/31 21:24:42 jstrachan Exp $
  + * $Id: CustomerBean.java,v 1.9 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -71,17 +71,17 @@
   import org.apache.commons.collections.IteratorEnumeration;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   
   /** <p><code>CustomerBean</code> is a sample bean for use by the test cases.</p>
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.8 $
  +  * @version $Revision: 1.9 $
     */
   public class CustomerBean implements Serializable {
   
       /** Logger */
  -    private static final Log log = LogSource.getInstance( CustomerBean.class );
  +    private static final Log log = LogFactory.getLog( CustomerBean.class );
       
       private String id;
       private String name;
  
  
  
  1.6       +6 -5      jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestAll.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestAll.java	7 Feb 2002 19:17:27 -0000	1.5
  +++ TestAll.java	19 Feb 2002 06:10:27 -0000	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestAll.java,v 1.5 2002/02/07 19:17:27 jstrachan Exp $
  - * $Revision: 1.5 $
  - * $Date: 2002/02/07 19:17:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestAll.java,v 1.6 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.6 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: TestAll.java,v 1.5 2002/02/07 19:17:27 jstrachan Exp $
  + * $Id: TestAll.java,v 1.6 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -71,7 +71,7 @@
   /** Entry point for all JUnit tests.
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.5 $
  +  * @version $Revision: 1.6 $
    */
   public class TestAll extends TestCase {
       
  @@ -85,6 +85,7 @@
           suite.addTest(TestXMLIntrospector.suite());
           suite.addTest(TestEvaluation.suite());
           suite.addTest(TestXMLBeanInfoDigester.suite());
  +        suite.addTest(TestRSSRoundTrip.suite());
           return suite;
       }
       
  
  
  
  1.3       +3 -3      jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestBeanReader.java
  
  Index: TestBeanReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestBeanReader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestBeanReader.java	6 Feb 2002 19:19:12 -0000	1.2
  +++ TestBeanReader.java	19 Feb 2002 06:10:27 -0000	1.3
  @@ -5,7 +5,7 @@
    * version 1.1, a copy of which has been included with this distribution in
    * the LICENSE file.
    * 
  - * $Id: TestBeanReader.java,v 1.2 2002/02/06 19:19:12 rdonkin Exp $
  + * $Id: TestBeanReader.java,v 1.3 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -21,14 +21,14 @@
   import org.apache.commons.betwixt.io.BeanWriter;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.commons.logging.impl.SimpleLog;
   
   
   /** Test harness for the BeanReader
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.2 $
  +  * @version $Revision: 1.3 $
     */
   public class TestBeanReader extends TestCase {
       
  
  
  
  1.11      +6 -6      jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestBeanWriter.java
  
  Index: TestBeanWriter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestBeanWriter.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- TestBeanWriter.java	10 Feb 2002 19:19:39 -0000	1.10
  +++ TestBeanWriter.java	19 Feb 2002 06:10:27 -0000	1.11
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestBeanWriter.java,v 1.10 2002/02/10 19:19:39 rdonkin Exp $
  - * $Revision: 1.10 $
  - * $Date: 2002/02/10 19:19:39 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestBeanWriter.java,v 1.11 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.11 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: TestBeanWriter.java,v 1.10 2002/02/10 19:19:39 rdonkin Exp $
  + * $Id: TestBeanWriter.java,v 1.11 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -71,14 +71,14 @@
   import org.apache.commons.betwixt.io.BeanWriter;
   
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.commons.logging.impl.SimpleLog;
   
   
   /** Test harness for the BeanWriter
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.10 $
  +  * @version $Revision: 1.11 $
     */
   public class TestBeanWriter extends AbstractTestCase {
       
  
  
  
  1.2       +8 -6      jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestXMLBeanInfoDigester.java
  
  Index: TestXMLBeanInfoDigester.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestXMLBeanInfoDigester.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestXMLBeanInfoDigester.java	7 Feb 2002 19:17:27 -0000	1.1
  +++ TestXMLBeanInfoDigester.java	19 Feb 2002 06:10:27 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestXMLBeanInfoDigester.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  - * $Revision: 1.1 $
  - * $Date: 2002/02/07 19:17:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestXMLBeanInfoDigester.java,v 1.2 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: TestXMLBeanInfoDigester.java,v 1.1 2002/02/07 19:17:27 jstrachan Exp $
  + * $Id: TestXMLBeanInfoDigester.java,v 1.2 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt;
   
  @@ -74,7 +74,7 @@
   /** Test harness for the Digester of XMLBeanInfo
     *
     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  -  * @version $Revision: 1.1 $
  +  * @version $Revision: 1.2 $
     */
   public class TestXMLBeanInfoDigester extends AbstractTestCase {
       
  @@ -93,7 +93,9 @@
       public void testDigester() throws Exception {
           XMLBeanInfoDigester digester = new XMLBeanInfoDigester();
   
  -        InputStream in = Channel.class.getResourceAsStream( "Channel.betwixt.xml" );
  +        InputStream in = Channel.class.getResourceAsStream( "Channel.betwixt" );
  +        
  +        assertTrue( "Found betwixt config file", in != null );
           
           XMLBeanInfo info = (XMLBeanInfo) digester.parse( in );
           
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestRSSRoundTrip.java
  
  Index: TestRSSRoundTrip.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/TestRSSRoundTrip.java,v 1.1 2002/02/19 06:10:27 jstrachan Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/19 06:10:27 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   * $Id: TestRSSRoundTrip.java,v 1.1 2002/02/19 06:10:27 jstrachan Exp $
   */
  package org.apache.commons.betwixt;
  
  import java.io.InputStream;
  import java.io.StringReader;
  import java.io.StringWriter;
  import java.io.Writer;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  import org.apache.commons.betwixt.io.BeanWriter;
  
  import org.apache.commons.digester.rss.RSSDigester;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.commons.logging.impl.SimpleLog;
  
  
  /** Test harness which parses an RSS document using Digester
    * then outputs it using Betwixt, then parses it again with Digester
    * to check that the document is parseable again.
    *
    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    * @version $Revision: 1.1 $
    */
  public class TestRSSRoundTrip extends AbstractTestCase {
      
      public static void main( String[] args ) {
          TestRunner.run( suite() );
      }
      
      public static Test suite() {
          return new TestSuite(TestRSSRoundTrip.class);
      }
      
      public TestRSSRoundTrip(String testName) {
          super(testName);
      }
      
      
  
      public void testRoundTrip() throws Exception {
          // lets parse the example 
          RSSDigester digester = new RSSDigester();
          
          InputStream in = getClass().getResourceAsStream( "rss-example.xml" );
          Object bean = digester.parse( in ); 
          in.close();
          
          // now lets output it to a buffer
          StringWriter buffer = new StringWriter();
          write( bean, buffer );
          
          // now lets try parse again
          String text = buffer.toString();
          bean = digester.parse( new StringReader( text ) );
          
          // managed to parse it again!
          
          // now lets write it to another buffer
          buffer = new StringWriter();
          write( bean, buffer );
          
          String text2 = buffer.toString();
          
          assertEquals( "Round trip value should remain unchanged", text, text2 );
      }
      
      protected void write(Object bean, Writer out) throws Exception {
          BeanWriter writer = new BeanWriter(out);
          writer.getXMLIntrospector().setAttributesForPrimitives(false);
          writer.enablePrettyPrint();
          writer.write( bean );
      }
  }
  
  
  
  
  1.3       +7 -7      jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/expression/TestEvaluation.java
  
  Index: TestEvaluation.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/expression/TestEvaluation.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestEvaluation.java	31 Jan 2002 19:20:27 -0000	1.2
  +++ TestEvaluation.java	19 Feb 2002 06:10:27 -0000	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/expression/TestEvaluation.java,v 1.2 2002/01/31 19:20:27 rdonkin Exp $
  - * $Revision: 1.2 $
  - * $Date: 2002/01/31 19:20:27 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/expression/TestEvaluation.java,v 1.3 2002/02/19 06:10:27 jstrachan Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/02/19 06:10:27 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: TestEvaluation.java,v 1.2 2002/01/31 19:20:27 rdonkin Exp $
  + * $Id: TestEvaluation.java,v 1.3 2002/02/19 06:10:27 jstrachan Exp $
    */
   package org.apache.commons.betwixt.expression;
   
  @@ -65,13 +65,13 @@
   
   import org.apache.commons.betwixt.CustomerBean;
   
  -import org.apache.commons.logging.LogSource;
  +import org.apache.commons.logging.LogFactory;
   import org.apache.commons.logging.Log;
   
   /** Test harness for the evaluation of beans using contexts.
     *
     * @author Robert Burrell Donkin
  -  * @version $Revision: 1.2 $
  +  * @version $Revision: 1.3 $
     */
   public class TestEvaluation extends TestCase {
       
  @@ -79,7 +79,7 @@
           return new TestSuite(TestEvaluation.class);
       }
       
  -    private Log log = LogSource.makeNewLogInstance("org.apache.commons.betwixt.TestEvaluation");
  +    private Log log = LogFactory.getLog( TestEvaluation.class );
       
       public TestEvaluation(String testName) {
           super(testName);
  
  
  
  1.1                  jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/digester/rss/Channel.betwixt
  
  Index: Channel.betwixt
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <info primitiveTypes="element">
    <element name="rss">
      <attribute name="version" value="0.91"/>
      <element name="channel">
        <element name="title" property="title"/>
        <element name="item"  property="items"/>
      </element>
      <addDefaults/>
    </element>
  </info>
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>