cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Francesco Chicchiriccò <ilgro...@apache.org>
Subject Re: possible design flaw in linking of pipelines (C3)
Date Tue, 11 Dec 2012 11:02:23 GMT
Robby,
could you please open an issue on JIRA and attach the patch you are 
currently working on?
Maybe I could help but I need to have your exact situation.

Regards.

On 07/12/2012 16:21, Robby Pelssers wrote:
> Just for the sake of it.... You wouldn't run into this issue if you set the system property
and just left the factoryclassname null.
>
> META-INF/services/javax.xml.transform.TransformerFactory
>
> Because in that case TRAX_FACTORY will ALWAYS create a new instance using the same TransformerFactory
implementation.
>
> Robby
>
> -----Original Message-----
> From: Robby Pelssers [mailto:Robby.Pelssers@nxp.com]
> Sent: Friday, December 07, 2012 4:12 PM
> To: dev@cocoon.apache.org
> Subject: possible design flaw in linking of pipelines (C3)
>
> Hi guys,
>
> Sorry if I make unnecessary noise here due to my incompetence. But I was trying to refactor
>   
> org.apache.cocoon.sax.component.XSLTTransformer by enabling users to choose a transfomerfactory
of their choice. I added a new constructor and did some basic refactoring.
>
>      public XSLTTransformer(final URL source, final Map<String, Object> attributes,
final String factoryClassName) {
>          super();
>          this.loadXSLT(source, attributes, factoryClassName);
>      }
>
>
> private void loadXSLT(final URL source, final Map<String, Object> attributes, final
String factoryClassName) {
>      ....
>              SAXTransformerFactory transformerFactory;
>              if (factoryClassName != null) {
>                  //we need to use factoryclassname
>                  transformerFactory = createNewSAXTransformerFactory(factoryClassName,
null);
>              } else {
>                  //we need to check for attributes
>                  if (attributes == null || attributes.isEmpty()) {
>                      //we can use static factory
>                      transformerFactory = TRAX_FACTORY;
>                  } else {
>                      //we need to instantiate new default factory
>                      transformerFactory = createNewSAXTransformerFactory();
>                  }
>              }
>     ....
> }
>
>      private static SAXTransformerFactory createNewSAXTransformerFactory() {
>          return (SAXTransformerFactory) TransformerFactory.newInstance();
>      }
>
>      private static SAXTransformerFactory createNewSAXTransformerFactory(final String
factoryClassName, final ClassLoader classLoader) {
>         return (SAXTransformerFactory) TransformerFactory.newInstance(factoryClassName,
classLoader);
>      }
>
>
>
> But then I hit a brick wall while running the unit test below:
>
>      public void testPipelineWithMultipleXSLTProcessors() throws Exception {
>           newCachingPipeline()
>               .setStarter(new XMLGenerator(getClass().getResource("/movies.xml")))
>               .addComponent(new XSLTTransformer(this.getClass().getResource("/moviesByDirector.xslt"),
null, "net.sf.saxon.TransformerFactoryImpl"))
>               .addComponent(new XSLTTransformer(this.getClass().getResource("/indent.xslt"),
null, "org.apache.xalan.processor.TransformerFactoryImpl"))
>               .setFinisher(new XMLSerializer())
>               .withEmptyConfiguration()
>               .setup(System.out)
>               .execute();
>      }
>
>
> Don’t look at linenumbers as I have different code now of course (and I added saxon
as dependency to test this):
>
> org.apache.cocoon.pipeline.SetupException: Could not initialize transformer handler.
> 	at org.apache.cocoon.sax.component.XSLTTransformer.setSAXConsumer(XSLTTransformer.java:247)
> 	at org.apache.cocoon.sax.AbstractSAXProducer.setConsumer(AbstractSAXProducer.java:39)
> 	at org.apache.cocoon.pipeline.AbstractPipeline.linkComponents(AbstractPipeline.java:214)
> 	at org.apache.cocoon.pipeline.AbstractPipeline.setupComponents(AbstractPipeline.java:187)
> 	at org.apache.cocoon.pipeline.AbstractPipeline.setup(AbstractPipeline.java:132)
> 	at org.apache.cocoon.pipeline.CachingPipeline.setup(CachingPipeline.java:183)
> 	at org.apache.cocoon.pipeline.AbstractPipeline.setup(AbstractPipeline.java:118)
> 	at org.apache.cocoon.pipeline.builder.PipelineBuilder$1$1$1$1.setup(PipelineBuilder.java:122)
> 	at org.apache.cocoon.sax.PipelineTest.testPipelineWithMultipleXSLTProcessors(PipelineTest.java:83)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
> 	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
> 	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
> 	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
> 	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
> Caused by: java.lang.ClassCastException: net.sf.saxon.Controller cannot be cast to org.apache.xalan.xsltc.trax.TransformerImpl
> 	at org.apache.xalan.xsltc.trax.TransformerFactoryImpl.newTransformerHandler(TransformerFactoryImpl.java:928)
> 	at org.apache.cocoon.sax.component.XSLTTransformer.setSAXConsumer(XSLTTransformer.java:245)
> 	... 30 more
>
>
> This is probably due to
>
>      @Override
>      protected void setSAXConsumer(final SAXConsumer consumer) {
>          TransformerHandler transformerHandler;
>          try {
>              transformerHandler = TRAX_FACTORY.newTransformerHandler(this.templates);
>          } catch (Exception e) {
>              throw new SetupException("Could not initialize transformer handler.", e);
>          }
>          ...
>       }
>
> I think we shouldn’t just ALWAYS create a new transformerhandler using the default
TRAX_FACTORY but it should the same SAXTransformerFactory we created in loadXSLT.
>
> But setSAXConsumer is called from within AbstractPipeline.setConsumer which again translates
to AbstractSAXProducer.setConsumer which sets the SaxConsumer.
>
>
> mmmm....   Anyone who is expert in this matter?
>
> Robby

-- 
Francesco Chicchiriccò

ASF Member, Apache Syncope PMC chair, Apache Cocoon PMC Member
http://people.apache.org/~ilgrosso/


Mime
View raw message