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>
* <foo>middle<bar/></foo>
* </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 <text> elements.
* These allow mixed content text to be specified.
* A mixed content element example:
* <pre>
* <foo>text<bar/></foo>
* </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]