You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by br...@apache.org on 2003/05/02 17:34:12 UTC

cvs commit: cocoon-2.0/src/java/org/apache/cocoon/transformation TraxTransformer.java

bruno       2003/05/02 08:34:12

  Modified:    src/java/org/apache/cocoon/transformation
                        TraxTransformer.java
  Log:
  Only call endDocument during recycle if:
   - the XSLT processor is Xalan
   - incremental processing is enabled
  This fixes bug 13186
  
  Revision  Changes    Path
  1.3       +30 -5     cocoon-2.0/src/java/org/apache/cocoon/transformation/TraxTransformer.java
  
  Index: TraxTransformer.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.0/src/java/org/apache/cocoon/transformation/TraxTransformer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TraxTransformer.java	14 Mar 2003 16:29:52 -0000	1.2
  +++ TraxTransformer.java	2 May 2003 15:34:12 -0000	1.3
  @@ -55,6 +55,7 @@
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.Map;
  +import java.lang.reflect.Method;
   
   import javax.xml.transform.sax.SAXResult;
   import javax.xml.transform.sax.TransformerHandler;
  @@ -201,6 +202,9 @@
       /** Did we finish the processing (is endDocument() called) */
       private boolean finishedDocument = false;
   
  +    /** Xalan's DTMManager.getIncremental() method. See recycle() method to see what we need this for. */
  +    private Method xalanDtmManagerGetIncrementalMethod;
  +
       /**
        * Configure this transformer.
        */
  @@ -242,6 +246,16 @@
                   throw new ConfigurationException("Cannot load XSLT processor", e);
               }
           }
  +
  +        try {
  +            // see the recyle() method to see what we need this for
  +            Class dtmManagerClass = Class.forName("org.apache.xml.dtm.DTMManager");
  +            xalanDtmManagerGetIncrementalMethod = dtmManagerClass.getMethod("getIncremental", null);
  +        } catch (ClassNotFoundException e) {
  +            // do nothing -- user does not use xalan, so we don't need the dtm manager
  +        } catch (NoSuchMethodException e) {
  +            throw new ConfigurationException("Was not able to get getIncremental method from Xalan's DTMManager.", e);
  +        }
       }
   
       /**
  @@ -540,7 +554,6 @@
           // Remove per-request resolver from the XSLT processor
           this.xsltProcessor.setSourceResolver(null);
   
  -        this.transformerHandler = null;
           this.objectModel = null;
           if (this.inputSource != null) {
             this.inputSource.recycle();
  @@ -548,11 +561,23 @@
           }
           this.par = null;
           if (this.finishedDocument == false) {
  -            try {
  -                super.endDocument();
  -            } catch (Exception ignore) {}
  +            // This situation will only occur if an exception occured during pipeline execution.
  +            // If Xalan is used in incremental mode, it is important that endDocument is called, otherwise
  +            // the thread on which it runs the transformation will keep waiting.
  +            // However, calling endDocument will cause the pipeline to continue executing, and thus the
  +            // serializer will write output to the outputstream after what's already there (the error page),
  +            // see also bug 13186.
  +            if (xalanDtmManagerGetIncrementalMethod != null
  +                    && transformerHandler.getClass().getName().equals("org.apache.xalan.transformer.TransformerHandlerImpl")) {
  +                try {
  +                    boolean incremental = ((Boolean)xalanDtmManagerGetIncrementalMethod.invoke(null, null)).booleanValue();
  +                    if (incremental)
  +                        super.endDocument();
  +                } catch (Exception ignore) {}
  +            }
           }
           this.finishedDocument = false;
  +        this.transformerHandler = null;
           super.recycle();
       }