<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at
  
  http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
-->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="pipelines">
  <title>Pipelines</title>

  <section id="pipelines.definition">
    <title>What is a pipeline?</title>
    <para>
      A Cocoon 3 pipeline expects one or more component(s). These components get linked with each other in the
      order they were added. There is no restriction on the content that flows through the pipeline.
    </para>
    <para>
      A pipeline works based on two fundamental concepts:
      <itemizedlist>
        <listitem>
          <para>The first component of a pipeline is of type 
            <literal>org.apache.cocoon.pipeline.component.Starter</literal>.
            The last component is of type <literal>org.apache.cocoon.pipeline.component.Finisher</literal>.
          </para>
        </listitem>
        <listitem>
          <para>
            In order to link components with each other, the first has to be a 
            <literal>org.apache.cocoon.pipeline.component.Producer</literal>, the latter
            <literal>org.apache.cocoon.pipeline.component.Consumer</literal>.
          </para>
        </listitem>
      </itemizedlist>
      When the pipeline links the components, it merely checks whether the above mentioned interfaces are present. So the
      pipeline does not know about the specific capabilities or the compatibility of the components. It is the
      responsibility of the <literal>Producer</literal> to decide whether a specific <literal>Consumer</literal> 
      can be linked to it or not (that is, whether it can produce output in the desired format of the <literal>Consumer</literal> 
      or not). It is also conceivable that a <literal>Producer</literal> is capable of accepting different types of 
      <literal>Consumer</literal> and adjust the output format
    </para>
    <section>
      <title>Linear pipelines</title>
      <para>
        A Cocoon 3 pipeline always goes through the same sequence of components to produce its output. There is no
        support for conditionals, loops, tees or alternative flows in the case of errors. The reason for this restriction
        is simplicity and that non-linear pipelines are more difficult (or even impossible) to be cached. In practice this means
        that a pipeline has to be contructed completely at build-time.
      </para>
      <para>
        If non-linear XML pipes with runtime-support for conditionals, loops, tees and error-flows are a requirement for you, 
        see the <ulink url="http://en.wikipedia.org/wiki/XProc">XProc</ulink> standard of the W3C. There
        are several available implementations for it.
      </para>
    </section>
    <section>
      <title>Pipelines by example</title>
      <para>
        But let's get more specific by giving an example: Cocoon has become famous for its SAX pipelines that consist 
        of exactly one SAX-based XML generator, zero, one or more SAX-based XML transformers and exactly one SAX-based 
        XML serializer. Of course, these specific SAX-based XML pipelines can be build by using general
        Cocoon 3 pipelines: generators, transformers and serializers are pipeline components. A generator is a 
        <literal>Starter</literal> and a <literal>Producer</literal>, a transformer can't be neither a 
        <literal>Starter</literal>, nor a <literal>Finisher</literal> but is always a <literal>Producer</literal> 
        and a <literal>Consumer</literal> and a serializer is a <literal>Consumer</literal> and a <literal>Finisher</literal>.
      </para>
      <para>
        Here is some Java code that demonstrates how a pipeline can be utilized with SAX-based XML components:      
      </para>
      <programlistingco>
        <areaspec>
          <area id="pipelines.definition.pipeline" coords="1"/>
          <area id="pipelines.definition.generator" coords="2"/>
          <area id="pipelines.definition.transformer1" coords="3"/>
          <area id="pipelines.definition.transformer2" coords="4"/>
          <area id="pipelines.definition.serializer" coords="5"/>
          <area id="pipelines.definition.setup" coords="7"/>
          <area id="pipelines.definition.execute" coords="8"/>
        </areaspec>      
      <programlisting language="java"><![CDATA[Pipeline<SAXPipelineComponent> pipeline = new NonCachingPipeline<SAXPipelineComponent>();
pipeline.addComponent(new XMLGenerator("<x></x>"));
pipeline.addComponent(new XSLTTransformer(this.getClass().getResource("/test1.xslt")));
pipeline.addComponent(new XSLTTransformer(this.getClass().getResource("/test2.xslt")));
pipeline.addComponent(new XMLSerializer());

pipeline.setup(System.out);
pipeline.execute();]]>
</programlisting>
       <calloutlist>
         <callout arearefs="pipelines.definition.pipeline">
            <para>
              Create a <literal>NonCachingPipeline</literal>. It's the simplest available pipeline implementation. The 
              <literal>org.apache.cocoon.pipeline.Pipeline</literal> interface doesn't impose any restrictions on the
              content that flows in it.
            </para>
         </callout>
         <callout arearefs="pipelines.definition.generator">
            <para>
              Add a generator, that implements the <literal>org.apache.cocoon.pipeline.component.PipelineComponent</literal> interface to the
              pipeline by using the pipeline's <literal>addComponent(pipelineComponent)</literal> interface.
            </para>
            <para>
              The <literal>XMLGenerator</literal> expects a <literal>java.lang.String</literal> object and produces SAX events by using a SAX parser.
              Hence it has to implement the <literal>org.apache.cocoon.sax.component.SAXProducer</literal> interface.
            </para>
            <para>
              The <literal>SAXProducer</literal> interface extends the <literal>org.apache.cocoon.pipeline.component.Producer</literal> interface. This
              means that it expects the next (or the same!) component to implement the <literal>org.apache.cocoon.pipeline.component.Consumer</literal>
              interface. The check that the next pipeline component is of type <literal>org.apache.cocoon.sax.component.SAXConsumer</literal>
              isn't done at interface level but by the implementation (see the <literal>org.apache.cocoon.sax.component.AbstractXMLProducer</literal>
              for details which the <literal>XMLGenerator</literal> is inherited from).
            </para>
            <para>
              Since a generator is the first component of a pipeline, it also has to implement the <literal>Starter</literal> interface.
            </para>
         </callout>
         <callout arearefs="pipelines.definition.transformer1">
            <para>
              Add a transformer, that implements the <literal>org.apache.cocoon.pipeline.component.PipelineComponent</literal> interface, to the
              pipeline by using the pipeline's <literal>addComponent(pipelineComponent)</literal> method.
            </para>
            <para>
              This <literal>XSLTTransformer</literal> expects the <literal>java.net.URL</literal> of an XSLT stylesheet. It uses the rules of the stylesheet
              to add, change or delete nodes of the XML SAX stream.
            </para>
            <para>
              Since it implements the <literal>org.apache.cocoon.pipeline.component.Consumer</literal> interface, it fulfills the general contract that a <literal>Consumer</literal>
              is linked with a <literal>Producer</literal>. By implementing the <literal>org.apache.cocoon.sax.component.SAXConsumer</literal> interface,
              it fulfills the specific requirement of the previous <literal>XMLGenerator</literal> that expects a next pipeline component of that type. 
            </para>
            <para>
              This transformer also implements the <literal>org.apache.cocoon.sax.component.SAXProducer</literal> interface. This interface extends the
              <literal>org.apache.cocoon.pipeline.component.Producer</literal> interface which means that the next component has to be a 
              <literal>org.apache.cocoon.pipeline.component.Consumer</literal>. Like the previous <literal>XMLGenerator</literal>, the <literal>XSLTTransformer</literal>
              inherits from the <literal>org.apache.cocoon.sax.component.AbstractXMLProducer</literal> which contains the check that the next component
              is of type <literal>org.apache.cocoon.sax.component.SAXConsumer</literal>. 
            </para>
         </callout>
         <callout arearefs="pipelines.definition.transformer2">
            <para>
              Add another transformer to the pipeline. A pipeline can contain any number of components that implement the <literal>Producer</literal> and 
              <literal>Consumer</literal> interfaces at the same time. However, they mustn't be neither of type <literal>Starter</literal> nor <literal>Finisher</literal>.
            </para>
         </callout>
         <callout arearefs="pipelines.definition.serializer">
            <para>
              Add a serializer, that implements the <literal>org.apache.cocoon.pipeline.component.PipelineComponent</literal> interface to the
              pipeline by using the pipeline's <literal>addComponent(pipelineComponent)</literal> interface.
            </para>
            <para>
              The XML serializer receives SAX events and serializes them into an <literal>java.io.OutputStream</literal>.
            </para>
            <para>
              A serializer component is the last component of a pipeline and hence it has to implement the <literal>org.apache.cocoon.pipeline.Finisher</literal>
              interface.
            </para>
            <para>
              Since it receives SAX events, it implements the <literal>org.apache.cocoon.pipeline.sax.SAXConsumer</literal> interface.
            </para>
         </callout>
         <callout arearefs="pipelines.definition.setup">
            <para>
              A pipeline has to be initialized first by calling its <literal>setup(outputStream)</literal> method. This method expects the output stream
              where the pipeline result should be streamed.
            </para>
         </callout>
         <callout arearefs="pipelines.definition.execute">
            <para>
              After the pipeline has been initialized, it can be executed by invoking its <literal>execute()</literal> method. The first pipeline component, a <literal>Starter</literal>,
              will be invoked which will trigger the next component and so on. Finally the last pipeline component, a <literal>Finisher</literal> will be reached which is responsible 
              for the serialization of the pipeline content.
            </para>
            <para>
              Once the pipeline has been started, it either succeeds or fails. There is no way to react on any (error) conditions.
            </para>
         </callout>
       </calloutlist>
      </programlistingco>
      <table id="pipeline.components.sax" pgwide="1">
        <title>SAX components and their interfaces</title>
        <tgroup cols="5">
          <colspec colname="c1" />
          <colspec colname="c2" align="center" />
          <colspec colname="c3" align="center" />
          <thead>
            <row>
              <entry>Component type</entry>
              <entry>Structural interfaces</entry>
              <entry>Content-specific interfaces</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>SAX generator</entry>
              <entry>Starter, Producer, PipelineComponent</entry>
              <entry>SAXProducer</entry>
            </row>
            <row>
              <entry>SAX transformer</entry>
              <entry>Producer, Consumer, PipelineComponent</entry>
              <entry>SAXProducer, SAXConsumer</entry>
            </row>
            <row>
              <entry>SAX serializer</entry>
              <entry>Finisher, Consumer, PipelineComponent</entry>
              <entry>SAXConsumer</entry>
            </row>
          </tbody>
        </tgroup>
      </table>      
    </section>
  </section>

  <section id="pipelines.implementations">
    <title>Pipeline implementations</title>
    <para>TBW: noncaching, caching, async-caching, expires caching, own implementations</para>
  </section>

  <section id="pipelines.embedding">
    <title>Embedding a pipeline</title>
    <para>TBW: Passing parameters to the pipeline and its components, finsih() method</para>
  </section>

  <section id="pipeline.sax">
    <title>SAX components</title>
    <para>concept, writing custom SAX components, link to Javadocs</para>

    <section>
      <title>Available components</title>
      <para>Link to Javadocs</para>
    </section>
    
    <section>
      <title>Writing custom components</title>
      <section>
        <title>SAX generator</title>
        <para>explain from a user's point of view, what she needs to do to implement one
              (available abstract classes)
        </para>
      </section>
      <section>
        <title>SAX transformer</title>
        <para>explain from a user's point of view, what she needs to do to implement one</para>
        <para>buffering</para>
      </section>
      <section>
        <title>SAX serializer</title>
        <para>explain from a user's point of view, what she needs to do to implement one</para>
      </section>
    </section>
  </section>
  
  <section id="pipeline.stax">
    <title>StAX components</title>
    <para>StAX pipelines provide an alternative API for writing pipeline components. Altough they are not as fast as SAX, they provide easier state handling as the component can control when to pull the next events. This allows an implicit state rather than have to manage the state in the various content handler methods of SAX.</para>
    <para>The most visible difference of StAX components in contrast to SAX is that the component itself has controls the parsing of the input whereas in SAX the parser controls the pipeline by calling the component.
    Our implementation of StAX pipelines uses just StAX interfaces for retrieving events - the writing interface is proprietary in order to avoid multihreading or continuations.
    So it is really a hybrid process - the StAX component is called to generate the next events, but it is also allowed to read as much data from the previous pipeline component as it wants. But as the produced events are kept in-memory until a later component pulls for them, the components should not emit large amounts of events during one invocation.
    </para>

    <section>
      <title>Available components</title>
      <para><itemizedlist>
        <listitem><para><literal>StAXGenerator</literal> is a Starter and normally parses a XML from an InputStream.</para></listitem>
        <listitem><para><literal>StAXSerializer</literal> is a Finisher and writes the StAX Events to an OutputStream.</para></listitem>
        <listitem><para><literal>AbstractStAXTransformer</literal> is the abstract base class for new transformers. It simplifies the task by providing a template method for generating the new events.</para></listitem>
        <listitem><para><literal>StAXCleaningTransformer</literal> is an transformer, which cleans the document from whitespaces and comments.</para></listitem>
        <listitem><para><literal>IncludeTransformer</literal> includes the contents of another document.</para></listitem>
      </itemizedlist></para>
      <para>For further information refer to the <ulink url="http://cocoon.apache.org/3.0/apidocs/org/apache/cocoon/stax/package-summary.html">javadoc</ulink></para>
    </section>
    
    <section>
      <title>Writing custom components</title>
      <section>
        <title>StAX generator</title>
	<para>The <literal>StAXGenerator</literal> is a <literal>Starter</literal> component and produces XMLEvents.
	<programlistingco>
        <areaspec>
          <area id="stax.generator.example.classdecl" coords="12"/>
          <area id="stax.generator.example.ctor" coords="18"/>
          <area id="stax.generator.example.execute" coords="27"/>
          <area id="stax.generator.example.hasNext" coords="31"/>
          <area id="stax.generator.example.nextEvent" coords="35"/>
          <area id="stax.generator.example.peek" coords="39"/>
        </areaspec>    
	<programlisting language="java"><![CDATA[import java.io.InputStream;
import java.net.URL;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

import org.apache.cocoon.pipeline.SetupException;
import org.apache.cocoon.pipeline.component.Starter;
public class MyStAXGenerator extends AbstractStAXProducer implements Starter {

   private XMLEventReader reader;
    
   public MyStAXGenerator(InputStream inputStream) {
      try {
         this.reader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
      } catch (XMLStreamException e) {
         throw new SetupException("Error during setup an XMLEventReader on the inputStream", e);
      } catch (FactoryConfigurationError e) {
         throw new SetupException("Error during setup the XMLInputFactory for creating an XMLEventReader", e);
      }
   }
    
   public void execute() {
      this.getConsumer().initiatePullProcessing();
   }

   public boolean hasNext() {
      return this.reader.hasNext();
   }

   public XMLEvent nextEvent() throws XMLStreamException {
      return this.reader.nextEvent();
   }
    
   public XMLEvent peek() throws XMLStreamException {
      return this.reader.peek();
   }
	
}]]>	</programlisting>
	<calloutlist>
         <callout arearefs="stax.generator.example.classdecl">
            <para>
	      In order to implement an own <literal>StAXGenerator</literal> the easiest approach is to inherit from <literal>AbstractStAXProducer</literal>.
            </para>
         </callout>
	<callout arearefs="stax.generator.example.ctor">
            <para>
	      The constructor creates a new XMLEventReader for reading from the inputstream.
            </para>
         </callout>
	<callout arearefs="stax.generator.example.execute">
            <para>
	      The pipeline is started using the <literal>execute</literal> method. As StAX is a pull based approach the last component has to start pulling.
            </para>
         </callout>
	 <callout arearefs="stax.generator.example.hasNext">
            <para>This method should return true if the generator has a next Event. </para>
         </callout>
 	 <callout arearefs="stax.generator.example.nextEvent">
            <para>Returns the next event from the generator.</para>
         </callout>
 	 <callout arearefs="stax.generator.example.peek">
            <para>Returns the next event from the generator, without moving actually to the next event.</para>
         </callout>
       </calloutlist>
      </programlistingco>
	</para>
      </section>
      <section>
        <title>StAX transformer</title>
        <para>Implementing a StAX Transformer should be the most common use case. The <literal>AbstractStAXTransformer</literal> provides a foundation for new transformers. But in order to write new transformers even simpler, let's describe another feature first:</para>
	
	<section>
	<title>Navigator</title>
        <para>Navigators allow an easier navigation in the XML document. They also simplify transformers, as usually transformers need only process some parts of the input document and the navigator helps to identify the interesting parts. There are several implementations already included:
	<itemizedlist>
	  <listitem><para><literal>FindStartElementNavigator</literal> finds the start tag with certain properties(name,attribute)</para></listitem>
	  <listitem><para><literal>FindEndElementNavigator</literal> finds the end tag with certain properties(name,attribute)</para></listitem>
	  <listitem><para><literal>FindCorrespondingStartEndElementPairNavigator</literal> finds both the start and the corresponding end tag.</para></listitem>
	  <listitem><para><literal>InSubtreeNavigator</literal> finds whole subtrees, by specifying the properties of the "root" element.</para></listitem>
	</itemizedlist>
	For further information refer to the <ulink url="http://cocoon.apache.org/3.0/apidocs/org/apache/cocoon/stax/navigation/package-summary.html">navigator javadoc</ulink>
	</para>
	<section>
	  <title>Using navigators</title>
	  <para>
	  Using a navigator is a rather simple task. The transformer peeks or gets the next event and calls <literal>Navigator.fulfillsCriteria</literal> - if true is returned the transformer should be process that event somehow. 
	  </para>
	</section>
	<section>
	  <title>Implementing a navigator</title>
	  <para>Creating a new navigator is a rather simple task and just means implementing two methods:</para>
	  <programlistingco>
	  <areaspec>
	    <area id="stax.navigator.example.fulfillsCriteria" coords="4"/>
	    <area id="stax.navigator.example.isActive" coords="8"/>
	  </areaspec>    
	  <programlisting language="java"><![CDATA[import javax.xml.stream.events.XMLEvent;

public class MyNavigator implements Navigator {
   public boolean fulfillsCriteria(XMLEvent event) {
      return false;
   }
    
   public boolean isActive() {
      return false;
   }
}
]]>	</programlisting>
	<calloutlist>
         <callout arearefs="stax.navigator.example.fulfillsCriteria">
            <para>
	      This method returns true if the event matches the criteria of the navigator.
            </para>
         </callout>
	<callout arearefs="stax.navigator.example.isActive">
            <para>
	      Returns the result of the last invocation of fulfillsCriteria.
	    </para>
         </callout>
       </calloutlist>
      </programlistingco>
	</section>
	</section>

	<section>
	  <title>Implementing a transformer</title>
	  <para>The next example should show you an transformer featuring navigators and implicit state handling through function calls.</para>
	  <programlistingco>
	      <areaspec>
		<area id="stax.transformer.example.navigatorFulfillsCriteria" coords="6"/>
		<area id="stax.transformer.example.collectLinkInfoInvocation" coords="8"/>
		<area id="stax.transformer.example.rewriteAndEmit" coords="10"/>
		<area id="stax.transformer.example.flushAdditionalEvents" coords="13"/>
		<area id="stax.transformer.example.collectLinkInfoInvocationNavigator" coords="26"/>
		<area id="stax.transformer.example.collectLinkInfoInvocationPeek" coords="31"/>
	      </areaspec>    
	      <programlisting language="java"><![CDATA[public class DaisyLinkRewriteTransformer extends AbstractStAXTransformer {
  @Override
   protected void produceEvents() throws XMLStreamException {
      while (this.getParent().hasNext()) {
         XMLEvent event = this.getParent().nextEvent();
         if (this.anchorNavigator.fulfillsCriteria(event)) {
            ArrayList<XMLEvent> innerContent = new ArrayList<XMLEvent>();
            LinkInfo linkInfo = this.collectLinkInfo(innerContent);
            if(linkInfo != null) {
               linkInfo.setNavigationPath(this.getAttributeValue(event.asStartElement(), 
                  PUBLISHER_NS,"navigationPath"));

               this.rewriteAttributesAndEmitEvent(event.asStartElement(),linkInfo);

               if(innerContent.size() != 0) {
                  this.addAllEventsToQueue(innerContent);
               }
            } 
            /* ... */
         } 
         /* ... */
      }
   }

   private LinkInfo collectLinkInfo(List<XMLEvent> events) throws XMLStreamException {
      Navigator linkInfoNavigator = new InSubtreeNavigator(LINK_INFO_EL);
      Navigator linkInfoPartNavigator = new FindStartElementNavigator(LINK_PART_INFO_EL);
      LinkInfo linkInfo = null;

      while (this.getParent().hasNext()) {
         XMLEvent event = this.getParent().peek();

         if (linkInfoNavigator.fulfillsCriteria(event)) {
            event = this.getParent().nextEvent();
            if (linkInfoPartNavigator.fulfillsCriteria(event)) {
               /* ... */
               String fileName = this.getAttributeValue(event.asStartElement(),"fileName");
               if (!"".equals(fileName)) {
                  linkInfo.setFileName(fileName);
               }
            } /* ... */
         } else if (event.isCharacters()) {
            events.add(this.getParent().nextEvent());
         } else {
            return linkInfo;
         }
      }
      return linkInfo;
   }

   private void rewriteAttributesAndEmitEvent(StartElement event, LinkInfo linkInfo) ;

}]]></programlisting>
	    <calloutlist>
	    <callout arearefs="stax.transformer.example.navigatorFulfillsCriteria">
		<para>The transformer checks for anchors in the XML.</para>
	    </callout>
	    <callout arearefs="stax.transformer.example.collectLinkInfoInvocation">
		<para>If an anchor is found, it invokes a method which parses the link info if there is any. The additional array is for returning any events, which were read but do not belong to the linkinfo.</para>
	    </callout>
	    <callout arearefs="stax.transformer.example.rewriteAndEmit">
		<para>This method finally writes the start tag with the correct attributes taken from the parsed LinkInfo.</para>
	    </callout>
	    <callout arearefs="stax.transformer.example.flushAdditionalEvents">
		<para>The events, which were read but not parsed, are finally added to the output of the transformer.</para>
	    </callout>
	    <callout arearefs="stax.transformer.example.collectLinkInfoInvocationNavigator">
		<para>The parser for the linkInfo object uses itself also navigators ...</para>
	    </callout>
	    <callout arearefs="stax.transformer.example.collectLinkInfoInvocationPeek">
		<para>... and reads more events from the parent.</para>
	    </callout>
	  </calloutlist>
	  </programlistingco>
      
	</section>
      </section>
      <section>
        <title>StAX serializer</title>
        <para>The <literal>StAXSerializer</literal> pulls and serializes the StAX events from the pipeline.</para>
		  <programlistingco>
	  <areaspec>
	    <area id="stax.serializer.example.parent" coords="4"/>
	    <area id="stax.serializer.example.initiatePull" coords="6"/>
	    <area id="stax.serializer.example.nextEvent" coords="9"/>
	    <area id="stax.serializer.example.setParent" coords="17"/>
	    <area id="stax.serializer.example.getContentType" coords="21"/>
	  </areaspec>    
	  <programlisting language="java"><![CDATA[public class NullSerializer extends AbstractStAXPipelineComponent 
   implements StAXConsumer, Finisher {
   
   private StAXProducer parent;

   public void initiatePullProcessing() {
      try {
         while (this.parent.hasNext()) {
            XMLEvent event = this.parent.nextEvent();
            /* serialize Event */
         }
      } catch (XMLStreamException e) {
         throw new ProcessingException("Error during writing output elements.", e);
      }
   }

   public void setParent(StAXProducer parent) {
      this.parent = parent;
   }

   public String getContentType()  ;
   public void setOutputStream(OutputStream outputStream) ;
}]]></programlisting>
	<calloutlist>
        <callout arearefs="stax.serializer.example.parent">
            <para>The Finisher has to pull from the previous pipeline component..</para>
         </callout>
         <callout arearefs="stax.serializer.example.initiatePull">
            <para>In case of StAX the last pipeline component has to start pulling for Events.</para>
         </callout>
         <callout arearefs="stax.serializer.example.nextEvent">
            <para>The serializer pulls the next Event from the previous component and should as next step serialize it.</para>
         </callout>
         <callout arearefs="stax.serializer.example.setParent">
            <para>During the pipeline construction the setParent is called to set the previous component of the pipeline.</para>
         </callout>
         <callout arearefs="stax.serializer.example.getContentType">
            <para>These two methods are defined in the Finisher and allow to set the OutputStream (if the Serializer needs any) and to retrieve the content-type of the result..</para>
         </callout>

       </calloutlist>
      </programlistingco>
      </section>
    </section>
    
    <section>
      <title>Using StAX and SAX components in the same pipeline</title>
      <para>The StAX pipeline offers interoperability to SAX components to a certain degree. However due their different paradigms only two use cases are currently implemented: Wrapping a SAX component in a StAX pipeline and a StAX-to-SAX pipeline, which starts with StAX components and finishes with SAX.</para>
        <section>
	<title>Wrapping a SAX component in a StAX pipeline</title>
	  <para>This allows to use existing SAX components in a StAX pipeline. Beware the overhead of the conversion of StAX->SAX->StAX - so no performance gains from a SAX component can be expected.</para>
	  <programlistingco>
	    <areaspec>
	      <area id="stax.converter.sax-in-stax.generator" coords="2"/>
	      <area id="stax.converter.sax-in-stax.wrapper" coords="3"/>
	      <area id="stax.converter.sax-in-stax.serializer" coords="4"/>
	    </areaspec>    
	    <programlisting language="java">
<![CDATA[Pipeline<StAXPipelineComponent> pipeStAX = new NonCachingPipeline<StAXPipelineComponent>();
pipeStAX.addComponent(new StAXGenerator(input));
pipeStAX.addComponent(new SAXForStAXPipelineWrapper(new CleaningTransformer()));
pipeStAX.addComponent(new StAXSerializer());
pipeStAX.setup(System.out);
pipeStAX.execute();]]></programlisting>
	  <calloutlist>
	    <callout arearefs="stax.converter.sax-in-stax.generator">
	      <para>The pipeline uses a <literal>StAXGenerator</literal> - which produces StAX events.</para>
	    </callout>
	    <callout arearefs="stax.converter.sax-in-stax.wrapper">
	      <para>In order to embed a single SAX component in a StAX pipeline, the <literal>SAXForStAXPipelineWrapper</literal> is needed. The constructor argument is the SAX component.</para>
	    </callout>
	    <callout arearefs="stax.converter.sax-in-stax.serializer">
	      <para>Altough the <literal>CleaningTransformer</literal> would emit SAX calls - the wrapper converts them back to the appropriate StAX events the <literal>StAXSerializer</literal> can write..</para>
	    </callout>
	  </calloutlist>
	</programlistingco>
	</section>
        <section>
	<title>StAX-to-SAX pipeline</title>
	  <para>This converter allows to mix StAX and SAX components - but is limited to starting with StAX and then switching to SAX. </para>
	  <programlistingco>
	    <areaspec>
	      <area id="stax.converter.stax-to-sax.generator" coords="2"/>
	      <area id="stax.converter.stax-to-sax.adapter" coords="3"/>
	      <area id="stax.converter.stax-to-sax.transformer" coords="4"/>
	      <area id="stax.converter.stax-to-sax.serializer" coords="5"/>
	    </areaspec>    
	    <programlisting language="java"><![CDATA[Pipeline<PipelineComponent> pipeStAX = new NonCachingPipeline<StAXPipelineComponent>();
pipeStAX.addComponent(new StAXGenerator(input));
pipeStAX.addComponent(new StAXToSAXPipelineAdapter());
pipeStAX.addComponent(new CleaningTransformer());
pipeStAX.addComponent(new XMLSerializer());
pipeStAX.setup(System.out);
pipeStAX.execute();]]></programlisting>
	  <calloutlist>
	    <callout arearefs="stax.converter.stax-to-sax.generator">
	      <para>The pipeline starts with a <literal>StAXGenerator</literal>.</para>
	    </callout>
	    <callout arearefs="stax.converter.stax-to-sax.adapter">
	      <para>The adapter converts the StAX events to SAX method calls.</para>
	    </callout>
	    <callout arearefs="stax.converter.stax-to-sax.transformer">
	      <para>The <literal>CleaningTransformer</literal> is a SAX component.</para>
	    </callout>
	    <callout arearefs="stax.converter.stax-to-sax.serializer">
	      <para>The <literal>XMLSerializer</literal> writes the SAX method calls to a file.</para>
	    </callout>
	  </calloutlist>
	</programlistingco>
	</section>
    </section>


    <section>
      <title>Java 1.5 support</title>
      <para>In order to use StAX with Java 1.5 an additional dependency is needed in the project's <literal>pom.xml</literal>. 
      <programlisting language="xml"><![CDATA[<dependency>
  <groupId>org.codehaus.woodstox</groupId>
  <artifactId>wstx-asl</artifactId>
  <version>3.2.7</version>
</dependency>]]>
</programlisting>
      Using woodstox is simpler, as the reference implementation depends on JAXP 1.4, which is not part of Java 1.5.
      </para>
    </section>
  </section>

  <section id="pipelines.utils">
    <title>Utilities</title>
    <para>TBW: XMLUtils, TransformUtils</para>
  </section>
</chapter>
