- robert
On 27 Apr 2004, at 05:11, George Papastamatopoulos wrote:
If I understand your problem correctly, you would like to include xml fragments, from within .betwixt files? I needed to do this the other day.
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]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
