Merged the content from staxReaderWriter into section 6 of ch-3 and removed the file. It was a temp working file. Worked on core graphics. commit is harmless but need more work on pom and process to document how and where graphics are supposed to be to get picked up in html and pdf generation. It's still confusing to me.

This commit is contained in:
wxlund
2008-03-10 17:45:51 +00:00
parent fe80f966c7
commit bba1458a28
3 changed files with 125 additions and 343 deletions

View File

@@ -56,13 +56,13 @@
<mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../resources/reference/images/simple-batch-execution-env.jpg"
fileref="../../resources/reference/images/simple-batch-execution-env.png"
format="JPG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/simple-batch-execution-env.jpg"
fileref="../../resources/reference/images/simple-batch-execution-env.png"
format="JPG" />
</imageobject>

View File

@@ -771,9 +771,12 @@ FOT;2;2;267.34</programlisting>
only to provide callbacks).</para>
</note>
<para>Lets take a closer look how XML input and output works in batch. It
is assumed the XML resource is a collection of 'fragments' corresponding
to individual records. Note that OXM tools are designed to work with
<para>Lets take a closer look how XML input and output works in batch.
First, there are a few concepts that vary from file reading and writing
but are common across Spring Batch XML processing. With XML processing
instead of lines of records (FieldSets) that need to be tokenized, it is
assumed an XML resource is a collection of 'fragments' corresponding to
individual records. Note that OXM tools are designed to work with
standalone XML documents rather than XML fragments cut out of an XML
document, therefore the Spring Batch infrastructure needs to work around
this fact (as described below).</para>
@@ -820,11 +823,18 @@ FOT;2;2;267.34</programlisting>
<caption><para>Figure X: OXM Binding</para></caption>
</mediaobject></para>
<para>The StaxEventItemReader configuration provides a typical setup for
the processing of records from an XML input stream. First, lets examine a
set of xml records that the StaxEventItemReader can process.</para>
<para>Now with and introduction into OXM and how one can use XML fragments
to represent records, let's take a closer look at Item Readers and Item
Writers.</para>
<para><programlisting>
<section>
<title>StaxEventItemReader</title>
<para>The StaxEventItemReader configuration provides a typical setup for
the processing of records from an XML input stream. First, lets examine
a set of xml records that the StaxEventItemReader can process.</para>
<para><programlisting>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;records&gt;
&lt;trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"&gt;
@@ -848,28 +858,28 @@ FOT;2;2;267.34</programlisting>
&lt;/records&gt;
</programlisting></para>
<para>To be able to process the XML records we need the following:
<itemizedlist>
<listitem>
<para>Root Element Name - this is name of the root element of the
fragment that constitutes the object to be mapped. The example
configuration demonstrates this with the value of trade.</para>
</listitem>
<para>To be able to process the XML records we need the following:
<itemizedlist>
<listitem>
<para>Root Element Name - this is name of the root element of the
fragment that constitutes the object to be mapped. The example
configuration demonstrates this with the value of trade.</para>
</listitem>
<listitem>
<para>Resource - This is a Spring Resource that in the case of this
example will abstract the details of opening a file for reading
content.</para>
</listitem>
<listitem>
<para>Resource - This is a Spring Resource that in the case of
this example will abstract the details of opening a file for
reading content.</para>
</listitem>
<listitem>
<para>Fragment Deserializer - this is the UnMarshalling facility
provided by Spring OXM for mapping the XML fragment to an
object.</para>
</listitem>
</itemizedlist></para>
<listitem>
<para>Fragment Deserializer - this is the UnMarshalling facility
provided by Spring OXM for mapping the XML fragment to an
object.</para>
</listitem>
</itemizedlist></para>
<para><programlisting>&lt;property name="itemReader"&gt;
<para><programlisting>&lt;property name="itemReader"&gt;
&lt;bean class="org.springframework.batch.io.xml.StaxEventItemReader"&gt;
&lt;property name="fragmentRootElementName" value="trade" /&gt;
&lt;property name="resource" value="data/staxJob/input/20070918.testStream.xmlFileStep.xml" /&gt;
@@ -886,15 +896,16 @@ FOT;2;2;267.34</programlisting>
&lt;/property&gt;
</programlisting></para>
<para>Notice that in this example we have chosen to use an
XStreamMarshaller that requires an alias passed in as a map with the first
key and value being the name of the fragment (i.e. root element) and the
object type to bind. Then, similar to a FieldSet, the names of the other
elements that map to fields within the object type are described as
key/value pairs in the map. In the configuration file we can use a spring
configuration utility to describe the required alias as follows:</para>
<para>Notice that in this example we have chosen to use an
XStreamMarshaller that requires an alias passed in as a map with the
first key and value being the name of the fragment (i.e. root element)
and the object type to bind. Then, similar to a FieldSet, the names of
the other elements that map to fields within the object type are
described as key/value pairs in the map. In the configuration file we
can use a spring configuration utility to describe the required alias as
follows:</para>
<para><programlisting>
<para><programlisting>
&lt;util:map id="aliases"&gt;
&lt;entry key="trade"
value="org.springframework.batch.sample.domain.Trade" /&gt;
@@ -905,18 +916,18 @@ FOT;2;2;267.34</programlisting>
&lt;/util:map&gt;
</programlisting></para>
<para>On input the reader reads the XML resource until it recognizes a new
fragment is about to start (by matching the tag name by default). The
reader creates a standalone XML document from the fragment (or at least
makes it appear so) and passes the document to a deserializer (typically a
wrapper around a Spring WS Unmarshaller) to map the XML to a Java
object.</para>
<para>On input the reader reads the XML resource until it recognizes a
new fragment is about to start (by matching the tag name by default).
The reader creates a standalone XML document from the fragment (or at
least makes it appear so) and passes the document to a deserializer
(typically a wrapper around a Spring WS Unmarshaller) to map the XML to
a Java object.</para>
<para>In summary, if you were to see this in scripted code like Java the
injection provided by the spring configuration would look something like
the following:</para>
<para>In summary, if you were to see this in scripted code like Java the
injection provided by the spring configuration would look something like
the following:</para>
<para><programlisting>
<para><programlisting>
StaxEventItemReader xmlStaxEventItemReader = new StaxEventItemReader()
Resource resource = new ByteArrayResource(xmlResource.getBytes())
@@ -945,29 +956,81 @@ FOT;2;2;267.34</programlisting>
}
</programlisting></para>
<para>Output works symetrically to input. Java object is passed to a
serializer (typically a wrapper around Spring WS Marshaller) which writes
to output using a custom event writer that filters the StartDocument and
EndDocument events produced for each fragment by the OXM tools.</para>
<para>For example configuration of XML input and output see the sample
xmlStaxJob. //TODO inline the example once it is not subject to change +
show sample input file</para>
<section>
<title>StaxEventItemReader</title>
<para></para>
</section>
<section>
<title>StaxEventItemWriter</title>
<para></para>
<para>Output works symetrically to input. The XMLItemWriter needs a
resource, a serializer, and a rootTagName. A java object is passed to a
serializer (typically a wrapper around Spring WS Marshaller) which
writes to output using a custom event writer that filters the
StartDocument and EndDocument events produced for each fragment by the
OXM tools. We'll show this in an example using the
MarshallingEventWriterSerializer. The Spring configuration for this
setup looks as follows:</para>
<programlisting>&lt;bean class="org.springframework.batch.item.xml.StaxEventItemWriter" id="tradeStaxWriter"&gt;
&lt;property name="resource"value="file:target/test-outputs/20070918.testStream.xmlFileStep.output.xml" /&gt;
&lt;property name="serializer" ref="tradeMarshallingSerializer" /&gt;
&lt;property name="rootTagName" value="trades" /&gt;
&lt;property name="overwriteOutput" value="true" /&gt;
&lt;/bean&gt;
</programlisting>
<para>The configuration sets up the three required properties and
optionally sets the overwriteOutput=true, mentioned earlier in the
chapter for specifying whether an existing file can be overwritten. The
TradeMarshallingSerializer is configured as follows:</para>
<programlisting><parameter>&lt;bean class="org.springframework.batch.item.xml.oxm.MarshallingEventWriterSerializer" id="tradeMarshallingSerializer"&gt;
&lt;constructor-arg&gt;
&lt;bean class="org.springframework.oxm.xstream.XStreamMarshaller"&gt;
&lt;property name="aliases" ref="aliases" /&gt;
&lt;/bean&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;</parameter></programlisting>
<para>To summarize with a Java example, the following code illustrates
all of the points discussed. The code demonstrates the programmatic
setup of the required properties. </para>
<programlisting>StaxEventItemWriter staxItemWriter = new StaxEventItemWriter()
FileSystemResource resource = new FileSystemResource(File.createTempFile("StaxEventWriterOutputSourceTests", "xml"))
Map aliases = new HashMap();
aliases.put("trade","org.springframework.batch.sample.domain.Trade");
aliases.put("isin","java.lang.String");
aliases.put("quantity","long");
aliases.put("price","java.math.BigDecimal");
aliases.put("customer","java.lang.String");
XStreamMarshaller marshaller = new XStreamMarshaller()
marshaller.setAliases(aliases)
MarshallingEventWriterSerializer tradeMarshallingSerializer = new MarshallingEventWriterSerializer(marshaller)
staxItemWriter.setResource(resource)
staxItemWriter.setSerializer(tradeMarshallingSerializer)
staxItemWriter.setRootTagName("trades")
staxItemWriter.setOverwriteOutput(true)
ExecutionContext executionContext = new ExecutionContext()
staxItemWriter.open(executionContext)
Trade trade = new Trade()
trade.isin = "XYZ0001"
trade.quantity =5
trade.price = 11.39
trade.customer = "Customer1"
println trade
staxItemWriter.write(trade)
staxItemWriter.flush()</programlisting>
<para>For a complete example configuration of XML input and output and a
corresponding Job see the sample xmlStaxJob.</para>
</section>
</section>
<section>
<title id="infrastructure.2.2">Database</title>
@@ -1276,4 +1339,4 @@ itemReader.close(executionContext);
to map FieldSets to objects. We will see how to take advantage of this
next.</para>
</section>
</chapter>
</chapter>

View File

@@ -1,281 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="spring-batch-infrastructure">
<title>Work-in-Progress StaxReaders and Writers</title>
<section>
<title id="infrastructure.2.3">XML Item Readers and Writers</title>
<para>Spring Batch provides transactional infrastructure for both reading
XML records and mapping them to Java objects as well as writing Java
objects as XML records.</para>
<note>
<title>Constraints on streaming XML</title>
<para>The StAX API is used for I/O as other standard XML parsing APIs do
not fit batch processing requirements (DOM loads the whole input into
memory at once and SAX controls the parsing process allowing the user
only to provide callbacks).</para>
</note>
<para>Lets take a closer look how XML input and output works in batch.
First, there are a few concepts that vary from file reading and writing
but are common across Spring Batch XML processing. With XML processing
instead of lines of records (FieldSets) that need to be tokenized, it is
assumed an XML resource is a collection of 'fragments' corresponding to
individual records. Note that OXM tools are designed to work with
standalone XML documents rather than XML fragments cut out of an XML
document, therefore the Spring Batch infrastructure needs to work around
this fact (as described below).</para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../../../target/site/reference/images/xmlinput.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/xmlinput.PNG"
format="PNG" />
</imageobject>
<caption><para>Figure X: XML Inputs</para></caption>
</mediaobject></para>
<para>Spring Batch uses Object/XML Mapping (OXM) to bind fragments to
objects. However, Spring Batch is not tied to any particular OXM
technology. Typical use is to delegate <ulink
url="http://static.springframework.org/spring-ws/site/reference/html/oxm.html"><citetitle>OXM
to Spring WS</citetitle></ulink>, which provides uniform abstraction for
the most popular OXM technologies. The dependency on Spring WS is optional
and you can choose to implement Spring Batch specific interfaces if
desired. The relationship to the technologies that OXM supports can be
shown as the following:</para>
<para><mediaobject>
<imageobject role="fo">
<imagedata align="center"
fileref="../../../../target/site/reference/images/oxm-fragments.png"
format="PNG" />
</imageobject>
<imageobject role="html">
<imagedata align="center"
fileref="../../resources/reference/images/oxm-fragments.png"
format="PNG" />
</imageobject>
<caption><para>Figure X: OXM Binding</para></caption>
</mediaobject></para>
<para>Now with and introduction into OXM and how one can use XML fragments
to represent records, let's take a closer look at Item Readers and Item
Writers.</para>
<section>
<title>StaxEventItemReader</title>
<para>The StaxEventItemReader configuration provides a typical setup for
the processing of records from an XML input stream. First, lets examine
a set of xml records that the StaxEventItemReader can process.</para>
<para><programlisting>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;records&gt;
&lt;trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"&gt;
&lt;isin&gt;XYZ0001&lt;/isin&gt;
&lt;quantity&gt;5&lt;/quantity&gt;
&lt;price&gt;11.39&lt;/price&gt;
&lt;customer&gt;Customer1&lt;/customer&gt;
&lt;/trade&gt;
&lt;trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"&gt;
&lt;isin&gt;XYZ0002&lt;/isin&gt;
&lt;quantity&gt;2&lt;/quantity&gt;
&lt;price&gt;72.99&lt;/price&gt;
&lt;customer&gt;Customer2c&lt;/customer&gt;
&lt;/trade&gt;
&lt;trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"&gt;
&lt;isin&gt;XYZ0003&lt;/isin&gt;
&lt;quantity&gt;9&lt;/quantity&gt;
&lt;price&gt;99.99&lt;/price&gt;
&lt;customer&gt;Customer3&lt;/customer&gt;
&lt;/trade&gt;
&lt;/records&gt;
</programlisting></para>
<para>To be able to process the XML records we need the following:
<itemizedlist>
<listitem>
<para>Root Element Name - this is name of the root element of the
fragment that constitutes the object to be mapped. The example
configuration demonstrates this with the value of trade.</para>
</listitem>
<listitem>
<para>Resource - This is a Spring Resource that in the case of
this example will abstract the details of opening a file for
reading content.</para>
</listitem>
<listitem>
<para>Fragment Deserializer - this is the UnMarshalling facility
provided by Spring OXM for mapping the XML fragment to an
object.</para>
</listitem>
</itemizedlist></para>
<para><programlisting>&lt;property name="itemReader"&gt;
&lt;bean class="org.springframework.batch.io.xml.StaxEventItemReader"&gt;
&lt;property name="fragmentRootElementName" value="trade" /&gt;
&lt;property name="resource" value="data/staxJob/input/20070918.testStream.xmlFileStep.xml" /&gt;
&lt;property name="fragmentDeserializer"&gt;
&lt;bean class="org.springframework.batch.io.xml.oxm.UnmarshallingEventReaderDeserializer"&gt;
&lt;constructor-arg&gt;
&lt;bean class="org.springframework.oxm.xstream.XStreamMarshaller"&gt;
&lt;property name="aliases" ref="aliases" /&gt;
&lt;/bean&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/property&gt;
</programlisting></para>
<para>Notice that in this example we have chosen to use an
XStreamMarshaller that requires an alias passed in as a map with the
first key and value being the name of the fragment (i.e. root element)
and the object type to bind. Then, similar to a FieldSet, the names of
the other elements that map to fields within the object type are
described as key/value pairs in the map. In the configuration file we
can use a spring configuration utility to describe the required alias as
follows:</para>
<para><programlisting>
&lt;util:map id="aliases"&gt;
&lt;entry key="trade"
value="org.springframework.batch.sample.domain.Trade" /&gt;
&lt;entry key="isin" value="java.lang.String" /&gt;
&lt;entry key="quantity" value="long" /&gt;
&lt;entry key="price" value="java.math.BigDecimal" /&gt;
&lt;entry key="customer" value="java.lang.String" /&gt;
&lt;/util:map&gt;
</programlisting></para>
<para>On input the reader reads the XML resource until it recognizes a
new fragment is about to start (by matching the tag name by default).
The reader creates a standalone XML document from the fragment (or at
least makes it appear so) and passes the document to a deserializer
(typically a wrapper around a Spring WS Unmarshaller) to map the XML to
a Java object.</para>
<para>In summary, if you were to see this in scripted code like Java the
injection provided by the spring configuration would look something like
the following:</para>
<para><programlisting>
StaxEventItemReader xmlStaxEventItemReader = new StaxEventItemReader()
Resource resource = new ByteArrayResource(xmlResource.getBytes())
Map aliases = new HashMap();
aliases.put("trade","org.springframework.batch.sample.domain.Trade");
aliases.put("isin","java.lang.String");
aliases.put("quantity","long");
aliases.put("price","java.math.BigDecimal");
aliases.put("customer","java.lang.String");
Marshaller marshaller = new XStreamMarshaller();
marshaller.setAliases(aliases);
xmlStaxEventItemReader.setFragmentDeserializer(new UnmarshallingEventReaderDeserializer(marshaller));
xmlStaxEventItemReader.setResource(resource);
xmlStaxEventItemReader.setFragmentRootElementName("trade");
xmlStaxEventItemReader.open(new ExecutionContext());
boolean hasNext = true
while (hasNext) {
trade = xmlStaxEventItemReader.read();
if (trade == null) {
hasNext = false;
} else {
println trade;
}
}
</programlisting></para>
</section>
<section>
<title>StaxEventItemWriter</title>
<para>Output works symetrically to input. The XMLItemWriter needs a
resource, a serializer, and a rootTagName. A java object is passed to a
serializer (typically a wrapper around Spring WS Marshaller) which
writes to output using a custom event writer that filters the
StartDocument and EndDocument events produced for each fragment by the
OXM tools. We'll show this in an example using the
MarshallingEventWriterSerializer. The Spring configuration for this
setup looks as follows:</para>
<programlisting>&lt;bean class="org.springframework.batch.item.xml.StaxEventItemWriter" id="tradeStaxWriter"&gt;
&lt;property name="resource"value="file:target/test-outputs/20070918.testStream.xmlFileStep.output.xml" /&gt;
&lt;property name="serializer" ref="tradeMarshallingSerializer" /&gt;
&lt;property name="rootTagName" value="trades" /&gt;
&lt;property name="overwriteOutput" value="true" /&gt;
&lt;/bean&gt;
</programlisting>
<para>The configuration sets up the three required properties and
optionally sets the overwriteOutput=true, mentioned earlier in the
chapter for specifying whether an existing file can be overwritten. The
TradeMarshallingSerializer is configured as follows:</para>
<programlisting><parameter>&lt;bean class="org.springframework.batch.item.xml.oxm.MarshallingEventWriterSerializer" id="tradeMarshallingSerializer"&gt;
&lt;constructor-arg&gt;
&lt;bean class="org.springframework.oxm.xstream.XStreamMarshaller"&gt;
&lt;property name="aliases" ref="aliases" /&gt;
&lt;/bean&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;</parameter></programlisting>
<para>To summarize with a Java example, the following code illustrates
all of the points discussed. The code demonstrates the programmatic
setup of the required properties. </para>
<programlisting>StaxEventItemWriter staxItemWriter = new StaxEventItemWriter()
FileSystemResource resource = new FileSystemResource(File.createTempFile("StaxEventWriterOutputSourceTests", "xml"))
Map aliases = new HashMap();
aliases.put("trade","org.springframework.batch.sample.domain.Trade");
aliases.put("isin","java.lang.String");
aliases.put("quantity","long");
aliases.put("price","java.math.BigDecimal");
aliases.put("customer","java.lang.String");
XStreamMarshaller marshaller = new XStreamMarshaller()
marshaller.setAliases(aliases)
MarshallingEventWriterSerializer tradeMarshallingSerializer = new MarshallingEventWriterSerializer(marshaller)
staxItemWriter.setResource(resource)
staxItemWriter.setSerializer(tradeMarshallingSerializer)
staxItemWriter.setRootTagName("trades")
staxItemWriter.setOverwriteOutput(true)
ExecutionContext executionContext = new ExecutionContext()
staxItemWriter.open(executionContext)
Trade trade = new Trade()
trade.isin = "XYZ0001"
trade.quantity =5
trade.price = 11.39
trade.customer = "Customer1"
println trade
staxItemWriter.write(trade)
staxItemWriter.flush()</programlisting>
<para>For a complete example configuration of XML input and output and a
corresponding Job see the sample xmlStaxJob.</para>
</section>
</section>
</chapter>