Try the following in your .betwixt file...
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE info [ <!ENTITY some_common_fragment SYSTEM "common-fragment.xml"> ]> <info> <element name="MyBean"> &some_common_fragment;
<!-- anything else you require here --> <addDefaults/> </element> </info>
george.
b p wrote:
Hi Robert,
One way I started using betwixt is to allow our testing organization to
easily create XML test data (they can modify the XML values to create a
large test bed without writting a lot of java code). One thing they
asked for was a way to include XML files for some pieces of data. I
originally fought with finding a way to create a custom digester rule to
do that, but then realized it could be done relatively easily with a
custom BeanCreator.
Below is a "IncludeBeanCreator" along with a test case for it. If you think it would be useful for others, you can include it in Betwixt (I still haven't dealt with looping includes, but I think I could add that relatively quickly when I get some additional time to look at it).
-Brian
IncludeBeanCreator.java ------------------------------------ package org.apache.commons.betwixt.io.read; import org.apache.commons.betwixt.io.BeanReader; import org.apache.commons.betwixt.BindingConfiguration; import org.xml.sax.SAXException; import org.xml.sax.Attributes; import java.net.URL; import java.io.IOException; import java.beans.IntrospectionException; import java.util.List; /** * BeanCreator that allows for "include" files. The current element's "include-file" property * indicates the name of the XML file that should be processed. For example, the following XML indicates * that the "venue" property should be created by parsing the file "org/apache/commons/betwixt/io/read/venue.xml": * <p/> * <p/> * <PRE> * <?xml version="1.0"?> * <PartyBean> * <dateOfParty>Wed Apr 14 19:46:55 MDT 2004</dateOfParty> * <excuse>tired</excuse> * <fromHour>2</fromHour> * <venue include-file="org/apache/commons/betwixt/io/read/venue.xml"/> * </PartyBean> * </PRE> * <p/> * The venue.xml file would be a standard XML input for betwixt: * <p/> * <PRE> * <?xml version="1.0"?> * <venue> * <city>San Francisco</city> * <code>94404</code> * <country>USA</country> * <street>123 Here</street> * </venue> * </PRE> * <p/> * <p/> * The include file is loaded as a resource using the current <code>ClassLoader</code> following the rules * as described by the <code>ClassLoader.getResource</code> method. * <p/> * The include file is parsed using a <code>BeanReader</code> with the <code>BindingConfiguration</code> * and <code>ReadConfiguration</code> which can be explicitly set, or if it is not set, * a default will be used. * <p/> * The current class (obtained from the <code>ElementMapping</code>) will be registered with the <code>BeanReader</code> * using the "name" of the current <code>ElementMapping</code>. * * @author Brian Pugh */ public class IncludeBeanCreator implements ChainedBeanCreator { private BindingConfiguration bindingConfiguration; private ReadConfiguration readConfiguration; private List parsedFiles;
/** * Constructs a new IncludeBeanCreator. */ public IncludeBeanCreator() { } /** * Constructs a new IncludeBeanCreator. * * @param bindingConfiguration the <code>BindingConfiguration</code> that will be used to parse include files. */ public IncludeBeanCreator(BindingConfiguration bindingConfiguration, ReadConfiguration readConfiguration) { setBindingConfiguration(bindingConfiguration); setReadConfiguration(readConfiguration); }
/**
* Get the <code>BindingConfiguration</code> that will be used to
parse include files.
*
* @return the <code>BindingConfiguration</code> that will be used to
parse include files.
*/
public BindingConfiguration getBindingConfiguration() {
return bindingConfiguration;
}
/**
* Set the <code>BindingConfiguration</code> that will be used to
parse include files.
*
* @param bindingConfiguration the <code>BindingConfiguration</code>
that will be used to parse include files.
*/
public void setBindingConfiguration(BindingConfiguration
bindingConfiguration) {
this.bindingConfiguration = bindingConfiguration;
}
/**
* Get the <code>ReadConfiguration</code> that will be used to parse
include files.
* @return the <code>ReadConfiguration</code> that will be used to
parse include files.
*/
public ReadConfiguration getReadConfiguration() {
return readConfiguration;
}
/**
* Set the <code>ReadConfiguration</code> that will be used to parse
include files.
* @param readConfiguration the <code>ReadConfiguration</code> that
will be used to parse include files.
*/
public void setReadConfiguration(ReadConfiguration readConfiguration)
{
this.readConfiguration = readConfiguration;
}
/**
* If the "include-file" attribute is found, the bean is created by
parsing the include xml file.
* Otherwise bean creation is delegated to the other members of the
chain.
*
* @param elementMapping specifies the mapping between the type and
element.
* @param context the context in which this converision
happens, not null
* @param chain not null
* @return the Object created, possibly null
*/
public Object create(ElementMapping elementMapping, ReadContext
context, BeanCreationChain chain) {
Attributes attributes = elementMapping.getAttributes();
String file = attributes.getValue("include-file");
if (file != null && !file.equals("")) {
BeanReader beanReader = new BeanReader();
if (bindingConfiguration != null) {
beanReader.setBindingConfiguration(bindingConfiguration);
}
if (readConfiguration != null) {
beanReader.setReadConfiguration(readConfiguration);
}
String name = elementMapping.getName();
Class clazz = elementMapping.getType();
ClassLoader loader = getClass().getClassLoader();
URL url = loader.getResource(file);
if (url == null) {
url = loader.getResource("/" + file);
}
if (url == null) {
throw new RuntimeException("Unable to locate include file: " +
file);
}
try {
beanReader.registerBeanClass(name, clazz);
return beanReader.parse(url.toString()); }
catch (IntrospectionException e) {
throw new RuntimeException("Unable to register class with
beanReader. Classname: " + clazz, e);
}
catch (IOException e) {
throw new RuntimeException("Unable to process include file: " +
file, e);
}
catch (SAXException e) {
throw new RuntimeException("Unable to process include file: " +
file, e);
}
}
return chain.create(elementMapping, context);
}
}
TestInclude.java ---------------------------------------------------------------------- package org.apache.commons.betwixt.io.read; import junit.framework.TestCase; import org.apache.commons.betwixt.PartyBean; import org.apache.commons.betwixt.io.BeanReader; import java.net.URL; import java.util.Date; /** * Test the IncludeBeanCreator. * * @author Brian Pugh */ public class TestInclude extends TestCase {
/** * Test IncludeBeanCreator. * * @throws Exception if test fails. */ public void testInclude() throws Exception { URL url = getClass().getClassLoader().getResource("org/apache/commons/betwixt/io/r ead/party.xml"); assertNotNull("couldn't load party xml file!", url); BeanReader beanReader = new BeanReader(); beanReader.registerBeanClass(PartyBean.class); BeanCreationList chain = BeanCreationList.createStandardChain(); //put in second place (let the idref creator run first) chain.insertBeanCreator(2, new IncludeBeanCreator(beanReader.getBindingConfiguration(),
beanReader.getReadConfiguration())); beanReader.getReadConfiguration().setBeanCreationChain(chain); PartyBean result = (PartyBean)beanReader.parse(url.toString()); assertNotNull("Couldn't read a PartyBean!", result); assertEquals("didn't get a Date right!", new Date("Wed Apr 14 19:46:55 MDT 2004"), result.getDateOfParty()); assertEquals("didn't get excuse right!", "tired", result.getExcuse()); assertEquals("didn't get fromhour right!", 2, result.getFromHour()); assertNotNull("didn't get venue back!", result.getVenue()); assertEquals("didn't get venue city right!", "San Francisco", result.getVenue().getCity()); assertEquals("didn't get venue code right!", "94404", result.getVenue().getCode()); assertEquals("didn't get venue country right!", "USA", result.getVenue().getCountry()); assertEquals("didn't get venue street right!", "123 Here", result.getVenue().getStreet()); } }
XML files (n the org.apache.commons.betwixt.io.read package) party.xml ---------------------------------------------------------------- <?xml version="1.0"?> <PartyBean> <dateOfParty>Wed Apr 14 19:46:55 MDT 2004</dateOfParty> <excuse>tired</excuse> <fromHour>2</fromHour> <venue include-file="org/apache/commons/betwixt/io/read/venue.xml"/> </PartyBean>
venue.xml -------------------------------------------------------------- <?xml version="1.0"?> <venue> <city>San Francisco</city> <code>94404</code> <country>USA</country> <street>123 Here</street> </venue>
--------------------------------- Do you Yahoo!? Yahoo! Tax Center - File online by April 15th
-- ___________________________ George Papastamatopoulos
Lawlex Compliance Solutions +61 3 9278 1182 ___________________________
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
