diff --git a/docs/src/site/docbook/reference/readersAndWriters.xml b/docs/src/site/docbook/reference/readersAndWriters.xml
index 51c695790..64f36a6d0 100644
--- a/docs/src/site/docbook/reference/readersAndWriters.xml
+++ b/docs/src/site/docbook/reference/readersAndWriters.xml
@@ -1729,6 +1729,193 @@ itemReader.close(executionContext);
+
+ Item Transforming
+
+ The ItemReader and
+ ItemWriter interfaces have been discussed in detail
+ in this chapter, but what if you want to insert business logic before
+ writing? One option for both reading and writing is to use the composite
+ pattern. That is, create an ItemWriter that
+ contains another ItemWriter, or an
+ ItemReader that contains another
+ ItemReader. For example:
+
+ public class CompositeItemWriter implements ItemWriter {
+
+ ItemWriter itemWriter;
+
+ public CompositeItemWriter(ItemWriter itemWriter) {
+ this.itemWriter = itemWriter;
+ }
+
+ public void write(Object item) throws Exception {
+
+ //Add business logic here
+
+ itemWriter.write(item);
+ }
+
+ public void clear() throws ClearFailedException {
+ itemWriter.clear();
+ }
+
+ public void flush() throws FlushFailedException {
+ itemWriter.flush();
+ }
+}
+
+ The class above contains another ItemWriter
+ that it delgates to after having provided some business logic. It should
+ be noted that the clear and
+ flush methods must be propogated as well so that
+ the delegate ItemWriter is notified. This pattern
+ could easily be used for an ItemReader as well,
+ perhaps to obtain more reference data based upon the input that was
+ provided by the main ItemReader. This pattern is
+ very useful if you need to control the call to
+ write yourself. However, if you only want to
+ 'transform' the item passed in for writing before it is actual written,
+ there isn't much need to call write yourself, you
+ just want to modify the item. For this scenario, Spring Batch provides the
+ ItemTransformer interface:
+
+ public interface ItemTransformer {
+
+ Object transform(Object item) throws Exception;
+ }
+
+ An ItemTransformer interface is very simple, given one object,
+ transorm it and return another. The object provided may or may not be of
+ the same type. The point is that business logic may be applied within
+ transform, and is completely up to the developer to create. An
+ ItemTransformer is used as part of the
+ ItemTransformerItemWriter, which accepts an
+ ItemWriter and an
+ ItemTransformer, passing the item first to the
+ transformer, before writing it. For example, assuming an
+ ItemReader provides a class of type Foo, and it
+ needs to be converted to type Bar before being written out. An
+ ItemTransformer can be written that perform the
+ conversion:
+
+ public class Foo {}
+
+ public class Bar {
+ public Bar(Foo foo) {}
+ }
+
+ public class FooTransformer implements ItemTransformer{
+
+ //Preform simple transformation, convert a Foo to a Barr
+ public Object transform(Object item) throws Exception {
+ assertTrue(item instanceof Foo);
+ Foo foo = (Foo)item;
+ return new Bar(foo);
+ }
+ }
+
+ public class BarWriter implements ItemWriter{
+
+ public void write(Object item) throws Exception {
+ assertTrue(item instanceof Bar);
+ }
+
+ //rest of class ommitted for clarity
+ }
+
+ In the very simple example above, there is a class
+ Foo, a class Bar, and a
+ class FooTransformer that adheres to the
+ ItemTransformer interface. The transformation is
+ simple, but any type of transformation could be done here. The
+ BarWriter will be used to write out 'Bars',
+ throwing an exception if any other type is provided. Similarly, the
+ FooTransformer will throw an exception if anything but a
+ Foo is provided. An
+ ItemTransformerItemWriter can then be used like a
+ normal ItemWriter. It will be passed a Foo for
+ writing, which will be passed to the transformer, and a
+ Bar returned. The resulting
+ Bar will then be written:
+
+ ItemTransformerItemWriter itemTransformerItemWriter = new ItemTransformerItemWriter();
+ itemTransformerItemWriter.setItemTransformer(new FooTransformer());
+ itemTransformerItemWriter.setDelegate(new BarWriter());
+ itemTransformerItemWriter.write(new Foo());
+
+
+ Chaining ItemTransformers
+
+ Performing a single transformation is useful in many scenarios,
+ but what if you want to 'chain' together multiple ItemTransformers? This
+ can be accomplished using a
+ CompositeItemTransformer. To update the previous,
+ single transformation, example, Foo will be
+ Transformed to Bar, which will be transformed to
+ Foobar and written out:
+
+ public class Foo {}
+
+ public class Bar {
+ public Bar(Foo foo) {}
+ }
+
+ public class Foobar{
+ public Foobar(Bar bar){}
+ }
+
+ public class FooTransformer implements ItemTransformer{
+
+ //Preform simple transformation, convert a Foo to a Barr
+ public Object transform(Object item) throws Exception {
+ assertTrue(item instanceof Foo);
+ Foo foo = (Foo)item;
+ return new Bar(foo);
+ }
+ }
+
+ public class BarTransformer implements ItemTransformer{
+
+ public Object transform(Object item) throws Exception {
+ assertTrue(item instanceof Bar);
+ return new Foobar((Bar)item);
+ }
+ }
+
+ public class FoobarWriter implements ItemWriter{
+
+ public void write(Object item) throws Exception {
+ assertTrue(item instanceof Foobar);
+ }
+
+ //rest of class ommitted for clarity
+ }
+
+ A FooTransformer and
+ BarTransformer can be 'chained' together to give
+ the resultant Foobar:
+
+ CompositeItemTransformer compositeTransformer = new CompositeItemTransformer();
+ List itemTransformers = new ArrayList();
+ itemTransformers.add(new FooTransformer());
+ itemTransformers.add(new BarTransformer());
+ compositeTransformer.setItemTransformers(itemTransformers);
+
+ The compositeTransformer could be said to accept a
+ Foo and return a Foobar.
+ Clients of the composite transformer don't need to know that there are
+ actually two separate transformations taking place. By updating the
+ example from above to use the composite transformer, the correct class
+ can be passed to FoobarWriter:
+
+ ItemTransformerItemWriter itemTransformerItemWriter = new ItemTransformerItemWriter();
+ itemTransformerItemWriter.setItemTransformer(compositeTransformer);
+ itemTransformerItemWriter.setDelegate(new FoobarWriter());
+ itemTransformerItemWriter.write(new Foo());
+
+
+