cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From reinh...@apache.org
Subject svn commit: r896957 [5/7] - in /cocoon/site/site/3.0: ./ css/ images/ reference/ reference/html-single/ reference/html-single/css/ reference/html-single/graphics/ reference/html/ reference/html/css/ reference/html/graphics/ reference/pdf/ student-proje...
Date Thu, 07 Jan 2010 18:47:20 GMT
Modified: cocoon/site/site/3.0/reference/html/pipelines.html
URL: http://svn.apache.org/viewvc/cocoon/site/site/3.0/reference/html/pipelines.html?rev=896957&r1=896956&r2=896957&view=diff
==============================================================================
--- cocoon/site/site/3.0/reference/html/pipelines.html (original)
+++ cocoon/site/site/3.0/reference/html/pipelines.html Thu Jan  7 18:47:18 2010
@@ -10,8 +10,8 @@
             The last component is of type <code class="literal">org.apache.cocoon.pipeline.component.Finisher</code>.
           </p></li><li><p>
             In order to link components with each other, the first has to be a 
-            <code class="literal">org.apache.cocoon.pipeline.component.Finisher</code>, the latter
-            <code class="literal">org.apache.cocoon.pipeline.component.Producer</code>.
+            <code class="literal">org.apache.cocoon.pipeline.component.Producer</code>, the latter
+            <code class="literal">org.apache.cocoon.pipeline.component.Consumer</code>.
           </p></li></ul></div><p>
       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
@@ -38,8 +38,8 @@
         and a <code class="literal">Consumer</code> and a serializer is a <code class="literal">Consumer</code> and a <code class="literal">Finisher</code>.
       </p><p>
         Here is some Java code that demonstrates how a pipeline can be utilized with SAX-based XML components:      
-      </p><div class="programlistingco"><pre class="programlisting">Pipeline pipeline = <span class="hl-keyword">new</span> NonCachingPipeline();                                            <span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
-pipeline.addComponent(<span class="hl-keyword">new</span> StringGenerator(<span class="hl-string">"&lt;x&gt;&lt;/x&gt;"</span>));                                   <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+      </p><div class="programlistingco"><pre class="programlisting">Pipeline&lt;SAXPipelineComponent&gt; pipeline = <span class="hl-keyword">new</span> NonCachingPipeline&lt;SAXPipelineComponent&gt;();<span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
+pipeline.addComponent(<span class="hl-keyword">new</span> XMLGenerator(<span class="hl-string">"&lt;x&gt;&lt;/x&gt;"</span>));                                      <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
 pipeline.addComponent(<span class="hl-keyword">new</span> XSLTTransformer(<span class="hl-keyword">this</span>.getClass().getResource(<span class="hl-string">"/test1.xslt"</span>)));  <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
 pipeline.addComponent(<span class="hl-keyword">new</span> XSLTTransformer(<span class="hl-keyword">this</span>.getClass().getResource(<span class="hl-string">"/test2.xslt"</span>)));  <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
 pipeline.addComponent(<span class="hl-keyword">new</span> XMLSerializer());                                              <span class="co"><img src="images/callouts/5.png" alt="(5)"></span>
@@ -54,32 +54,32 @@
               Add a generator, that implements the <code class="literal">org.apache.cocoon.pipeline.component.PipelineComponent</code> interface to the
               pipeline by using the pipeline's <code class="literal">addComponent(pipelineComponent)</code> interface.
             </p><p>
-              The <code class="literal">StringGenerator</code> expects a <code class="literal">java.lang.String</code> object and produces SAX events by using a SAX parser.
-              Hence it has to implement the <code class="literal">org.apache.cocoon.pipeline.component.sax.SAXProducer</code> interface.
+              The <code class="literal">XMLGenerator</code> expects a <code class="literal">java.lang.String</code> object and produces SAX events by using a SAX parser.
+              Hence it has to implement the <code class="literal">org.apache.cocoon.sax.component.SAXProducer</code> interface.
             </p><p>
               The <code class="literal">SAXProducer</code> interface extends the <code class="literal">org.apache.cocoon.pipeline.component.Producer</code> interface. This
               means that it expects the next (or the same!) component to implement the <code class="literal">org.apache.cocoon.pipeline.component.Consumer</code>
-              interface. The check that the next pipeline component is of type <code class="literal">org.apache.cocoon.pipeline.component.sax.SAXConsumer</code>
-              isn't done at interface level but by the implementation (see the <code class="literal">org.apache.cocoon.pipeline.component.sax.AbstractXMLProducer</code>
-              for details which the <code class="literal">StringGenerator</code> is inherited from).
+              interface. The check that the next pipeline component is of type <code class="literal">org.apache.cocoon.sax.component.SAXConsumer</code>
+              isn't done at interface level but by the implementation (see the <code class="literal">org.apache.cocoon.sax.component.AbstractXMLProducer</code>
+              for details which the <code class="literal">XMLGenerator</code> is inherited from).
             </p><p>
               Since a generator is the first component of a pipeline, it also has to implement the <code class="literal">Starter</code> interface.
             </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>
-              Add a transformer, that implements the <code class="literal">org.apache.cocoon.pipeline.component.PipelineComponent</code> interface to the
-              pipeline by using the pipeline's <code class="literal">addComponent(pipelineComponent)</code> interface.
+              Add a transformer, that implements the <code class="literal">org.apache.cocoon.pipeline.component.PipelineComponent</code> interface, to the
+              pipeline by using the pipeline's <code class="literal">addComponent(pipelineComponent)</code> method.
             </p><p>
               This <code class="literal">XSLTTransformer</code> expects the <code class="literal">java.net.URL</code> of an XSLT stylesheet. It uses the rules of the stylesheet
               to add, change or delete nodes of the XML SAX stream.
             </p><p>
               Since it implements the <code class="literal">org.apache.cocoon.pipeline.component.Consumer</code> interface, it fulfills the general contract that a <code class="literal">Consumer</code>
-              is linked with a <code class="literal">Producer</code>. By implementing the <code class="literal">org.apache.cocoon.pipeline.component.sax.SAXConsumer</code> interface,
-              it fulfills the specific requirement of the previous <code class="literal">StringGenerator</code> that expects a next pipeline component of that type. 
+              is linked with a <code class="literal">Producer</code>. By implementing the <code class="literal">org.apache.cocoon.sax.component.SAXConsumer</code> interface,
+              it fulfills the specific requirement of the previous <code class="literal">XMLGenerator</code> that expects a next pipeline component of that type. 
             </p><p>
-              This transformer also implements the <code class="literal">org.apache.cocoon.pipeline.component.sax.SAXProducer</code> interface. This interface extends the
+              This transformer also implements the <code class="literal">org.apache.cocoon.sax.component.SAXProducer</code> interface. This interface extends the
               <code class="literal">org.apache.cocoon.pipeline.component.Producer</code> interface which means that the next component has to be a 
-              <code class="literal">org.apache.cocoon.pipeline.component.Consumer</code>. Like the previous <code class="literal">StringGenerator</code>, the <code class="literal">XSLTTransformer</code>
-              inherits from the <code class="literal">org.apache.cocoon.pipeline.component.sax.AbstractXMLProducer</code> which contains the check that the next component
-              is of type <code class="literal">org.apache.cocoon.pipeline.component.sax.SAXConsumer</code>. 
+              <code class="literal">org.apache.cocoon.pipeline.component.Consumer</code>. Like the previous <code class="literal">XMLGenerator</code>, the <code class="literal">XSLTTransformer</code>
+              inherits from the <code class="literal">org.apache.cocoon.sax.component.AbstractXMLProducer</code> which contains the check that the next component
+              is of type <code class="literal">org.apache.cocoon.sax.component.SAXConsumer</code>. 
             </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>
               Add another transformer to the pipeline. A pipeline can contain any number of components that implement the <code class="literal">Producer</code> and 
               <code class="literal">Consumer</code> interfaces at the same time. However, they mustn't be neither of type <code class="literal">Starter</code> nor <code class="literal">Finisher</code>.
@@ -104,6 +104,170 @@
               Once the pipeline has been started, it either succeeds or fails. There is no way to react on any (error) conditions.
             </p></td></tr></table></div></div><div class="table"><a name="pipeline.components.sax"></a><p class="title"><b>Table&nbsp;2.1.&nbsp;SAX components and their interfaces</b></p><div class="table-contents"><table summary="SAX components and their interfaces" width="100%" border="1"><colgroup><col><col align="center"><col align="center"><col><col></colgroup><thead><tr><th>Component type</th><th align="center">Structural interfaces</th><th align="center">Content-specific interfaces</th><td class="auto-generated">&nbsp;</td><td class="auto-generated">&nbsp;</td></tr></thead><tbody><tr><td>SAX generator</td><td align="center">Starter, Producer, PipelineComponent</td><td align="center">SAXProducer</td><td class="auto-generated">&nbsp;</td><td class="auto-generated">&nbsp;</td></tr><tr><td>SAX transformer</td><td align="center">Producer, Consumer, PipelineComponent</td><td align="center">SAXProducer, SAXConsumer</td><td class="auto-generated">&nbsp;</td><td class="auto-ge
 nerated">&nbsp;</td></tr><tr><td>SAX serializer</td><td align="center">Finisher, Consumer, PipelineComponent</td><td align="center">SAXConsumer</td><td class="auto-generated">&nbsp;</td><td class="auto-generated">&nbsp;</td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipelines.implementations"></a>2.2.&nbsp;Pipeline implementations</h2></div></div></div><p>TBW: noncaching, caching, async-caching, expires caching, own implementations</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipelines.embedding"></a>2.3.&nbsp;Embedding a pipeline</h2></div></div></div><p>TBW: Passing parameters to the pipeline and its components, finsih() method</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipeline.sax"></a>2
 .4.&nbsp;SAX components</h2></div></div></div><p>concept, writing custom SAX components, link to Javadocs</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e363"></a>2.4.1.&nbsp;Available components</h3></div></div></div><p>Link to Javadocs</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e368"></a>2.4.2.&nbsp;Writing custom components</h3></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e371"></a>2.4.2.1.&nbsp;SAX generator</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one
               (available abstract classes)
-        </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e376"></a>2.4.2.2.&nbsp;SAX transformer</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one</p><p>buffering</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e383"></a>2.4.2.3.&nbsp;SAX serializer</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one</p></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipeline.stax"></a>2.5.&nbsp;StAX components</h2></div></div></div><p>explain StAX in general, advantages (ease of writing fast transformers), links to external sources</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e393"></a>2.5.1.&nbsp;Available components</h3></div></div></div><p>Link to Javadocs
 </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e398"></a>2.5.2.&nbsp;Writing custom components</h3></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e401"></a>2.5.2.1.&nbsp;StAX generator</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one
-              (available abstract classes)
-        </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e406"></a>2.5.2.2.&nbsp;StAX transformer</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one</p><p>explain navigators by example</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e413"></a>2.5.2.3.&nbsp;StAX serializer</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e418"></a>2.5.3.&nbsp;Using StAX and SAX components in the same pipeline</h3></div></div></div><p></p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e422"></a>2.5.4.&nbsp;Java 1.5 support</h3></div></div></div><p>What do you have to do to use StAX components, in a Java 1.5 environment</p></div></di
 v><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipelines.utils"></a>2.6.&nbsp;Utilities</h2></div></div></div><p>TBW: XMLUtils, TransformUtils</p></div></div><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="introduction.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="sitemap.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;1.&nbsp;Introduction&nbsp;</td><td width="20%" align="center"><span style="color:white;font-size:85%;"><a href="http://cocoon.apache.org/3.0/" title="The Apache Cocoon community">The Apache Cocoon community</a></span></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;3.&nbsp;Sitemaps</td></tr></table></di
 v></body></html>
+        </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e376"></a>2.4.2.2.&nbsp;SAX transformer</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one</p><p>buffering</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e383"></a>2.4.2.3.&nbsp;SAX serializer</h4></div></div></div><p>explain from a user's point of view, what she needs to do to implement one</p></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipeline.stax"></a>2.5.&nbsp;StAX components</h2></div></div></div><p>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.</p><p>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.
+    </p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e395"></a>2.5.1.&nbsp;Available components</h3></div></div></div><div class="itemizedlist"><ul type="disc"><li><p><code class="literal">StAXGenerator</code> is a Starter and normally parses a XML from an InputStream.</p></li><li><p><code class="literal">StAXSerializer</code> is a Finisher and writes the StAX Events to an OutputStream.</p></li><li><p><code class="literal">AbstractStAXTransformer</code> is the abstract base class for new transformers. It simplifies the task by providing a template method for generating the new events.</p></li><li><p><code class="literal">StAXCleaningTransformer</code> is an transformer, which cleans the document from whitespaces and comments.</p></li><li><p><code class="literal">IncludeTransformer</code> includes the contents of another document.</p></li></ul></div><p>For further information refer to the <a xmlns:xlink="http://www.w3.org/1999/x
 link" href="http://cocoon.apache.org/3.0/apidocs/org/apache/cocoon/stax/package-summary.html" target="_top">javadoc</a></p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e429"></a>2.5.2.&nbsp;Writing custom components</h3></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e432"></a>2.5.2.1.&nbsp;StAX generator</h4></div></div></div><p>The <code class="literal">StAXGenerator</code> is a <code class="literal">Starter</code> component and produces XMLEvents.
+  </p><div class="programlistingco"><pre class="programlisting"><span class="hl-keyword">import</span> java.io.InputStream;
+<span class="hl-keyword">import</span> java.net.URL;
+
+<span class="hl-keyword">import</span> javax.xml.stream.FactoryConfigurationError;
+<span class="hl-keyword">import</span> javax.xml.stream.XMLEventReader;
+<span class="hl-keyword">import</span> javax.xml.stream.XMLInputFactory;
+<span class="hl-keyword">import</span> javax.xml.stream.XMLStreamException;
+<span class="hl-keyword">import</span> javax.xml.stream.events.XMLEvent;
+
+<span class="hl-keyword">import</span> org.apache.cocoon.pipeline.SetupException;
+<span class="hl-keyword">import</span> org.apache.cocoon.pipeline.component.Starter;
+<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> MyStAXGenerator <span class="hl-keyword">extends</span> AbstractStAXProducer <span class="hl-keyword">implements</span> Starter {           <span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
+
+   <span class="hl-keyword">private</span> XMLEventReader reader;
+    
+   <span class="hl-keyword">public</span> MyStAXGenerator(InputStream inputStream) {
+      <span class="hl-keyword">try</span> {
+         <span class="hl-keyword">this</span>.reader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);  <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+      } <span class="hl-keyword">catch</span> (XMLStreamException e) {
+         <span class="hl-keyword">throw</span> <span class="hl-keyword">new</span> SetupException(<span class="hl-string">"Error during setup an XMLEventReader on the inputStream"</span>, e);
+      } <span class="hl-keyword">catch</span> (FactoryConfigurationError e) {
+         <span class="hl-keyword">throw</span> <span class="hl-keyword">new</span> SetupException(<span class="hl-string">"Error during setup the XMLInputFactory for creating an XMLEventReader"</span>, e);
+      }
+   }
+    
+   <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> execute() {
+      <span class="hl-keyword">this</span>.getConsumer().initiatePullProcessing();                                       <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
+   }
+
+   <span class="hl-keyword">public</span> <span class="hl-keyword">boolean</span> hasNext() {
+      <span class="hl-keyword">return</span> <span class="hl-keyword">this</span>.reader.hasNext();                                                      <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
+   }
+
+   <span class="hl-keyword">public</span> XMLEvent nextEvent() <span class="hl-keyword">throws</span> XMLStreamException {
+      <span class="hl-keyword">return</span> <span class="hl-keyword">this</span>.reader.nextEvent();                                                    <span class="co"><img src="images/callouts/5.png" alt="(5)"></span>
+   }
+    
+   <span class="hl-keyword">public</span> XMLEvent peek() <span class="hl-keyword">throws</span> XMLStreamException {
+      <span class="hl-keyword">return</span> <span class="hl-keyword">this</span>.reader.peek();                                                         <span class="co"><img src="images/callouts/6.png" alt="(6)"></span>
+   }
+  
+} </pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>
+        In order to implement an own <code class="literal">StAXGenerator</code> the easiest approach is to inherit from <code class="literal">AbstractStAXProducer</code>.
+            </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>
+        The constructor creates a new XMLEventReader for reading from the inputstream.
+            </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>
+        The pipeline is started using the <code class="literal">execute</code> method. As StAX is a pull based approach the last component has to start pulling.
+            </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>This method should return true if the generator has a next Event. </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/5.png" alt="5" border="0"></td><td valign="top" align="left"><p>Returns the next event from the generator.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/6.png" alt="6" border="0"></td><td valign="top" align="left"><p>Returns the next event from the generator, without moving actually to the next event.</p></td></tr></table></div></div><p>
+  </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e482"></a>2.5.2.2.&nbsp;StAX transformer</h4></div></div></div><p>Implementing a StAX Transformer should be the most common use case. The <code class="literal">AbstractStAXTransformer</code> provides a foundation for new transformers. But in order to write new transformers even simpler, let's describe another feature first:</p><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="d0e490"></a>2.5.2.2.1.&nbsp;Navigator</h5></div></div></div><p>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:
+  </p><div class="itemizedlist"><ul type="disc"><li><p><code class="literal">FindStartElementNavigator</code> finds the start tag with certain properties(name,attribute)</p></li><li><p><code class="literal">FindEndElementNavigator</code> finds the end tag with certain properties(name,attribute)</p></li><li><p><code class="literal">FindCorrespondingStartEndElementPairNavigator</code> finds both the start and the corresponding end tag.</p></li><li><p><code class="literal">InSubtreeNavigator</code> finds whole subtrees, by specifying the properties of the "root" element.</p></li></ul></div><p>
+  For further information refer to the <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://cocoon.apache.org/3.0/apidocs/org/apache/cocoon/stax/navigation/package-summary.html" target="_top">navigator javadoc</a>
+  </p><div class="section" lang="en"><div class="titlepage"><div><div><h6 class="title"><a name="d0e520"></a>2.5.2.2.1.1.&nbsp;Using navigators</h6></div></div></div><p>
+    Using a navigator is a rather simple task. The transformer peeks or gets the next event and calls <code class="literal">Navigator.fulfillsCriteria</code> - if true is returned the transformer should be process that event somehow. 
+    </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h6 class="title"><a name="d0e528"></a>2.5.2.2.1.2.&nbsp;Implementing a navigator</h6></div></div></div><p>Creating a new navigator is a rather simple task and just means implementing two methods:</p><div class="programlistingco"><pre class="programlisting"><span class="hl-keyword">import</span> javax.xml.stream.events.XMLEvent;
+
+<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> MyNavigator <span class="hl-keyword">implements</span> Navigator {
+   <span class="hl-keyword">public</span> <span class="hl-keyword">boolean</span> fulfillsCriteria(XMLEvent event) {                                     <span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
+      <span class="hl-keyword">return</span> false;
+   }
+    
+   <span class="hl-keyword">public</span> <span class="hl-keyword">boolean</span> isActive() {                                                           <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+      <span class="hl-keyword">return</span> false;
+   }
+}
+  </pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>
+        This method returns true if the event matches the criteria of the navigator.
+            </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>
+        Returns the result of the last invocation of fulfillsCriteria.
+      </p></td></tr></table></div></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="d0e546"></a>2.5.2.2.2.&nbsp;Implementing a transformer</h5></div></div></div><p>The next example should show you an transformer featuring navigators and implicit state handling through function calls.</p><div class="programlistingco"><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> DaisyLinkRewriteTransformer <span class="hl-keyword">extends</span> AbstractStAXTransformer {
+  @Override
+   <span class="hl-keyword">protected</span> <span class="hl-keyword">void</span> produceEvents() <span class="hl-keyword">throws</span> XMLStreamException {
+      <span class="hl-keyword">while</span> (<span class="hl-keyword">this</span>.getParent().hasNext()) {
+         XMLEvent event = <span class="hl-keyword">this</span>.getParent().nextEvent();
+         <span class="hl-keyword">if</span> (<span class="hl-keyword">this</span>.anchorNavigator.fulfillsCriteria(event)) {                             <span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
+            ArrayList&lt;XMLEvent&gt; innerContent = <span class="hl-keyword">new</span> ArrayList&lt;XMLEvent&gt;();
+            LinkInfo linkInfo = <span class="hl-keyword">this</span>.collectLinkInfo(innerContent);                      <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+            <span class="hl-keyword">if</span>(linkInfo != null) {
+               linkInfo.setNavigationPath(<span class="hl-keyword">this</span>.getAttributeValue(event.asStartElement(), <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
+                  PUBLISHER_NS,<span class="hl-string">"navigationPath"</span>));
+
+               <span class="hl-keyword">this</span>.rewriteAttributesAndEmitEvent(event.asStartElement(),linkInfo);      <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
+
+               <span class="hl-keyword">if</span>(innerContent.size() != 0) {
+                  <span class="hl-keyword">this</span>.addAllEventsToQueue(innerContent);
+               }
+            } 
+            <span class="hl-comment">/* ... */</span>
+         } 
+         <span class="hl-comment">/* ... */</span>
+      }
+   }
+
+   <span class="hl-keyword">private</span> LinkInfo collectLinkInfo(List&lt;XMLEvent&gt; events) <span class="hl-keyword">throws</span> XMLStreamException {
+      Navigator linkInfoNavigator = <span class="hl-keyword">new</span> InSubtreeNavigator(LINK_INFO_EL);                <span class="co"><img src="images/callouts/5.png" alt="(5)"></span>
+      Navigator linkInfoPartNavigator = <span class="hl-keyword">new</span> FindStartElementNavigator(LINK_PART_INFO_EL);
+      LinkInfo linkInfo = null;
+
+      <span class="hl-keyword">while</span> (<span class="hl-keyword">this</span>.getParent().hasNext()) {
+         XMLEvent event = <span class="hl-keyword">this</span>.getParent().peek();                                       <span class="co"><img src="images/callouts/6.png" alt="(6)"></span>
+
+         <span class="hl-keyword">if</span> (linkInfoNavigator.fulfillsCriteria(event)) {
+            event = <span class="hl-keyword">this</span>.getParent().nextEvent();
+            <span class="hl-keyword">if</span> (linkInfoPartNavigator.fulfillsCriteria(event)) {
+               <span class="hl-comment">/* ... */</span>
+               String fileName = <span class="hl-keyword">this</span>.getAttributeValue(event.asStartElement(),<span class="hl-string">"fileName"</span>);
+               <span class="hl-keyword">if</span> (!<span class="hl-string">""</span>.equals(fileName)) {
+                  linkInfo.setFileName(fileName);
+               }
+            } <span class="hl-comment">/* ... */</span>
+         } <span class="hl-keyword">else</span> <span class="hl-keyword">if</span> (event.isCharacters()) {
+            events.add(<span class="hl-keyword">this</span>.getParent().nextEvent());
+         } <span class="hl-keyword">else</span> {
+            <span class="hl-keyword">return</span> linkInfo;
+         }
+      }
+      <span class="hl-keyword">return</span> linkInfo;
+   }
+
+   <span class="hl-keyword">private</span> <span class="hl-keyword">void</span> rewriteAttributesAndEmitEvent(StartElement event, LinkInfo linkInfo) ;
+
+}</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>The transformer checks for anchors in the XML.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>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.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>This method finally writes the start tag with the correct attributes taken from the parsed LinkInfo.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>T
 he events, which were read but not parsed, are finally added to the output of the transformer.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/5.png" alt="5" border="0"></td><td valign="top" align="left"><p>The parser for the linkInfo object uses itself also navigators ...</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/6.png" alt="6" border="0"></td><td valign="top" align="left"><p>... and reads more events from the parent.</p></td></tr></table></div></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e580"></a>2.5.2.3.&nbsp;StAX serializer</h4></div></div></div><p>The <code class="literal">StAXSerializer</code> pulls and serializes the StAX events from the pipeline.</p><div class="programlistingco"><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> NullSerializer <span class="hl-keyword">ext
 ends</span> AbstractStAXPipelineComponent 
+   <span class="hl-keyword">implements</span> StAXConsumer, Finisher {
+   
+   <span class="hl-keyword">private</span> StAXProducer parent;                                                          <span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
+
+   <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> initiatePullProcessing() {                                                <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+      <span class="hl-keyword">try</span> {
+         <span class="hl-keyword">while</span> (<span class="hl-keyword">this</span>.parent.hasNext()) {
+            XMLEvent event = <span class="hl-keyword">this</span>.parent.nextEvent();                                    <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
+            <span class="hl-comment">/* serialize Event */</span>
+         }
+      } <span class="hl-keyword">catch</span> (XMLStreamException e) {
+         <span class="hl-keyword">throw</span> <span class="hl-keyword">new</span> ProcessingException(<span class="hl-string">"Error during writing output elements."</span>, e);
+      }
+   }
+
+   <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setParent(StAXProducer parent) {                                          <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
+      <span class="hl-keyword">this</span>.parent = parent;
+   }
+
+   <span class="hl-keyword">public</span> String getContentType()  ;                                                     <span class="co"><img src="images/callouts/5.png" alt="(5)"></span>
+   <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setOutputStream(OutputStream outputStream) ;
+}</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>The Finisher has to pull from the previous pipeline component..</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>In case of StAX the last pipeline component has to start pulling for Events.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>The serializer pulls the next Event from the previous component and should as next step serialize it.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>During the pipeline construction the setParent is called to set the previous component of the 
 pipeline.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/5.png" alt="5" border="0"></td><td valign="top" align="left"><p>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..</p></td></tr></table></div></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e613"></a>2.5.3.&nbsp;Using StAX and SAX components in the same pipeline</h3></div></div></div><p>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.</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e618"></a>2.5.3.1.&nbsp;Wrapping a SAX compone
 nt in a StAX pipeline</h4></div></div></div><p>This allows to use existing SAX components in a StAX pipeline. Beware the overhead of the conversion of StAX-&gt;SAX-&gt;StAX - so no performance gains from a SAX component can be expected.</p><div class="programlistingco"><pre class="programlisting">
+Pipeline&lt;StAXPipelineComponent&gt; pipeStAX = <span class="hl-keyword">new</span> NonCachingPipeline&lt;StAXPipelineComponent&gt;(<span class="co"><img src="images/callouts/1.png" alt="(1)"></span>);
+pipeStAX.addComponent(<span class="hl-keyword">new</span> StAXGenerator(input));                                         <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+pipeStAX.addComponent(<span class="hl-keyword">new</span> SAXForStAXPipelineWrapper(<span class="hl-keyword">new</span> CleaningTransformer()));         <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
+pipeStAX.addComponent(<span class="hl-keyword">new</span> StAXSerializer());
+pipeStAX.setup(System.out);
+pipeStAX.execute();</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>The pipeline uses a <code class="literal">StAXGenerator</code> - which produces StAX events.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>In order to embed a single SAX component in a StAX pipeline, the <code class="literal">SAXForStAXPipelineWrapper</code> is needed. The constructor argument is the SAX component.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Altough the <code class="literal">CleaningTransformer</code> would emit SAX calls - the wrapper converts them back to the appropriate StAX events the <code class="literal">StAXSerializer</code> ca
 n write..</p></td></tr></table></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e652"></a>2.5.3.2.&nbsp;StAX-to-SAX pipeline</h4></div></div></div><p>This converter allows to mix StAX and SAX components - but is limited to starting with StAX and then switching to SAX. </p><div class="programlistingco"><pre class="programlisting">Pipeline&lt;PipelineComponent&gt; pipeStAX = <span class="hl-keyword">new</span> NonCachingPipeline&lt;StAXPipelineComponent&gt;();
+pipeStAX.addComponent(<span class="hl-keyword">new</span> StAXGenerator(input));                                         <span class="co"><img src="images/callouts/1.png" alt="(1)"></span>
+pipeStAX.addComponent(<span class="hl-keyword">new</span> StAXToSAXPipelineAdapter());                                   <span class="co"><img src="images/callouts/2.png" alt="(2)"></span>
+pipeStAX.addComponent(<span class="hl-keyword">new</span> CleaningTransformer());                                        <span class="co"><img src="images/callouts/3.png" alt="(3)"></span>
+pipeStAX.addComponent(<span class="hl-keyword">new</span> XMLSerializer());                                              <span class="co"><img src="images/callouts/4.png" alt="(4)"></span>
+pipeStAX.setup(System.out);
+pipeStAX.execute();</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>The pipeline starts with a <code class="literal">StAXGenerator</code>.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>The adapter converts the StAX events to SAX method calls.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>The <code class="literal">CleaningTransformer</code> is a SAX component.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>The <code class="literal">XMLSerializer</code> writes the SAX method calls to a file.</p></td></tr></table></div></di
 v></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e687"></a>2.5.4.&nbsp;Java 1.5 support</h3></div></div></div><p>In order to use StAX with Java 1.5 an additional dependency is needed in the project's <code class="literal">pom.xml</code>. 
+      </p><pre class="programlisting">&lt;<span class="hl-tag">dependency</span>&gt;
+  &lt;<span class="hl-tag">groupId</span>&gt;org.codehaus.woodstox&lt;<span class="hl-tag">/groupId</span>&gt;
+  &lt;<span class="hl-tag">artifactId</span>&gt;wstx-asl&lt;<span class="hl-tag">/artifactId</span>&gt;
+  &lt;<span class="hl-tag">version</span>&gt;3.2.7&lt;<span class="hl-tag">/version</span>&gt;
+&lt;<span class="hl-tag">/dependency</span>&gt;
+</pre><p>
+      Using woodstox is simpler, as the reference implementation depends on JAXP 1.4, which is not part of Java 1.5.
+      </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="pipelines.utils"></a>2.6.&nbsp;Utilities</h2></div></div></div><p>TBW: XMLUtils, TransformUtils</p></div></div><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="introduction.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="sitemap.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;1.&nbsp;Introduction&nbsp;</td><td width="20%" align="center"><span style="color:white;font-size:85%;"><a href="http://cocoon.apache.org/3.0/" title="The Apache Cocoon community">The Apache Cocoon community</a></span></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;3.&nbsp;Sitemaps</
 td></tr></table></div></body></html>



Mime
View raw message