Hi,

I have the following problem when using Betwixt:

I am writing a small test Java program that uses Betwixt to write a bean to an 
xml file and then reads it back as a bean. The program listing is pasted below. 
The problem is the following: I have 2 simple beans called FooBean and BarBean. 
I have another bean called CompoundListBean that contains a private ArrayList 
field. Now this list can contain instances of FooBean and instances of BarBean, 
that is, it is a compound list and can take in multiple kinds of beans. In the 
Test class, I construct a couple of FooBean and BarBean instances each and add 
them to an instance of  CompoundListBean. The CompoundListBean instance is then 
written out to xml. The xml output is also pasted below. 

When the program tries to read the CompoundListBean back, it is unable to do so 
as shown by the program output that contains the output of the toString() call 
on CompoundListBean before and after the program run. 

So the Q is how can I modify this program to be able to write a 
CompoundListBean that can contain multiple kinds of beans in its ArrayList 
field to xml and then read it back successfully?



Java Program Listing:
-------------------------------

public class FooBean {
  private String name;
  public String getName () { return name; }
  public void setName (String value) { name = value; }

  public String toString ()
  {
    StringBuffer buffer = new StringBuffer();
    buffer.append("[Foo: name = ").append(name).append("\n");
    return buffer.toString();
  }
}

public class BarBean {
  private String name;
  public String getName () { return name; }
  public void setName (String value) { name = value; }

  public String toString ()
  {
    StringBuffer buffer = new StringBuffer();
    buffer.append("[Bar: name = ").append(name).append("\n");
    return buffer.toString();
  }
}


import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

public class CompoundListBean {
  private List list;

  public CompoundListBean () { list = new ArrayList(); }
  public List getCompoundList() { return list; }

  public void addFoo (FooBean value) { list.add(value); }
  public void addBar (BarBean value) { list.add(value); }

  public String toString ()
  {
    StringBuffer buffer = new StringBuffer();
    buffer.append("[CompoundList:").append("\n");
    for (Iterator it = list.iterator(); it.hasNext(); )
    {
      Object bean = (Object) it.next();
      buffer.append(bean);
    }
    buffer.append("\n");
    return buffer.toString();
  }
}


import java.io.File;
import java.io.FileWriter;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.betwixt.XMLIntrospector;

public class Test {

  private static XMLIntrospector createXMLIntrospector()
  {
    XMLIntrospector introspector = new XMLIntrospector();
    introspector.setAttributesForPrimitives(false);
    introspector.setWrapCollectionsInElement(false);
    return introspector;
  }

  public static void testCompoundEntity () throws Exception
  {
    FileWriter fWriter = new FileWriter("Compound.xml");
    BeanWriter bWriter = new BeanWriter(fWriter);
    bWriter.setXMLIntrospector(createXMLIntrospector());

    FooBean foo1 = new FooBean();
    foo1.setName("foo1");
    FooBean foo2 = new FooBean();
    foo2.setName("foo2");
    BarBean bar1 = new BarBean();
    bar1.setName("bar1");
    BarBean bar2 = new BarBean();
    bar2.setName("bar2");
    CompoundListBean entityListBean = new CompoundListBean();
    entityListBean.addFoo(foo1);
    entityListBean.addBar(bar1);
    entityListBean.addBar(bar2);
    entityListBean.addFoo(foo2);

    System.err.println(entityListBean);
    bWriter.enablePrettyPrint();
    bWriter.write(entityListBean);
    bWriter.flush();

    BeanReader reader = new BeanReader();
    reader.setXMLIntrospector(createXMLIntrospector());
    reader.registerBeanClass(CompoundListBean.class);
    CompoundListBean entityListReadFromFile = 
      (CompoundListBean)reader.parse(new File("Compound.xml"));
    System.err.println(entityListReadFromFile);
  }

  public static void main(String args[]) throws Exception 
  {
    testCompoundEntity();
  }
                                              
}


CompoundListBean.betwixt:
----------------------------------------
<?xml version="1.0" encoding="UTF-8" ?>
<info primitiveTypes="element">
  <element name="list-of-compound">
    <addDefaults/>
  </element>
</info>


XML output file Compund.xml written out by Test class:
-------------------------------------------------------------------------------
  <list-of-compound id="1">
    <FooBean id="2">
      <name>foo1</name>
    </FooBean>
    <BarBean id="3">
      <name>bar1</name>
    </BarBean>
    <BarBean id="4">
      <name>bar2</name>
    </BarBean>
    <FooBean id="5">
      <name>foo2</name>
    </FooBean>
  </list-of-compound>


Console output when running Test class thru ant:
----------------------------------------------------------------------
~/java/betwixt 535$ ant runTest
Buildfile: build.xml

runTest:
     [echo] betwixt-project: c:\kumar\java\betwixt\build.xml
     [java] [CompoundList:
     [java] [Foo: name = foo1
     [java] [Bar: name = bar1
     [java] [Bar: name = bar2
     [java] [Foo: name = foo2


     [java] Apr 10, 2007 3:19:04 PM 
org.apache.commons.betwixt.io.read.ChainedBeanCreatorFactory$2 create
     [java] WARNING: Could not create instance of type: java.util.List
     [java] Apr 10, 2007 3:19:04 PM 
org.apache.commons.betwixt.io.read.ChainedBeanCreatorFactory$2 create
     [java] WARNING: Could not create instance of type: java.util.List
     [java] Apr 10, 2007 3:19:04 PM 
org.apache.commons.betwixt.io.read.ChainedBeanCreatorFactory$2 create
     [java] WARNING: Could not create instance of type: java.util.List
     [java] Apr 10, 2007 3:19:04 PM 
org.apache.commons.betwixt.io.read.ChainedBeanCreatorFactory$2 create
     [java] WARNING: Could not create instance of type: java.util.List
     [java] Apr 10, 2007 3:19:04 PM 
org.apache.commons.betwixt.expression.Context popOptions
     [java] INFO: Cannot pop options off empty stack
     [java] Apr 10, 2007 3:19:04 PM 
org.apache.commons.betwixt.expression.Context popOptions
     [java] INFO: Cannot pop options off empty stack
     [java] [CompoundList:



BUILD SUCCESSFUL



Analysis:
--------------
The program output shows that while the CompoundListBean could be written out 
correctly before the XML write to file, it was not read correctly from the file 
Compound.xml. And the basic problem is that the ArrayList in CompoundListBean 
can take in multiple types of beans. When I do a similar program that takes in 
only FooBeans, for example, and correspondingly modify the CompoundListBean 
class to just have an addFoo(FooBean) method, the XML write and read from file 
work correctly.

The problem is is also reflected in the Compound.xml file that is written out. 
As pasted above, the xml file has tags called "<FooBean>", "<BarBean>". When I 
do the program with FooBeans only as described in above paragraph, the tags 
change to "<foo>", which lets the XML read back then work correctly.

Any ideas/suggestions on how to make a list of multiple types of beans work out 
will be appreciated.

thanks


 
---------------------------------
We won't tell. Get more on shows you hate to love
(and love to hate): Yahoo! TV's Guilty Pleasures list.

Reply via email to