rdonkin     2003/03/19 14:59:02

  Modified:    betwixt/src/java/org/apache/commons/betwixt
                        ElementDescriptor.java NodeDescriptor.java
               betwixt/src/java/org/apache/commons/betwixt/digester
                        ElementRule.java XMLBeanInfoDigester.java
               betwixt/src/java/org/apache/commons/betwixt/io
                        AbstractBeanWriter.java
  Added:       betwixt/src/java/org/apache/commons/betwixt Descriptor.java
                        TextDescriptor.java
               betwixt/src/java/org/apache/commons/betwixt/digester
                        MappedPropertyRule.java TextRule.java
  Log:
  Added support for writing mixed content text. Added a new element called text to the 
betwixt file format. This allows a descriptor to be specifies which allows either 
static or property mapped mixed content text to be specified.
  
  Revision  Changes    Path
  1.8       +95 -0     
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.java
  
  Index: ElementDescriptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/ElementDescriptor.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ElementDescriptor.java    29 Jan 2003 18:55:09 -0000      1.7
  +++ ElementDescriptor.java    19 Mar 2003 22:59:01 -0000      1.8
  @@ -90,6 +90,12 @@
       private ElementDescriptor[] elementDescriptors;
       
       /** 
  +     * Descriptors for child content
  +     * Constructed lazily on demand from a List.
  +     */
  +    private Descriptor[] contentDescriptors;
  +    
  +    /** 
        * The List used on construction. It will be GC'd
        * after initilization and the array is lazily constructed
        */
  @@ -100,6 +106,12 @@
        * after initilization and the array is lazily constructed
        */
       private List elementList;
  +    
  +    /** 
  +     * The list used o construct array. It will be GC'd after
  +     * initialization when the array is lazily constructed.
  +     */
  +    private List contentList;
           
       /** the expression used to evaluate the new context of this node 
        * or null if the same context is to be used */
  @@ -169,6 +181,16 @@
       }
       
       /** 
  +     * Returns true if this element has child content.
  +     * @return true if this element has either child mixed content or child elements
  +     * @see #getContentDescriptors
  +     */
  +    public boolean hasContent() {
  +        return contentDescriptors != null && contentDescriptors.length > 0; 
  +     } 
  +    
  +    
  +    /** 
        * Sets whether <code>Collection</code> bean properties should wrap items in a 
parent element.
        * In other words, should the mapping for bean properties which are 
<code>Collection</code>s 
        * enclosed the item elements within a parent element.
  @@ -253,6 +275,7 @@
           }
           getElementList().add( descriptor );
           elementDescriptors = null;
  +        addContentDescriptor( descriptor );
       }
       
       /** 
  @@ -277,12 +300,58 @@
   
       /** 
        * Sets the descriptors for the child element of the element this describes. 
  +     * Also sets the child content descriptors for this element
  +     *
        * @param elementDescriptors the <code>ElementDescriptor</code>s of the element 
        * that this describes
        */
       public void setElementDescriptors(ElementDescriptor[] elementDescriptors) {
           this.elementDescriptors = elementDescriptors;
           this.elementList = null;
  +        setContentDescriptors( elementDescriptors );
  +    }
  +    
  +    /**
  +     * Adds a descriptor for child content.
  +     * 
  +     * @param descriptor the <code>Descriptor</code> describing the child content 
to add
  +     */
  +    public void addContentDescriptor(Descriptor descriptor) {
  +        if ( contentList == null ) {
  +            contentList = new ArrayList();
  +        }
  +        getContentList().add( descriptor );
  +        contentDescriptors = null;
  +    }
  +    
  +    /** 
  +     * Returns descriptors for the child content of the element this describes.
  +     * @return the <code>Descriptor</code> describing the child elements
  +     * of the element that this <code>ElementDescriptor</code> describes
  +     */
  +    public Descriptor[] getContentDescriptors() {
  +        if ( contentDescriptors == null ) {
  +            if ( contentList == null ) {
  +                contentDescriptors = new Descriptor[0];
  +            } else {
  +                contentDescriptors = new Descriptor[ contentList.size() ];
  +                contentList.toArray( contentDescriptors );
  +                
  +                // allow GC of List when initialized
  +                contentList = null;
  +            }
  +        }
  +        return contentDescriptors;
  +    }
  +
  +    /** 
  +     * Sets the descriptors for the child content of the element this describes. 
  +     * @param contentDescriptors the <code>Descriptor</code>s of the element 
  +     * that this describes
  +     */
  +    public void setContentDescriptors(Descriptor[] contentDescriptors) {
  +        this.contentDescriptors = contentDescriptors;
  +        this.contentList = null;
       }
       
       /** 
  @@ -370,6 +439,32 @@
               }            
           }
           return elementList;
  +    }
  +    
  +    /**  
  +     * Lazily creates the mutable List of child content descriptors.
  +     * This nullifies the contentDescriptors array so that
  +     * as items are added to the list the Array is ignored until it is
  +     * explicitly asked for.
  +     *
  +     * @return list of <code>Descriptor</code>'s describe the child content of 
  +     * the element that this <code>Descriptor</code> describes
  +     */
  +    protected List getContentList() {
  +        if ( contentList == null ) {
  +            if ( contentDescriptors != null ) {
  +                int size = contentDescriptors.length;
  +                contentList = new ArrayList( size );
  +                for ( int i = 0; i < size; i++ ) {
  +                    contentList.add( contentDescriptors[i] );
  +                }
  +                // force lazy recreation later
  +                contentDescriptors = null;
  +            } else {
  +                contentList = new ArrayList();
  +            }            
  +        }
  +        return contentList;
       }
       
       /**
  
  
  
  1.6       +1 -107    
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/NodeDescriptor.java
  
  Index: NodeDescriptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/NodeDescriptor.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- NodeDescriptor.java       13 Jan 2003 18:07:52 -0000      1.5
  +++ NodeDescriptor.java       19 Mar 2003 22:59:01 -0000      1.6
  @@ -73,7 +73,7 @@
     * @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
     * @version $Revision$
     */
  -public class NodeDescriptor {
  +public class NodeDescriptor extends Descriptor {
   
       /** The local name of this node without any namespace prefix */
       private String localName;
  @@ -81,17 +81,6 @@
       private String qualifiedName;
       /** The namespace URI of this node */
       private String uri = "";
  -    /** the expression used to evaluate the text value of this node */
  -    private Expression textExpression;
  -    /** the updater used to update the current bean from the text value of this 
node */
  -    private Updater updater;
  -    /** The property expression to which this node refers to, or null if it is just 
a constant */
  -    private String propertyName;
  -    /** the property type associated with this node, if any */
  -    private Class propertyType;
  -    /** the singular property type (i.e. the type ignoring the Collection or Array 
*/
  -    private Class singularPropertyType;
  -    
       
       /** Base constructor */
       public NodeDescriptor() {
  @@ -179,99 +168,4 @@
           }
           this.uri = uri;
       }
  -    
  -    /** 
  -     * Gets the expression used to evaluate the text value of this node 
  -     * for a particular <code>Context</code>.
  -     * @return the expression used to evaluate the text value of this node 
  -     */
  -    public Expression getTextExpression() {
  -        return textExpression;
  -    }
  -    
  -    /** 
  -     * Sets the expression used to evaluate the text value of this node
  -     * for a particular <code>Context</code>
  -     * @param textExpression the Expression to be used to evaluate the value of 
this node
  -     */
  -    public void setTextExpression(Expression textExpression) {
  -        this.textExpression = textExpression;
  -    }
  -    
  -    /** 
  -     * Gets the <code>Updater</code> used to update a <code>Context</code> from the 
text value
  -     * corresponding to this node in an xml document
  -     * @return the Update that should be used to update the value of this node
  -     */
  -    public Updater getUpdater() {
  -        return updater;
  -    }
  -    
  -    /**
  -     * Sets the <code>Updater</code> used to update a <code>Context</code> from the 
text value
  -     * corresponding to this node in an xml document
  -     * @param updater the Updater to be used to update the values of this node
  -     */
  -    public void setUpdater(Updater updater) {
  -        this.updater = updater;
  -    }
  -    
  -    /** 
  -     * Gets the type of the bean property associated with this node, if any
  -     * @return the property type associated with this node, if any 
  -     */
  -    public Class getPropertyType() {
  -        return propertyType;
  -    }
  -    
  -    /** 
  -     * Sets the type of the bean property associated with this node, if any 
  -     * @param propertyType the Class of the bean property
  -     */
  -    public void setPropertyType(Class propertyType) {
  -        this.propertyType = propertyType;
  -    }
  -
  -    
  -    /** 
  -     * Gets the name of the bean property to which this node refers
  -     * @return the name of the bean property to which this node refers to, 
  -     * or null if it is just a constant 
  -     */
  -    public String getPropertyName() {
  -        return propertyName;
  -    }
  -    
  -    /** 
  -     * Sets the name of the bean property to which this node refers
  -     * @param propertyName the name of the bean property. 
  -     * Or null, if this node is not mapped to to a bean property
  -     */
  -    public void setPropertyName(String propertyName) {
  -        this.propertyName = propertyName;
  -    }
  -    
  -    /** 
  -     * Gets the underlying type ignoring any wrapping a Collection or Array.
  -     *
  -     * @return if this property is a 1-N relationship then this returns the type
  -     * of a single property value.
  -     */
  -    public Class getSingularPropertyType() {
  -        if ( singularPropertyType == null ) {
  -            return getPropertyType();
  -        }
  -        return singularPropertyType;
  -    }
  -    
  -    /** 
  -     * Sets the underlying type ignoring any wrapping Collection or Array.
  -     *
  -     * @param singularPropertyType the Class of the items in the Collection or 
Array. 
  -     * If node is associated with a collective bean property, then this should not 
be null.
  -     */
  -    public void setSingularPropertyType(Class singularPropertyType) {
  -        this.singularPropertyType = singularPropertyType;
  -    }
  -
   }
  
  
  
  1.1                  
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/Descriptor.java
  
  Index: Descriptor.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/Descriptor.java,v
 1.1 2003/03/19 22:59:01 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2003/03/19 22:59:01 $
   *
   * ====================================================================
   *
   * 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 [EMAIL PROTECTED]
   *
   * 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: Descriptor.java,v 1.1 2003/03/19 22:59:01 rdonkin Exp $
   */
  package org.apache.commons.betwixt;
  
  import org.apache.commons.betwixt.expression.Expression;
  import org.apache.commons.betwixt.expression.Updater;
  
  /** <p>Describes a content node mapping.</p>
    * Common superclass for types of <code>Descriptor</code></p>
    *
    * @author Robert Burrell Donkin
    * @version $Revision: 1.1 $
    */
  public abstract class Descriptor {
  
      /** the expression used to evaluate the text value of this node */
      private Expression textExpression;
      /** the updater used to update the current bean from the text value of this node 
*/
      private Updater updater;
      /** The property expression to which this node refers to, or null if it is just 
a constant */
      private String propertyName;
      /** the property type associated with this node, if any */
      private Class propertyType;
      /** the singular property type (i.e. the type ignoring the Collection or Array */
      private Class singularPropertyType;
      
      
      /** Base constructor */
      public Descriptor() {
      }   
          
      /** 
       * Gets the expression used to evaluate the text value of this node 
       * for a particular <code>Context</code>.
       * @return the expression used to evaluate the text value of this node 
       */
      public Expression getTextExpression() {
          return textExpression;
      }
      
      /** 
       * Sets the expression used to evaluate the text value of this node
       * for a particular <code>Context</code>
       * @param textExpression the Expression to be used to evaluate the value of this 
node
       */
      public void setTextExpression(Expression textExpression) {
          this.textExpression = textExpression;
      }
      
      /** 
       * Gets the <code>Updater</code> used to update a <code>Context</code> from the 
text value
       * corresponding to this node in an xml document
       * @return the Update that should be used to update the value of this node
       */
      public Updater getUpdater() {
          return updater;
      }
      
      /**
       * Sets the <code>Updater</code> used to update a <code>Context</code> from the 
text value
       * corresponding to this node in an xml document
       * @param updater the Updater to be used to update the values of this node
       */
      public void setUpdater(Updater updater) {
          this.updater = updater;
      }
      
      /** 
       * Gets the type of the bean property associated with this node, if any
       * @return the property type associated with this node, if any 
       */
      public Class getPropertyType() {
          return propertyType;
      }
      
      /** 
       * Sets the type of the bean property associated with this node, if any 
       * @param propertyType the Class of the bean property
       */
      public void setPropertyType(Class propertyType) {
          this.propertyType = propertyType;
      }
  
      
      /** 
       * Gets the name of the bean property to which this node refers
       * @return the name of the bean property to which this node refers to, 
       * or null if it is just a constant 
       */
      public String getPropertyName() {
          return propertyName;
      }
      
      /** 
       * Sets the name of the bean property to which this node refers
       * @param propertyName the name of the bean property. 
       * Or null, if this node is not mapped to to a bean property
       */
      public void setPropertyName(String propertyName) {
          this.propertyName = propertyName;
      }
      
      /** 
       * Gets the underlying type ignoring any wrapping a Collection or Array.
       *
       * @return if this property is a 1-N relationship then this returns the type
       * of a single property value.
       */
      public Class getSingularPropertyType() {
          if ( singularPropertyType == null ) {
              return getPropertyType();
          }
          return singularPropertyType;
      }
      
      /** 
       * Sets the underlying type ignoring any wrapping Collection or Array.
       *
       * @param singularPropertyType the Class of the items in the Collection or 
Array. 
       * If node is associated with a collective bean property, then this should not 
be null.
       */
      public void setSingularPropertyType(Class singularPropertyType) {
          this.singularPropertyType = singularPropertyType;
      }
  
  }
  
  
  
  1.1                  
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/TextDescriptor.java
  
  Index: TextDescriptor.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/TextDescriptor.java,v
 1.1 2003/03/19 22:59:01 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2003/03/19 22:59:01 $
   *
   * ====================================================================
   *
   * 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 [EMAIL PROTECTED]
   *
   * 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: TextDescriptor.java,v 1.1 2003/03/19 22:59:01 rdonkin Exp $
   */
  package org.apache.commons.betwixt;
  
  /** <p>Describes mixed-content text. 
    * A mixed content element contains elements mixed with text.
    * For example:
    * <pre>
    *   &lt;foo&gt;middle&lt;bar/&gt;&lt;/foo&gt;
    * </pre>
    * In the above example, a <code>TextDescriptor</code> could be used
    * to allow the mixed content text <code>middle</code> to be mapped.</p>
    *
    * <p>This is really just a marker class - all functionality is inherited.</p>
    *
    * @author Robert Burrell Donkin
    * @version $Revision: 1.1 $
    */
  public class TextDescriptor extends Descriptor {
      
      /** Base constructor */
      public TextDescriptor() {
      }   
  
  }
  
  
  
  1.9       +4 -85     
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/ElementRule.java
  
  Index: ElementRule.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/ElementRule.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ElementRule.java  18 Mar 2003 22:30:43 -0000      1.8
  +++ ElementRule.java  19 Mar 2003 22:59:01 -0000      1.9
  @@ -77,18 +77,15 @@
     * @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
     * @version $Id$
     */
  -public class ElementRule extends RuleSupport {
  +public class ElementRule extends MappedPropertyRule {
   
       /** Logger */
       private static final Log log = LogFactory.getLog( ElementRule.class );
  -    /** Classloader used to load classes by name */
  -    private ClassLoader classLoader;
  +
       /** Class for which the .bewixt file is being digested */
       private Class beanClass;
       /** Base constructor */
  -    public ElementRule() {
  -        this.classLoader = getClass().getClassLoader();
  -    }
  +    public ElementRule() {}
       
       // Rule interface
       //-------------------------------------------------------------------------    
  @@ -179,46 +176,6 @@
       // Implementation methods
       //-------------------------------------------------------------------------    
       
  -    /**
  -     * Gets the type of a property
  -     *
  -     * @param propertyClassName class name for property type (may be null)
  -     * @param beanClass class that has property 
  -     * @param propertyName the name of the property whose type is to be determined
  -     * @return property type 
  -     */
  -    protected Class getPropertyType( String propertyClassName, 
  -                                     Class beanClass, String propertyName ) {
  -        // XXX: should use a ClassLoader to handle 
  -        //      complex class loading situations
  -        if ( propertyClassName != null ) {
  -            try {
  -                Class answer = classLoader.loadClass(propertyClassName);
  -                if (answer != null) {
  -                    if (log.isTraceEnabled()) {
  -                        log.trace("Used specified type " + answer);
  -                    }
  -                    return answer;
  -                }
  -            } catch (Exception e) {
  -                log.warn("Cannot load specified type", e);
  -            }
  -        }
  -        
  -        PropertyDescriptor descriptor = 
  -            getPropertyDescriptor( beanClass, propertyName );        
  -        if ( descriptor != null ) { 
  -            return descriptor.getPropertyType();
  -        }
  -        
  -        if (log.isTraceEnabled()) {
  -            log.trace("Cannot find property type.");
  -            log.trace("  className=" + propertyClassName 
  -                        + " base=" + beanClass + " name=" + propertyName);
  -        }
  -        return null;            
  -    }
  -    
       /** 
        * Set the Expression and Updater from a bean property name 
        *
  @@ -236,43 +193,5 @@
                   getProcessedPropertyNameSet().add( name );
               }
           }
  -    }    
  -
  -    /** 
  -     * Returns the property descriptor for the class and property name.
  -     * Note that some caching could be used to improve performance of 
  -     * this method. Or this method could be added to PropertyUtils.
  -     *
  -     * @param beanClass descriptor for property in this class
  -     * @param propertyName descriptor for property with this name
  -     * @return property descriptor for the named property in the given class 
  -     */
  -    protected PropertyDescriptor getPropertyDescriptor( Class beanClass, 
  -                                                        String propertyName ) {
  -        if ( beanClass != null && propertyName != null ) {
  -            if (log.isTraceEnabled()) {
  -                log.trace("Searching for property " + propertyName + " on " + 
beanClass);
  -            }
  -            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 ( propertyName.equals( descriptor.getName() ) ) {
  -                            log.trace("Found matching method.");
  -                            return descriptor;
  -                        }
  -                    }
  -                }
  -                log.trace("No match found.");
  -                return null;
  -            } catch (Exception e) {
  -                log.warn( "Caught introspection exception", e );
  -            }
  -        }
  -        return null;
  -    }
  -    
  +    }        
   }
  
  
  
  1.4       +1 -0      
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/XMLBeanInfoDigester.java
  
  Index: XMLBeanInfoDigester.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/XMLBeanInfoDigester.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLBeanInfoDigester.java  7 Jan 2003 22:32:57 -0000       1.3
  +++ XMLBeanInfoDigester.java  19 Mar 2003 22:59:01 -0000      1.4
  @@ -204,6 +204,7 @@
               
               addRule( "info", new InfoRule() );
               addRule( "*/element", new ElementRule() );
  +            addRule( "*/text", new TextRule() );
               addRule( "*/attribute", new AttributeRule() );
               addRule( "*/hide", new HideRule() );
               addRule( "*/addDefaults", new AddDefaultsRule() );
  
  
  
  1.1                  
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/MappedPropertyRule.java
  
  Index: MappedPropertyRule.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/MappedPropertyRule.java,v
 1.1 2003/03/19 22:59:01 rdonkin Exp $
   * $Revision: 1.1 $
   * $Date: 2003/03/19 22:59:01 $
   *
   * ====================================================================
   *
   * 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 [EMAIL PROTECTED]
   *
   * 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: MappedPropertyRule.java,v 1.1 2003/03/19 22:59:01 rdonkin Exp $
   */
  package org.apache.commons.betwixt.digester;
  
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  import java.beans.BeanInfo;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /** <p>Factors out common code used by Betwixt rules that access bean properties.
    * Maybe a lot of this should be moved into <code>BeanUtils</code>.</p>
    *
    * @author Robert Burrell Donkin
    * @version $Revision: 1.1 $
    */
  abstract public class MappedPropertyRule extends RuleSupport {
  
      /** Logger */
      private static final Log log = LogFactory.getLog( MappedPropertyRule.class );   
       /** Classloader used to load classes by name */
      private ClassLoader classLoader;
      /** Base constructor */
      public MappedPropertyRule() {
          this.classLoader = getClass().getClassLoader();
      }
      
      
  
      // Implementation methods
      //-------------------------------------------------------------------------    
  
      /** 
       * Returns the property descriptor for the class and property name.
       * Note that some caching could be used to improve performance of 
       * this method. Or this method could be added to PropertyUtils.
       *
       * @param beanClass descriptor for property in this class
       * @param propertyName descriptor for property with this name
       * @return property descriptor for the named property in the given class 
       */
      protected PropertyDescriptor getPropertyDescriptor( Class beanClass, 
                                                          String propertyName ) {
          if ( beanClass != null && propertyName != null ) {
              if (log.isTraceEnabled()) {
                  log.trace("Searching for property " + propertyName + " on " + 
beanClass);
              }
              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 ( propertyName.equals( descriptor.getName() ) ) {
                              log.trace("Found matching method.");
                              return descriptor;
                          }
                      }
                  }
                  log.trace("No match found.");
                  return null;
              } catch (Exception e) {
                  log.warn( "Caught introspection exception", e );
              }
          }
          return null;
      }
      
      
      /**
       * Gets the type of a property
       *
       * @param propertyClassName class name for property type (may be null)
       * @param beanClass class that has property 
       * @param propertyName the name of the property whose type is to be determined
       * @return property type 
       */
      protected Class getPropertyType( String propertyClassName, 
                                       Class beanClass, String propertyName ) {
          // XXX: should use a ClassLoader to handle 
          //      complex class loading situations
          if ( propertyClassName != null ) {
              try {
                  Class answer = classLoader.loadClass(propertyClassName);
                  if (answer != null) {
                      if (log.isTraceEnabled()) {
                          log.trace("Used specified type " + answer);
                      }
                      return answer;
                  }
              } catch (Exception e) {
                  log.warn("Cannot load specified type", e);
              }
          }
          
          PropertyDescriptor descriptor = 
              getPropertyDescriptor( beanClass, propertyName );        
          if ( descriptor != null ) { 
              return descriptor.getPropertyType();
          }
          
          if (log.isTraceEnabled()) {
              log.trace("Cannot find property type.");
              log.trace("  className=" + propertyClassName 
                          + " base=" + beanClass + " name=" + propertyName);
          }
          return null;            
      }
  }
  
  
  
  1.1                  
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/TextRule.java
  
  Index: TextRule.java
  ===================================================================
  package org.apache.commons.betwixt.digester;
  
  /*
   * ====================================================================
   *
   * 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 [EMAIL PROTECTED]
   *
   * 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/>.
   * 
   */
  
  import java.beans.BeanInfo;
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  
  import java.lang.reflect.Method;
  
  import org.apache.commons.betwixt.expression.MethodExpression;
  import org.apache.commons.betwixt.expression.ConstantExpression;
  import org.apache.commons.betwixt.TextDescriptor;
  import org.apache.commons.betwixt.ElementDescriptor;
  import org.apache.commons.betwixt.XMLBeanInfo;
  import org.apache.commons.betwixt.XMLUtils;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  /** 
    * <p>Rule for parsing &lt;text&gt; elements.
    * These allow mixed content text to be specified.
    * A mixed content element example:
    * <pre>
    *   &lt;foo&gt;text&lt;bar/&gt;&lt;/foo&gt;
    * </pre>
    * </p>
    *
    * @author Robert Burrell Donkin
    * @version $Id: TextRule.java,v 1.1 2003/03/19 22:59:01 rdonkin Exp $
    */
  public class TextRule extends MappedPropertyRule {
  
      /** Logger */
      private static final Log log = LogFactory.getLog( TextRule.class );
      /** Class for which the .bewixt file is being digested */
      private Class beanClass;
      /** Base constructor */
      public TextRule() {}
      
      // Rule interface
      //-------------------------------------------------------------------------    
      
      /**
       * Process the beginning of this element.
       *
       * @param attributes The attribute list of this element
       * @throws SAXException 1. If this tag's parent is not an element tag.
       * 2. If this tag has a value attribute together with either a property
       * or type attribute.
       */
      public void begin(Attributes attributes) throws SAXException {
          
          TextDescriptor descriptor = new TextDescriptor();
          
          String value = attributes.getValue( "value" );
          String propertyName = attributes.getValue( "property" );
          String propertyType = attributes.getValue( "type" );
          
          if ( value != null) {
              if ( propertyName != null || propertyType != null ) {
                  // not allowed
                  throw new SAXException("You cannot specify attribute 'value' 
together with either " +
                      " the 'property' or 'type' attributes");                
              }
              // fixed value text
              descriptor.setTextExpression( new ConstantExpression( value ) );
              
          } else {
              // property based text
              descriptor.setPropertyName( propertyName );
              
              
              // set the property type using reflection
              descriptor.setPropertyType( 
                  getPropertyType( propertyType, beanClass, propertyName ) 
              );
              
              Class beanClass = getBeanClass();
              if ( beanClass != null ) {
                  String name = descriptor.getPropertyName();
                  PropertyDescriptor propertyDescriptor = 
                      getPropertyDescriptor( beanClass, name );
                  if ( propertyDescriptor != null ) { 
                          Method readMethod = propertyDescriptor.getReadMethod();
                          descriptor.setTextExpression( new MethodExpression( 
readMethod ) );
                          getProcessedPropertyNameSet().add( name );
                  }
              }
          }
          
          Object top = digester.peek();
          if ( top instanceof XMLBeanInfo ) {
              XMLBeanInfo beanInfo = (XMLBeanInfo) top;
              ElementDescriptor elementDescriptor = beanInfo.getElementDescriptor();
              if (elementDescriptor == null) {
                  elementDescriptor.addContentDescriptor( descriptor );
              }
              beanClass = beanInfo.getBeanClass();
              
          } else if ( top instanceof ElementDescriptor ) {
              ElementDescriptor parent = (ElementDescriptor) top;
              parent.addContentDescriptor( descriptor );
              
          } else {
              throw new SAXException( "Invalid use of <text>. It should " 
                  + "be nested <text> nodes" );
          }
      }
  }
  
  
  
  1.15      +49 -32    
jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/io/AbstractBeanWriter.java
  
  Index: AbstractBeanWriter.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/io/AbstractBeanWriter.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- AbstractBeanWriter.java   27 Feb 2003 19:20:17 -0000      1.14
  +++ AbstractBeanWriter.java   19 Mar 2003 22:59:02 -0000      1.15
  @@ -68,6 +68,7 @@
   
   import org.apache.commons.betwixt.AttributeDescriptor;
   import org.apache.commons.betwixt.ElementDescriptor;
  +import org.apache.commons.betwixt.Descriptor;
   import org.apache.commons.betwixt.XMLBeanInfo;
   import org.apache.commons.betwixt.XMLIntrospector;
   import org.apache.commons.betwixt.expression.Context;
  @@ -688,39 +689,55 @@
                                   SAXException,
                                   IntrospectionException {     
                                   
  -        ElementDescriptor[] childDescriptors = 
elementDescriptor.getElementDescriptors();
  +        Descriptor[] childDescriptors = elementDescriptor.getContentDescriptors();
           if ( childDescriptors != null && childDescriptors.length > 0 ) {
               // process child elements
               for ( int i = 0, size = childDescriptors.length; i < size; i++ ) {
  -                ElementDescriptor childDescriptor = childDescriptors[i];
  -                Context childContext = context;
  -                Expression childExpression = childDescriptor.getContextExpression();
  -                if ( childExpression != null ) {
  -                    Object childBean = childExpression.evaluate( context );
  -                    if ( childBean != null ) {
  -                        String qualifiedName = childDescriptor.getQualifiedName();
  -                        String namespaceUri = childDescriptor.getURI();
  -                        String localName = childDescriptor.getLocalName();
  -                        // XXXX: should we handle nulls better
  -                        if ( childBean instanceof Iterator ) {
  -                            for ( Iterator iter = (Iterator) childBean; 
iter.hasNext(); ) {
  -                                Object object = iter.next();
  -                                if (object == null) {
  -                                    continue;
  +                if (childDescriptors[i] instanceof ElementDescriptor) {
  +                    // Element content
  +                    ElementDescriptor childDescriptor = (ElementDescriptor) 
childDescriptors[i];
  +                    Context childContext = context;
  +                    Expression childExpression = 
childDescriptor.getContextExpression();
  +                    if ( childExpression != null ) {
  +                        Object childBean = childExpression.evaluate( context );
  +                        if ( childBean != null ) {
  +                            String qualifiedName = 
childDescriptor.getQualifiedName();
  +                            String namespaceUri = childDescriptor.getURI();
  +                            String localName = childDescriptor.getLocalName();
  +                            // XXXX: should we handle nulls better
  +                            if ( childBean instanceof Iterator ) {
  +                                for ( Iterator iter = (Iterator) childBean; 
iter.hasNext(); ) {
  +                                    Object object = iter.next();
  +                                    if (object == null) {
  +                                        continue;
  +                                    }
  +                                    writeBean( namespaceUri, localName, 
qualifiedName, object );
                                   }
  -                                writeBean( namespaceUri, localName, qualifiedName, 
object );
  +                            } else {
  +                                writeBean( namespaceUri, localName, qualifiedName, 
childBean );
                               }
  -                        } else {
  -                            writeBean( namespaceUri, localName, qualifiedName, 
childBean );
  -                        }
  -                    }                    
  +                        }                    
  +                    } else {
  +                        writeElement(
  +                                    childDescriptor.getURI(), 
  +                                    childDescriptor.getLocalName(), 
  +                                    childDescriptor.getQualifiedName(), 
  +                                    childDescriptor, 
  +                                    childContext );
  +                    }
                   } else {
  -                     writeElement(
  -                                childDescriptor.getURI(), 
  -                                childDescriptor.getLocalName(), 
  -                                childDescriptor.getQualifiedName(), 
  -                                childDescriptor, 
  -                                childContext );
  +                    // Mixed text content
  +                    // evaluate the body text 
  +                    Expression expression = childDescriptors[i].getTextExpression();
  +                    if ( expression != null ) {
  +                        Object value = expression.evaluate( context );
  +                        if ( value != null ) {
  +                            String text = value.toString();
  +                            if ( text != null && text.length() > 0 ) {
  +                                bodyText(text);
  +                            }
  +                        }                
  +                    }
                   }
               }
           } else {
  
  
  

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

Reply via email to