jstrachan 01/08/23 07:25:58
Modified: betwixt build.xml
betwixt/src/java/org/apache/commons/betwixt
ElementDescriptor.java XMLIntrospector.java
betwixt/src/java/org/apache/commons/betwixt/expression
IteratorExpression.java MethodExpression.java
betwixt/src/java/org/apache/commons/betwixt/io
BeanWriter.java
betwixt/src/test/org/apache/commons/betwixt
AbstractTestCase.java CustomerBean.java
Added: betwixt/src/java/org/apache/commons/betwixt/expression
EmptyExpression.java
betwixt/src/test/org/apache/commons/betwixt
SystemProperties.java
Log:
Now the default introspector is working with Map, arrays, enumerations, Collections
and iterators
Revision Changes Path
1.3 +11 -1 jakarta-commons-sandbox/betwixt/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/build.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- build.xml 2001/08/23 04:34:40 1.2
+++ build.xml 2001/08/23 14:25:57 1.3
@@ -1,4 +1,4 @@
-<!-- $Id: build.xml,v 1.2 2001/08/23 04:34:40 jstrachan Exp $ -->
+<!-- $Id: build.xml,v 1.3 2001/08/23 14:25:57 jstrachan Exp $ -->
<project name="betwixt" default="test" basedir=".">
<!-- patternset describing files to be copied from the doc directory -->
@@ -238,6 +238,16 @@
<target name="demo" depends="build-test" description="runs sample program">
<java classname="org.apache.commons.betwixt.SampleBeanWriter" fork="yes">
+ <classpath>
+ <pathelement location="${dest.classes}" />
+ <pathelement path="${classpath}" />
+ <pathelement path="${java.class.path}" />
+ </classpath>
+ </java>
+ </target>
+
+ <target name="demo2" depends="build-test" description="runs sample program2">
+ <java classname="org.apache.commons.betwixt.SystemProperties" fork="yes">
<classpath>
<pathelement location="${dest.classes}" />
<pathelement path="${classpath}" />
1.3 +12 -2
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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ElementDescriptor.java 2001/08/22 18:30:48 1.2
+++ ElementDescriptor.java 2001/08/23 14:25:57 1.3
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
- * $Id: ElementDescriptor.java,v 1.2 2001/08/22 18:30:48 jstrachan Exp $
+ * $Id: ElementDescriptor.java,v 1.3 2001/08/23 14:25:57 jstrachan Exp $
*/
package org.apache.commons.betwixt;
@@ -15,7 +15,7 @@
* to be created for a bean instance.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*/
public class ElementDescriptor extends NodeDescriptor {
@@ -38,6 +38,16 @@
super(localName, qualifiedName, uri);
}
+ /** Returns true if this element has child elements */
+ public boolean hasChildren() {
+ return elementDescriptors != null && elementDescriptors.length > 0;
+ }
+
+ /** Returns true if this element has attributes */
+ public boolean hasAttributes() {
+ return attributeDescriptors != null && attributeDescriptors.length > 0;
+ }
+
/** Returns the attribute descriptors for this element */
public AttributeDescriptor[] getAttributeDescriptors() {
return attributeDescriptors;
1.5 +47 -38
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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- XMLIntrospector.java 2001/08/23 04:34:40 1.4
+++ XMLIntrospector.java 2001/08/23 14:25:57 1.5
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
- * $Id: XMLIntrospector.java,v 1.4 2001/08/23 04:34:40 jstrachan Exp $
+ * $Id: XMLIntrospector.java,v 1.5 2001/08/23 14:25:57 jstrachan Exp $
*/
package org.apache.commons.betwixt;
@@ -26,15 +26,16 @@
import java.util.List;
import java.util.Map;
-import org.apache.commons.betwixt.expression.StringExpression;
+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.StringExpression;
/** <p><code>XMLIntrospector</code> an introspector of beans to create a
XMLBeanInfo instance.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*/
public class XMLIntrospector {
@@ -45,8 +46,7 @@
}
public XMLBeanInfo introspect(Object bean) throws IntrospectionException {
- BeanInfo info = Introspector.getBeanInfo( bean.getClass() );
- return introspect( info );
+ return introspect( bean.getClass() );
}
public XMLBeanInfo introspect(Class aClass) throws IntrospectionException {
@@ -57,13 +57,24 @@
public XMLBeanInfo introspect(BeanInfo beanInfo) throws IntrospectionException
{
XMLBeanInfo answer = createXMLBeanInfo( beanInfo );
+ BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
+ Class beanType = beanDescriptor.getBeanClass();
+
ElementDescriptor elementDescriptor = new ElementDescriptor();
- elementDescriptor.setLocalName( beanInfo.getBeanDescriptor().getName() );
+ elementDescriptor.setLocalName( beanDescriptor.getName() );
// add default string value for primitive types
- if ( isPrimitiveType( beanInfo.getBeanDescriptor().getBeanClass() ) ) {
+ if ( isPrimitiveType( beanType ) ) {
elementDescriptor.setTextExpression( StringExpression.getInstance() );
}
+ else if ( isLoopType( beanType ) ) {
+ ElementDescriptor loopDescriptor = new ElementDescriptor();
+ loopDescriptor.setContextExpression(
+ new IteratorExpression( EmptyExpression.getInstance() )
+ );
+
+ elementDescriptor.setElementDescriptors( new ElementDescriptor[] {
loopDescriptor } );
+ }
else {
ArrayList elements = new ArrayList();
ArrayList attributes = new ArrayList();
@@ -115,30 +126,28 @@
if ( readMethod == null ) {
return;
}
- Expression loop = createLoopExpression( propertyDescriptor, type );
- if ( loop != null ) {
- ElementDescriptor elementDescriptor = new ElementDescriptor();
-
+ if ( isPrimitiveType( type ) ) {
+ nodeDescriptor = new AttributeDescriptor();
+ nodeDescriptor.setTextExpression( new MethodExpression( readMethod ) );
+ attributes.add( nodeDescriptor );
+ }
+ else if ( isLoopType( type ) ) {
ElementDescriptor loopDescriptor = new ElementDescriptor();
- loopDescriptor.setContextExpression( loop );
- elementDescriptor.setElementDescriptors( new ElementDescriptor[] {
loopDescriptor } );
+ loopDescriptor.setContextExpression(
+ new IteratorExpression( new MethodExpression( readMethod ) )
+ );
+ ElementDescriptor elementDescriptor = new ElementDescriptor();
+ elementDescriptor.setElementDescriptors( new ElementDescriptor[] {
loopDescriptor } );
nodeDescriptor = elementDescriptor;
elements.add( nodeDescriptor );
}
- else if ( isPrimitiveType( type ) ) {
- nodeDescriptor = new AttributeDescriptor();
- nodeDescriptor.setTextExpression( new MethodExpression( readMethod ) );
- attributes.add( nodeDescriptor );
- }
else {
- XMLBeanInfo childBeanInfo = introspect( type );
- ElementDescriptor childDescriptor =
childBeanInfo.getElementDescriptor();
+ ElementDescriptor childDescriptor = new ElementDescriptor();
+ childDescriptor.setContextExpression( new MethodExpression( readMethod
) );
ElementDescriptor elementDescriptor = new ElementDescriptor();
- elementDescriptor.setElementDescriptors(
childDescriptor.getElementDescriptors() );
- elementDescriptor.setAttributeDescriptors(
childDescriptor.getAttributeDescriptors() );
- elementDescriptor.setContextExpression( new MethodExpression(
readMethod ) );
+ elementDescriptor.setElementDescriptors( new ElementDescriptor[] {
childDescriptor } );
nodeDescriptor = elementDescriptor;
elements.add( nodeDescriptor );
@@ -157,24 +166,24 @@
return answer;
}
- /** Creates a new Expression for loop based properties such as Arrays,
- * Collections, Enumerations, Arrays etc.
- */
- protected Expression createLoopExpression( PropertyDescriptor
propertyDescriptor, Class type ) {
- if ( type.isArray()
- || type.isAssignableFrom( Map.class )
- || type.isAssignableFrom( Collection.class )
- || type.isAssignableFrom( Enumeration.class )
- || type.isAssignableFrom( Iterator.class )
- ) {
- return new IteratorExpression( new MethodExpression(
propertyDescriptor.getReadMethod() ) );
- }
- return null;
+ /** Returns true if the type is a loop type */
+ protected 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 */
protected boolean isPrimitiveType(Class type) {
- String name = type.getName();
- return name.startsWith( "java.lang." ) || type.isAssignableFrom( Date.class
);
+ 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.2 +1 -5
jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/IteratorExpression.java
Index: IteratorExpression.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/IteratorExpression.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- IteratorExpression.java 2001/08/22 19:44:55 1.1
+++ IteratorExpression.java 2001/08/23 14:25:57 1.2
@@ -13,7 +13,7 @@
/** <p><code>IteratorExpression</code> returns an iterator over the current
context.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public class IteratorExpression implements Expression {
@@ -26,7 +26,6 @@
/** Returns an interator over the current context */
public Object evaluate(Context context) {
Object value = expression.evaluate( context );
- //System.out.println( "IeratorExpression evaluating: " + value );
if ( value instanceof Iterator ) {
return (Iterator) value;
}
@@ -44,10 +43,7 @@
else if ( value != null ) {
Class type = value.getClass();
if ( type.isArray() ) {
-/*
- Object[] array = (Object[]) value;
- return new ArrayIterator( array );
-*/
+ return new ArrayIterator( value );
}
}
return Collections.EMPTY_LIST.iterator();
1.2 +34 -2
jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/MethodExpression.java
Index: MethodExpression.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/MethodExpression.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MethodExpression.java 2001/08/22 12:25:02 1.1
+++ MethodExpression.java 2001/08/23 14:25:57 1.2
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
- * $Id: MethodExpression.java,v 1.1 2001/08/22 12:25:02 jstrachan Exp $
+ * $Id: MethodExpression.java,v 1.2 2001/08/23 14:25:57 jstrachan Exp $
*/
package org.apache.commons.betwixt.expression;
@@ -14,12 +14,13 @@
/** <p><code>MethodExpression</code> evaluates a method on the current bean
context.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public class MethodExpression implements Expression {
/** null arguments */
protected static Object[] NULL_ARGUMENTS;
+ protected static Class[] NULL_CLASSES;
/** The method to call on the bean */
private Method method;
@@ -39,6 +40,19 @@
try {
return method.invoke( bean, arguments );
}
+ catch (IllegalAccessException e) {
+ // lets try use another method with the same name
+ try {
+ Class type = bean.getClass();
+ Method alternate = findAlternateMethod( type, method );
+ if ( alternate != null ) {
+ return alternate.invoke( bean, arguments );
+ }
+ }
+ catch (Exception e2) {
+ handleException(e2);
+ }
+ }
catch (Exception e) {
handleException(e);
}
@@ -62,6 +76,24 @@
/** Allows derived objects to create arguments for the method call */
protected Object[] getArguments() {
return NULL_ARGUMENTS;
+ }
+
+ /** Tries to find an alternate method for the given type using interfaces
+ * which gets around the problem of inner classes, such as on Map.Entry
implementations
+ */
+ protected Method findAlternateMethod( Class type, Method method ) throws
NoSuchMethodException {
+ Class[] interfaces = type.getInterfaces();
+ if ( interfaces != null ) {
+ String name = method.getName();
+ for ( int i = 0, size = interfaces.length; i < size; i++ ) {
+ Class otherType = interfaces[i];
+ Method alternate = otherType.getMethod( name, NULL_CLASSES );
+ if ( alternate != null && alternate != method ) {
+ return alternate;
+ }
+ }
+ }
+ return null;
}
/** Allows derived objects to handle exceptions differently */
1.1
jakarta-commons-sandbox/betwixt/src/java/org/apache/commons/betwixt/expression/EmptyExpression.java
Index: EmptyExpression.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
* $Id: EmptyExpression.java,v 1.1 2001/08/23 14:25:57 jstrachan Exp $
*/
package org.apache.commons.betwixt.expression;
/** <p><code>EmptyExpression</code> returns the same value as is passed in.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
* @version $Revision: 1.1 $
*/
public class EmptyExpression implements Expression {
private static final EmptyExpression singleton = new EmptyExpression();
public static EmptyExpression getInstance() {
return singleton;
}
public EmptyExpression() {
}
public Object evaluate(Context context) {
return context.getBean();
}
}
1.5 +14 -15
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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- BeanWriter.java 2001/08/23 04:34:40 1.4
+++ BeanWriter.java 2001/08/23 14:25:57 1.5
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
- * $Id: BeanWriter.java,v 1.4 2001/08/23 04:34:40 jstrachan Exp $
+ * $Id: BeanWriter.java,v 1.5 2001/08/23 14:25:57 jstrachan Exp $
*/
package org.apache.commons.betwixt.io;
@@ -27,7 +27,7 @@
/** <p><code>BeanWriter</code> outputs a bean as XML.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*/
public class BeanWriter {
@@ -137,22 +137,21 @@
Expression childExpression =
childDescriptor.getContextExpression();
if ( childExpression != null ) {
Object childBean = childExpression.evaluate( context );
- if ( childBean == null ) {
+ if ( childBean != null ) {
// XXXX: should we handle nulls better
- continue;
- }
- if ( childBean instanceof Iterator ) {
- for ( Iterator iter = (Iterator) childBean; iter.hasNext();
) {
- write( iter.next() );
+ if ( childBean instanceof Iterator ) {
+ for ( Iterator iter = (Iterator) childBean;
iter.hasNext(); ) {
+ write( iter.next() );
+ }
}
- continue;
- }
- else {
- childContext = context.newContext( childBean );
- }
-
+ else {
+ write( childBean );
+ }
+ }
+ }
+ else {
+ write( childDescriptor, childContext );
}
- write( childDescriptor, childContext );
}
--indentLevel;
writePrintln();
1.2 +3 -2
jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/AbstractTestCase.java
Index: AbstractTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/AbstractTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractTestCase.java 2001/08/22 18:30:48 1.1
+++ AbstractTestCase.java 2001/08/23 14:25:58 1.2
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
- * $Id: AbstractTestCase.java,v 1.1 2001/08/22 18:30:48 jstrachan Exp $
+ * $Id: AbstractTestCase.java,v 1.2 2001/08/23 14:25:58 jstrachan Exp $
*/
package org.apache.commons.betwixt;
@@ -21,7 +21,7 @@
/** Abstract base class for test cases.
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public abstract class AbstractTestCase extends TestCase {
@@ -33,7 +33,8 @@
CustomerBean bean = new CustomerBean();
bean.setID( "1" );
bean.setName( "James" );
- bean.setEmail( "[EMAIL PROTECTED]" );
+ bean.setEmails( new String[] { "[EMAIL PROTECTED]",
"[EMAIL PROTECTED]" } );
+ bean.setNumbers( new int[] { 3, 4, 5 } );
Map projects = new HashMap();
projects.put( "dom4j", "http://dom4j.org" );
1.5 +16 -9
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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CustomerBean.java 2001/08/23 04:34:40 1.4
+++ CustomerBean.java 2001/08/23 14:25:58 1.5
@@ -5,7 +5,7 @@
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
- * $Id: CustomerBean.java,v 1.4 2001/08/23 04:34:40 jstrachan Exp $
+ * $Id: CustomerBean.java,v 1.5 2001/08/23 14:25:58 jstrachan Exp $
*/
package org.apache.commons.betwixt;
@@ -19,13 +19,14 @@
/** <p><code>CustomerBean</code> is a sample bean for use by the test cases.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*/
public class CustomerBean implements Serializable {
private String id;
private String name;
- private String email;
+ private String[] emails;
+ private int[] numbers;
private AddressBean address;
private Map projectMap;
@@ -40,19 +41,21 @@
return name;
}
- public String getEmail() {
- return email;
+ public String[] getEmails() {
+ return emails;
}
+ public int[] getNumbers() {
+ return numbers;
+ }
+
public AddressBean getAddress() {
return address;
}
-/*
public Map getProjectMap() {
return projectMap;
}
-*/
public Iterator getProjectNames() {
if ( projectMap == null ) {
@@ -75,9 +78,13 @@
public void setName(String name) {
this.name = name;
}
+
+ public void setEmails(String[] emails) {
+ this.emails = emails;
+ }
- public void setEmail(String email) {
- this.email = email;
+ public void setNumbers(int[] numbers) {
+ this.numbers = numbers;
}
public void setAddress(AddressBean address) {
1.1
jakarta-commons-sandbox/betwixt/src/test/org/apache/commons/betwixt/SystemProperties.java
Index: SystemProperties.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*
* $Id: SystemProperties.java,v 1.1 2001/08/23 14:25:58 jstrachan Exp $
*/
package org.apache.commons.betwixt;
import org.apache.commons.betwixt.io.BeanWriter;
/** A sample program to output system properties as XML
*
* @author <a href="mailto:[EMAIL PROTECTED]">James Strachan</a>
* @version $Revision: 1.1 $
*/
public class SystemProperties {
public static void main(String[] args) throws Exception {
Object bean = System.getProperties();
BeanWriter writer = new BeanWriter();
writer.enablePrettyPrint();
writer.write( bean );
}
}