Just wanted to reply on my own question.  I did a bit of out-of-the-box thinking and came up with a even nicer solution for my particular use case.

 

Basically all that servlet service does is exposing that XSLT to all cocoon blocks using that have a dependency on this shared module.  And I might add it’s doing this in a tedious way.

 

Remember my original service pattern?  It was first of all tedious to pass on parameters to it and secondly it just doesn’t work if the serializer is not of @type XML.

 

            <map:match pattern="csv-transformation-service/*">

              <map:generate src="service-consumer:"/>

              <map:transform src="xslt/csv_transformer.xslt" type="saxon">

                <map:parameter name="separator" value="{1}"/>

              </map:transform>

              <map:serialize type="text"/>

            </map:match>

 

Invocation from this service looked like this:

 

      <map:match pattern="test-csv-transformer-service">

          <map:generate src="data/csv_generator_testdata.xml"/>

          <map:transform type="servletService">

            <map:parameter name="service" value="servlet:shared:/csv-transformation-service/blabla"/>

          </map:transform>

          <map:serialize type="text"/>

      </map:match>

 

 

Here comes the clean and elegant solution  (I just expose the XSLT by itself) and no ugly match pattern needed.

 

            <!-- match pattern pointing to shared CSV XML transformer -->

            <map:match pattern="csv-transformer">

              <map:generate src="xslt/csv_transformer.xslt"/>

              <map:serialize type="xml"/>

            </map:match>

 

Here is the invocation where I can pass parameters just as one would expect for an xslt.

      <map:match pattern="test-csv-transformer">

          <map:generate src="data/csv_generator_testdata.xml"/>

          <map:transform src="servlet:shared:/csv-transformer" type="saxon">

            <map:parameter name="separator" value="&#x9;"/>

          </map:transform>

          <map:serialize type="text"/>

      </map:match>

 

Just tested it and of course this workaround works as one would expect.  Although I consider this a workaround I think it’s even much more user friendly and simple than using the servlet service.  Hence I’d like to share it.

 

Cheers,

Robby Pelssers

 

From: Robby Pelssers [mailto:Robby.Pelssers@nxp.com]
Sent: Tuesday, May 15, 2012 12:36 PM
To: dev@cocoon.apache.org; users@cocoon.apache.org
Subject: Bug in servlet service framework C2.2??

 

Hi all,

 

As an important side note.  I’ve run into a serious limitation a few times already.

 

Let me explain shortly what I try to do.

 

I want to e.g. generate an XML representation of CSV data from an XQuery generator.  I borrowed the schema from the CSV generator and dropped some attributes which are not useful.

 

<?xml version="1.0" encoding="ISO-8859-1"?>

<csv:document xmlns:csv="http://apache.org/cocoon/csv/1.0">

    <csv:header>

        <csv:column>Column A</csv:column>

        <csv:column>Column B</csv:column>

        <csv:column>Column C</csv:column>

    </csv:header>

    <csv:record>

        <csv:field>Field A1</csv:field>

        <csv:field>Field B1</csv:field>

        <csv:field>Field C1</csv:field>

    </csv:record>

    <csv:record>

        <csv:field>Field A2</csv:field>

        <csv:field>Field B2</csv:field>

        <csv:field>Field C2</csv:field>

    </csv:record>

</csv:document>

 

Next I wrote a XSLT that transforms this into a CSV file.

 

<?xml version="1.0" encoding="UTF-8"?>

<!--

Author: Robby Pelssers

This stylesheet transforms a CSV xml file into CSV

-->

 

<xsl:stylesheet version="2.0"

  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

  xmlns:xs="http://www.w3.org/2001/XMLSchema"

  xmlns:fn="http://www.w3.org/2005/xpath-functions"

  xmlns:csv="http://apache.org/cocoon/csv/1.0">

 

  <xsl:output method="text"/>

 

  <xsl:param name="separator" as="xs:string"/>

  <xsl:variable name="new_line" select="'&#xA;'" />

 

  <xsl:template match="/">

    <xsl:apply-templates/>

  </xsl:template>

 

  <xsl:template match="csv:document">

    <xsl:apply-templates select="csv:header"/>

    <xsl:apply-templates select="csv:record"/>

  </xsl:template>

 

  <xsl:template match="csv:header">

    <xsl:value-of select="fn:string-join(csv:column, $separator)"/><xsl:value-of select="$new_line" />

  </xsl:template>

 

  <xsl:template match="csv:record">

    <xsl:value-of select="fn:string-join(csv:field, $separator)"/><xsl:value-of select="$new_line" />

  </xsl:template>

 

</xsl:stylesheet>

 

To test if it works I wrote a little match pattern:

 

            <map:match pattern="test_csv_transformer">

              <map:generate src="data/csv_generator_testdata.xml"/>

              <map:transform src="xslt/csv_transformer.xslt" type="saxon">

                <map:parameter name="separator" value="&#x9;"/>

              </map:transform>

              <map:serialize type="text"/>

            </map:match>

 

And the output works like a charm:

Column A       Column B       Column C

Field A1       Field B1       Field C1

Field A2       Field B2       Field C2

 

But I wanted to create a reusable transformation service and setup following pattern:

 

            <map:match pattern="csv-transformation-service/*">

              <map:generate src="service-consumer:"/>

              <map:transform src="xslt/csv_transformer.xslt" type="saxon">

                <map:parameter name="separator" value="{1}"/>

              </map:transform>

              <map:serialize type="text"/>

            </map:match>

 

Unfortunately I can’t call this from another cocoon block like e.g.

 

      <map:match pattern="test-csv-transformer-service">

          <map:generate src="data/csv_generator_testdata.xml"/>

          <map:transform type="servletService">

            <map:parameter name="service" value="servlet:shared:/csv-transformation-service/blabla"/>

          </map:transform>

          <map:serialize type="text"/>

      </map:match>

 

 

The reason is that only XML is supported evidently.  But is this a requirement by design or were such use cases not foreseen?!

 

Robby

 

 

Stacktrace:

 

2012-05-15 12:33:55.935::INFO:  Started SelectChannelConnector@0.0.0.0:8888

javax.servlet.ServletException: org.apache.cocoon.ProcessingException: Failed to process pipeline

                at [SAXParseException] - servlet:com.nxp.spider2.shared.service+:/csv-transformation-service/blabla:1:1

                at <map:serialize type="text"> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:354:39

                at <map:transform type="servletService"> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:351:48

                at <map:generate> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:350:64

                at <map:match> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:349:57

                at org.apache.cocoon.servlet.RequestProcessor.service(RequestProcessor.java:230)

                at org.apache.cocoon.sitemap.SitemapServlet.service(SitemapServlet.java:84)

                at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

                at org.apache.cocoon.servletservice.ServletServiceContext$PathDispatcher.forward(ServletServiceContext.java:468)

                at org.apache.cocoon.servletservice.ServletServiceContext$PathDispatcher.forward(ServletServiceContext.java:443)

                at org.apache.cocoon.servletservice.spring.ServletFactoryBean$ServiceInterceptor.invoke(ServletFactoryBean.java:264)

                at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)

                at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)

                at $Proxy21.service(Unknown Source)

                at org.apache.cocoon.servletservice.DispatcherServlet.service(DispatcherServlet.java:106)

                at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

                at org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingServlet.service(ReloadingServlet.java:115)

                at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)

                at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)

                at org.apache.cocoon.servlet.multipart.MultipartFilter.doFilter(MultipartFilter.java:131)

                at org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingServletFilter.doFilter(ReloadingServletFilter.java:66)

                at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

                at org.apache.cocoon.servlet.DebugFilter.doFilter(DebugFilter.java:167)

                at org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingServletFilter.doFilter(ReloadingServletFilter.java:66)

                at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

                at org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingSpringFilter.doFilter(ReloadingSpringFilter.java:71)

                at org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingServletFilter.doFilter(ReloadingServletFilter.java:66)

                at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)

                at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)

                at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

                at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)

                at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)

                at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)

                at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)

                at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)

                at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)

                at org.mortbay.jetty.Server.handle(Server.java:326)

                at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:536)

                at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:915)

                at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)

                at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)

                at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:405)

                at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)

                at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Caused by: org.apache.cocoon.ProcessingException: Failed to process pipeline

                at [SAXParseException] - servlet:com.nxp.spider2.shared.service+:/csv-transformation-service/blabla:1:1

                at <map:serialize type="text"> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:354:39

                at <map:transform type="servletService"> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:351:48

                at <map:generate> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:350:64

                at <map:match> - file:///C:/development/workspaces/intellij11/CTPI-PX/spider2/search/target/classes/COB-INF/sitemap.xmap:349:57

                at org.apache.cocoon.ProcessingException.throwLocated(ProcessingException.java:143)

                at org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.handleException(AbstractProcessingPipeline.java:923)

                at org.apache.cocoon.components.pipeline.impl.AbstractCachingProcessingPipeline.processXMLPipeline(AbstractCachingProcessingPipeline.java:379)

                at org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.process(AbstractProcessingPipeline.java:439)

                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

                at java.lang.reflect.Method.invoke(Method.java:597)

                at org.apache.cocoon.core.container.spring.avalon.PoolableProxyHandler.invoke(PoolableProxyHandler.java:79)

                at $Proxy40.process(Unknown Source)

                at org.apache.cocoon.components.treeprocessor.sitemap.SerializeNode.invoke(SerializeNode.java:147)

                at org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:55)

                at org.apache.cocoon.components.treeprocessor.sitemap.MatchNode.invoke(MatchNode.java:87)

                at org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:78)

                at org.apache.cocoon.components.treeprocessor.sitemap.PipelineNode.invoke(PipelineNode.java:143)

                at org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:78)

                at org.apache.cocoon.components.treeprocessor.sitemap.PipelinesNode.invoke(PipelinesNode.java:81)

                at org.apache.cocoon.components.treeprocessor.ConcreteTreeProcessor.process(ConcreteTreeProcessor.java:239)

                at org.apache.cocoon.components.treeprocessor.ConcreteTreeProcessor.process(ConcreteTreeProcessor.java:171)

                at org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:247)

                at org.apache.cocoon.servlet.RequestProcessor.process(RequestProcessor.java:351)

                at org.apache.cocoon.servlet.RequestProcessor.service(RequestProcessor.java:169)

                ... 38 more

Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.

                at org.apache.cocoon.core.xml.impl.JaxpSAXParser.fatalError(JaxpSAXParser.java:275)

                at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)

                at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)

                at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)

                at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)

                at org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)

                at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)

                at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

                at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

                at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)

                at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)

                at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)

                at org.apache.cocoon.core.xml.impl.JaxpSAXParser.parse(JaxpSAXParser.java:196)

                at org.apache.cocoon.core.xml.impl.JaxpSAXParser.parse(JaxpSAXParser.java:204)

                at org.apache.cocoon.components.source.util.SourceUtil.parse(SourceUtil.java:297)

                at org.apache.cocoon.servletservice.postable.components.ServletServiceTransformer.endDocument(ServletServiceTransformer.java:99)

                at org.apache.cocoon.components.sax.XMLTeePipe.endDocument(XMLTeePipe.java:71)

                at org.apache.xerces.parsers.AbstractSAXParser.endDocument(Unknown Source)

                at org.apache.xerces.impl.XMLDocumentScannerImpl.endEntity(Unknown Source)

                at org.apache.xerces.impl.XMLEntityManager.endEntity(Unknown Source)

                at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)

                at org.apache.xerces.impl.XMLEntityScanner.skipSpaces(Unknown Source)

                at org.apache.xerces.impl.XMLDocumentScannerImpl$TrailingMiscDispatcher.dispatch(Unknown Source)

                at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)

                at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

                at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

                at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)

                at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)

                at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)

                at org.apache.cocoon.core.xml.impl.JaxpSAXParser.parse(JaxpSAXParser.java:196)

                at org.apache.cocoon.core.xml.impl.JaxpSAXParser.parse(JaxpSAXParser.java:204)

                at org.apache.cocoon.components.source.util.SourceUtil.parse(SourceUtil.java:297)

                at org.apache.cocoon.generation.FileGenerator.generate(FileGenerator.java:136)

                at org.apache.cocoon.components.pipeline.impl.AbstractCachingProcessingPipeline.processXMLPipeline(AbstractCachingProcessingPipeline.java:360)

                ... 57 more

Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.

                at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)

                ... 90 more