Save This Page
Home » cocoon-2.1.11-src » org.apache » cocoon » transformation » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.cocoon.transformation;
   19   
   20   import java.io.IOException;
   21   import java.io.Serializable;
   22   import java.lang.reflect.Method;
   23   import java.util.Enumeration;
   24   import java.util.HashMap;
   25   import java.util.Iterator;
   26   import java.util.Map;
   27   import java.util.Set;
   28   import java.util.Map.Entry;
   29   
   30   import javax.xml.transform.sax.SAXResult;
   31   import javax.xml.transform.sax.TransformerHandler;
   32   
   33   import org.apache.avalon.framework.activity.Disposable;
   34   import org.apache.avalon.framework.configuration.Configurable;
   35   import org.apache.avalon.framework.configuration.Configuration;
   36   import org.apache.avalon.framework.configuration.ConfigurationException;
   37   import org.apache.avalon.framework.logger.LogEnabled;
   38   import org.apache.avalon.framework.parameters.Parameters;
   39   import org.apache.avalon.framework.service.ServiceException;
   40   import org.apache.avalon.framework.service.ServiceManager;
   41   import org.apache.avalon.framework.service.Serviceable;
   42   import org.apache.cocoon.ProcessingException;
   43   import org.apache.cocoon.caching.CacheableProcessingComponent;
   44   import org.apache.cocoon.components.source.SourceUtil;
   45   import org.apache.cocoon.components.xslt.TraxErrorListener;
   46   import org.apache.cocoon.environment.Cookie;
   47   import org.apache.cocoon.environment.ObjectModelHelper;
   48   import org.apache.cocoon.environment.Request;
   49   import org.apache.cocoon.environment.Session;
   50   import org.apache.cocoon.environment.SourceResolver;
   51   import org.apache.cocoon.xml.XMLConsumer;
   52   import org.apache.commons.lang.BooleanUtils;
   53   import org.apache.commons.lang.exception.NestableRuntimeException;
   54   import org.apache.excalibur.source.Source;
   55   import org.apache.excalibur.source.SourceException;
   56   import org.apache.excalibur.source.SourceValidity;
   57   import org.apache.excalibur.xml.xslt.XSLTProcessor;
   58   import org.apache.excalibur.xml.xslt.XSLTProcessorException;
   59   import org.xml.sax.SAXException;
   60   
   61   /**
   62    * @cocoon.sitemap.component.documentation
   63    * The stylesheet processor
   64    *
   65    * @cocoon.sitemap.component.name   xslt
   66    * @cocoon.sitemap.component.logger sitemap.transformer.xslt
   67    * @cocoon.sitemap.component.documentation.caching
   68    *               Uses the last modification date of the xslt document for validation
   69    *
   70    * @cocoon.sitemap.component.pooling.max  32
   71    * <p>
   72    * This Transformer is used to transform the incoming SAX stream using
   73    * a TrAXProcessor. Use the following sitemap declarations to define, configure
   74    * and parameterize it:
   75    * </p>
   76    * <b>In the map:sitemap/map:components/map:transformers:</b><br>
   77    * <pre>
   78    * &lt;map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer"&gt;<br>
   79    *   &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
   80    *   &lt;use-browser-capabilities-db&gt;false&lt;/use-browser-capabilities-db&gt;
   81    *   &lt;use-session-info&gt;false&lt;/use-session-info&gt;
   82    *   &lt;xslt-processor-role&gt;xslt&lt;/xslt-processor-role&gt;
   83    *   &lt;transformer-factory&gt;org.apache.xalan.processor.TransformerFactoryImpl&lt;/transformer-factory&gt;
   84    *   &lt;check-includes&gt;true&lt;/check-includes&gt;
   85    * &lt;/map:transformer&gt;
   86    * </pre>
   87    *
   88    * The &lt;use-request-parameter&gt; configuration forces the transformer to make all
   89    * request parameters available in the XSLT stylesheet. Note that this has
   90    * implications for caching of the generated output of this transformer.<br>
   91    * This property is false by default.
   92    * <p>
   93    * The &lt;use-cookies&gt; configuration forces the transformer to make all
   94    * cookies from the request available in the XSLT stylesheets.
   95    * Note that this has implications for caching of the generated output of this
   96    * transformer.<br>
   97    * This property is false by default.
   98    * <p>
   99    * The &lt;use-session-info&gt; configuration forces the transformer to make all
  100    * of the session information available in the XSLT stylesheetas.<br>
  101    * These infos are (boolean values are "true" or "false" strings: session-is-new,
  102    * session-id-from-cookie, session-id-from-url, session-valid, session-id.<br>
  103    * This property is false by default.
  104    *
  105    * <p>Note that this has implications for caching of the generated output of
  106    * this transformer.<br>
  107    *
  108    *
  109    * The &lt;xslt-processor-role&gt; configuration allows to specify the TrAX processor (defined in
  110    * the cocoon.xconf) that will be used to obtain the XSLT processor. This allows to have
  111    * several XSLT processors in the configuration (e.g. Xalan, XSLTC, Saxon, ...) and choose
  112    * one or the other depending on the needs of stylesheet specificities.<br>
  113    * If no processor is specified, this transformer will use the XSLT implementation
  114    * that Cocoon uses internally.
  115    *
  116    * The &lt;transformer-factory&gt; configuration allows to specify the TrAX transformer factory
  117    * implementation that will be used to obtain the XSLT processor. This is only useful for
  118    * compatibility reasons. Please configure the XSLT processor in the cocoon.xconf properly
  119    * and use the xslt-processor-role configuration mentioned above.
  120    *
  121    * The &lt;check-includes&gt; configuration specifies if the included stylesheets are
  122    * also checked for changes during caching. If this is set to true (default), the
  123    * included stylesheets are also checked for changes; if this is set to false, only
  124    * the main stylesheet is checked. Setting this to false improves the performance,
  125    * and should be used whenever no includes are in the stylesheet. However, if
  126    * you have includes, you have to be careful when changing included stylesheets
  127    * as the changes might not take effect immediately. You should touch the main
  128    * stylesheet as well.
  129    *
  130    * <p>
  131    * <b>In a map:sitemap/map:pipelines/map:pipeline:</b><br>
  132    * <pre>
  133    * &lt;map:transform type="xslt" src="stylesheets/yours.xsl"&gt;<br>
  134    *   &lt;parameter name="myparam" value="myvalue"/&gt;
  135    * &lt;/map:transform&gt;
  136    * </pre>
  137    * All &lt;parameter&gt; declarations will be made available in the XSLT stylesheet as
  138    * xsl:variables.
  139    *
  140    * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
  141    * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
  142    * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
  143    * @author <a href="mailto:giacomo@apache.org">Giacomo Pati</a>
  144    * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
  145    * @author <a href="mailto:marbut@hplb.hpl.hp.com">Mark H. Butler</a>
  146    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
  147    *
  148    * @version SVN $Id: TraxTransformer.java 433543 2006-08-22 06:22:54Z crossley $
  149    */
  150   public class TraxTransformer extends AbstractTransformer
  151   implements Serviceable, Configurable, CacheableProcessingComponent, Disposable {
  152   
  153       /** The service manager instance (protected because used by subclasses) */
  154       protected ServiceManager manager;
  155   
  156       /** The object model (protected because used by subclasses) */
  157       protected Map objectModel;
  158   
  159       /** Logicsheet parameters (protected because used by subclasses) */
  160       protected Map logicSheetParameters;
  161   
  162       /** Should we make the request parameters available in the stylesheet? (default is off) */
  163       private boolean useParameters = false;
  164       private boolean _useParameters = false;
  165   
  166       /** Should we make the cookies available in the stylesheet? (default is off) */
  167       private boolean useCookies = false;
  168       private boolean _useCookies = false;
  169   
  170       /** Should we info about the session available in the stylesheet? (default is off) */
  171       private boolean useSessionInfo = false;
  172       private boolean _useSessionInfo = false;
  173   
  174       /** Do we check included stylesheets for changes? */
  175       private boolean checkIncludes = true;
  176   
  177       /** The trax TransformerHandler */
  178       protected TransformerHandler transformerHandler;
  179   
  180       /** The validity of the Transformer */
  181       protected SourceValidity transformerValidity;
  182   
  183       /** The Source */
  184       private Source inputSource;
  185       /** The parameters */
  186       private Parameters par;
  187       /** The source resolver */
  188       private SourceResolver resolver;
  189   
  190       /** Default source, used to create specialized transformers by configuration */
  191       private String defaultSrc;
  192   
  193       /** The XSLTProcessor */
  194       private XSLTProcessor xsltProcessor;
  195   
  196       /** Did we finish the processing (is endDocument() called) */
  197       private boolean finishedDocument = false;
  198   
  199       /** Xalan's DTMManager.getIncremental() method. See recycle() method to see what we need this for. */
  200       private Method xalanDtmManagerGetIncrementalMethod;
  201   
  202       /** Exception that might occur during setConsumer */
  203       private SAXException exceptionDuringSetConsumer;
  204   
  205       /** The error listener used by the stylesheet */
  206       private TraxErrorListener errorListener;
  207   
  208       /**
  209        * Configure this transformer.
  210        */
  211       public void configure(Configuration conf)
  212       throws ConfigurationException {
  213           Configuration child;
  214   
  215           child = conf.getChild("use-request-parameters");
  216           this.useParameters = child.getValueAsBoolean(false);
  217           this._useParameters = this.useParameters;
  218   
  219           child = conf.getChild("use-cookies");
  220           this.useCookies = child.getValueAsBoolean(false);
  221           this._useCookies = this.useCookies;
  222   
  223           child = conf.getChild("use-session-info");
  224           this.useSessionInfo = child.getValueAsBoolean(false);
  225           this._useSessionInfo = this.useSessionInfo;
  226   
  227           child = conf.getChild("transformer-factory");
  228           // traxFactory is null, if transformer-factory config is unspecified
  229           final String traxFactory = child.getValue(null);
  230   
  231           child = conf.getChild("xslt-processor-role");
  232           String xsltProcessorRole = child.getValue(XSLTProcessor.ROLE);
  233           if (!xsltProcessorRole.startsWith(XSLTProcessor.ROLE)) {
  234               xsltProcessorRole = XSLTProcessor.ROLE + '/' + xsltProcessorRole;
  235           }
  236   
  237           child = conf.getChild("check-includes");
  238           this.checkIncludes = child.getValueAsBoolean(this.checkIncludes);
  239   
  240           child = conf.getChild("default-src",false);
  241           if(child!=null) {
  242               this.defaultSrc = child.getValue();
  243           }
  244   
  245           if (getLogger().isDebugEnabled()) {
  246               getLogger().debug("Use parameters is " + this.useParameters);
  247               getLogger().debug("Use cookies is " + this.useCookies);
  248               getLogger().debug("Use session info is " + this.useSessionInfo);
  249               getLogger().debug("Use TrAX Processor " + xsltProcessorRole);
  250               getLogger().debug("Check for included stylesheets is " + this.checkIncludes);
  251               if (traxFactory != null) {
  252                   getLogger().debug("Use TrAX Transformer Factory " + traxFactory);
  253               } else {
  254                   getLogger().debug("Use default TrAX Transformer Factory.");
  255               }
  256               getLogger().debug("Default source = " + this.defaultSrc);
  257           }
  258   
  259           try {
  260               this.xsltProcessor = (XSLTProcessor) this.manager.lookup(xsltProcessorRole);
  261               if (traxFactory != null) {
  262                   this.xsltProcessor.setTransformerFactory(traxFactory);
  263               }
  264           } catch (ServiceException e) {
  265               throw new ConfigurationException("Cannot load XSLT processor", e);
  266           }
  267   
  268           try {
  269               // see the recyle() method to see what we need this for
  270               Class dtmManagerClass = Class.forName("org.apache.xml.dtm.DTMManager");
  271               xalanDtmManagerGetIncrementalMethod = dtmManagerClass.getMethod("getIncremental", null);
  272           } catch (ClassNotFoundException e) {
  273               // do nothing -- user does not use xalan, so we don't need the dtm manager
  274           } catch (NoSuchMethodException e) {
  275               throw new ConfigurationException("Was not able to get getIncremental method from Xalan's DTMManager.", e);
  276           }
  277       }
  278   
  279       /**
  280        * Set the current <code>ServiceManager</code> instance used by this
  281        * <code>Serviceable</code>.
  282        */
  283       public void service(ServiceManager manager) throws ServiceException {
  284           this.manager = manager;
  285       }
  286   
  287       /**
  288        * Set the <code>SourceResolver</code>, the <code>Map</code> with
  289        * the object model, the source and sitemap
  290        * <code>Parameters</code> used to process the request.
  291        */
  292       public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
  293       throws SAXException, ProcessingException, IOException {
  294   
  295           if(src==null && defaultSrc!=null) {
  296               if(getLogger().isDebugEnabled()) {
  297                   getLogger().debug("src is null, using default source " + defaultSrc);
  298               }
  299               src = defaultSrc;
  300           }
  301   
  302           if (src == null) {
  303               throw new ProcessingException("Stylesheet URI can't be null");
  304           }
  305   
  306           this.par = par;
  307           this.objectModel = objectModel;
  308           this.resolver = resolver;
  309           try {
  310               this.inputSource = resolver.resolveURI(src);
  311           } catch (SourceException se) {
  312               throw SourceUtil.handle("Unable to resolve " + src, se);
  313           }
  314           _useParameters = par.getParameterAsBoolean("use-request-parameters", this.useParameters);
  315           _useCookies = par.getParameterAsBoolean("use-cookies", this.useCookies);
  316           _useSessionInfo = par.getParameterAsBoolean("use-session-info", this.useSessionInfo);
  317           final boolean _checkIncludes = par.getParameterAsBoolean("check-includes", this.checkIncludes);
  318   
  319           if (getLogger().isDebugEnabled()) {
  320               getLogger().debug("Using stylesheet: '" + this.inputSource.getURI() + "' in " + this);
  321               getLogger().debug("Use parameters is " + this._useParameters);
  322               getLogger().debug("Use cookies is " + this._useCookies);
  323               getLogger().debug("Use session info is " + this._useSessionInfo);
  324               getLogger().debug("Check for included stylesheets is " + _checkIncludes);
  325           }
  326   
  327           // Get a Transformer Handler if we check for includes
  328           // If we don't check the handler is get during setConsumer()
  329           try {
  330               if ( _checkIncludes ) {
  331                   XSLTProcessor.TransformerHandlerAndValidity handlerAndValidity =
  332                           this.xsltProcessor.getTransformerHandlerAndValidity(this.inputSource, null);
  333                   this.transformerHandler = handlerAndValidity.getTransfomerHandler();
  334                   this.transformerValidity = handlerAndValidity.getTransfomerValidity();
  335               } else {
  336                   this.transformerValidity = this.inputSource.getValidity();
  337               }
  338           } catch (XSLTProcessorException se) {
  339               throw new ProcessingException("Unable to get transformer handler for " + this.inputSource.getURI(), se);
  340           }
  341       }
  342   
  343       /**
  344        * Generate the unique key.
  345        * This key must be unique inside the space of this component.
  346        *
  347        * @return The generated key hashes the src
  348        */
  349       public Serializable getKey() {
  350           Map map = getLogicSheetParameters();
  351           if (map == null) {
  352               return this.inputSource.getURI();
  353           }
  354   
  355           StringBuffer sb = new StringBuffer();
  356           sb.append(this.inputSource.getURI());
  357           Set entries = map.entrySet();
  358           for(Iterator i=entries.iterator(); i.hasNext();){
  359               sb.append(';');
  360               Map.Entry entry = (Map.Entry)i.next();
  361               sb.append(entry.getKey());
  362               sb.append('=');
  363               sb.append(entry.getValue());
  364           }
  365           return sb.toString();
  366       }
  367   
  368       /**
  369        * Generate the validity object.
  370        *
  371        * @return The generated validity object or <code>null</code> if the
  372        *         component is currently not cacheable.
  373        */
  374       public SourceValidity getValidity() {
  375           //
  376           // VG: Key is generated using parameter/value pairs,
  377           // so this information does not need to be verified again
  378           // (if parameter added/removed or value changed, key should
  379           // change also), only stylesheet's validity is included.
  380           //
  381           return this.transformerValidity;
  382       }
  383   
  384       /**
  385        * Set the <code>XMLConsumer</code> that will receive XML data.
  386        */
  387       public void setConsumer(XMLConsumer consumer) {
  388   
  389           if ( this.transformerHandler == null ) {
  390               try {
  391                   this.transformerHandler = this.xsltProcessor.getTransformerHandler(this.inputSource);
  392               } catch (XSLTProcessorException se) {
  393                   // the exception will be thrown during startDocument()
  394                   this.exceptionDuringSetConsumer =
  395                      new SAXException("Unable to get transformer handler for " + this.inputSource.getURI(), se);
  396                   return;
  397               }
  398           }
  399           final Map map = getLogicSheetParameters();
  400           if (map != null) {
  401               final javax.xml.transform.Transformer transformer = this.transformerHandler.getTransformer();
  402               final Iterator iterator = map.entrySet().iterator();
  403               while (iterator.hasNext()) {
  404                   final Map.Entry entry = (Entry) iterator.next();
  405                   transformer.setParameter((String)entry.getKey(), entry.getValue());
  406               }
  407           }
  408   
  409           super.setContentHandler(this.transformerHandler);
  410           super.setLexicalHandler(this.transformerHandler);
  411   
  412           if (this.transformerHandler instanceof LogEnabled) {
  413           	((LogEnabled)this.transformerHandler).enableLogging(getLogger());
  414           }
  415           // According to TrAX specs, all TransformerHandlers are LexicalHandlers
  416           final SAXResult result = new SAXResult(consumer);
  417           result.setLexicalHandler(consumer);
  418           this.transformerHandler.setResult(result);
  419   
  420           this.errorListener = new TraxErrorListener(getLogger(), this.inputSource.getURI());
  421           this.transformerHandler.getTransformer().setErrorListener(this.errorListener);
  422       }
  423   
  424       /**
  425        * Get the parameters for the logicsheet
  426        */
  427       protected Map getLogicSheetParameters() {
  428           if (this.logicSheetParameters != null) {
  429               return this.logicSheetParameters;
  430           }
  431           HashMap map = null;
  432           if (par != null) {
  433               String[] params = par.getNames();
  434               if (params != null) {
  435                   for(int i = 0; i < params.length; i++) {
  436                       String name = params[i];
  437                       if (isValidXSLTParameterName(name)) {
  438                           String value = par.getParameter(name,null);
  439                           if (value != null) {
  440                               if (map == null) {
  441                                   map = new HashMap(params.length);
  442                               }
  443                               map.put(name,value);
  444                           }
  445                       }
  446                   }
  447               }
  448           }
  449   
  450           if (this._useParameters) {
  451               Request request = ObjectModelHelper.getRequest(objectModel);
  452   
  453               Enumeration parameters = request.getParameterNames();
  454               if (parameters != null) {
  455                   while (parameters.hasMoreElements()) {
  456                       String name = (String) parameters.nextElement();
  457                       if (isValidXSLTParameterName(name)) {
  458                           String value = request.getParameter(name);
  459                           if (map == null) {
  460                               map = new HashMap();
  461                           }
  462                           map.put(name,value);
  463                       }
  464                   }
  465               }
  466           }
  467   
  468           if (this._useSessionInfo) {
  469               final Request request = ObjectModelHelper.getRequest(objectModel);
  470               if (map == null) {
  471                   map = new HashMap(6);
  472               }
  473   
  474               final Session session = request.getSession(false);
  475               if (session != null) {
  476                   map.put("session-available", "true");
  477                   map.put("session-is-new", BooleanUtils.toStringTrueFalse(session.isNew()));
  478                   map.put("session-id-from-cookie", BooleanUtils.toStringTrueFalse(request.isRequestedSessionIdFromCookie()));
  479                   map.put("session-id-from-url", BooleanUtils.toStringTrueFalse(request.isRequestedSessionIdFromURL()));
  480                   map.put("session-valid", BooleanUtils.toStringTrueFalse(request.isRequestedSessionIdValid()));
  481                   map.put("session-id", session.getId());
  482               } else {
  483                   map.put("session-available", "false");
  484               }
  485           }
  486   
  487           if (this._useCookies) {
  488               Request request = ObjectModelHelper.getRequest(objectModel);
  489               Cookie cookies[] = request.getCookies();
  490               if (cookies != null) {
  491                   for (int i = 0; i < cookies.length; i++) {
  492                       String name = cookies[i].getName();
  493                       if (isValidXSLTParameterName(name)) {
  494                           String value = cookies[i].getValue();
  495                           if (map == null) {
  496                               map = new HashMap(cookies.length);
  497                           }
  498                           map.put(name,value);
  499                       }
  500                   }
  501               }
  502           }
  503           this.logicSheetParameters = map;
  504           return this.logicSheetParameters;
  505       }
  506   
  507       /**
  508        * Test if the name is a valid parameter name for XSLT
  509        */
  510       static boolean isValidXSLTParameterName(String name) {
  511           if (name.length() == 0) {
  512               return false;
  513           }
  514   
  515           char c = name.charAt(0);
  516           if (!(Character.isLetter(c) || c == '_')) {
  517               return false;
  518           }
  519   
  520           for (int i = name.length()-1; i > 1; i--) {
  521               c = name.charAt(i);
  522               if (!(Character.isLetterOrDigit(c) ||
  523                       c == '-' ||
  524                       c == '_' ||
  525                       c == '.')) {
  526                   return false;
  527               }
  528           }
  529           return true;
  530       }
  531   
  532       /**
  533        * Disposable
  534        */
  535       public void dispose() {
  536           if ( this.manager != null ) {
  537               this.manager.release(this.xsltProcessor);
  538               this.xsltProcessor = null;
  539               this.manager = null;
  540           }
  541       }
  542   
  543       /**
  544        * Recyclable
  545        */
  546       public void recycle() {
  547           this.objectModel = null;
  548           if (this.inputSource != null) {
  549               this.resolver.release(this.inputSource);
  550               this.inputSource = null;
  551           }
  552           this.resolver = null;
  553           this.par = null;
  554           if (!this.finishedDocument && transformerHandler != null) {
  555               // This situation will only occur if an exception occured during pipeline execution.
  556               // If Xalan is used in incremental mode, it is important that endDocument is called, otherwise
  557               // the thread on which it runs the transformation will keep waiting.
  558               // However, calling endDocument will cause the pipeline to continue executing, and thus the
  559               // serializer will write output to the outputstream after what's already there (the error page),
  560               // see also bug 13186.
  561               if (xalanDtmManagerGetIncrementalMethod != null
  562                   && transformerHandler.getClass().getName().equals("org.apache.xalan.transformer.TransformerHandlerImpl")) {
  563                   try {
  564                       final boolean incremental = ((Boolean)xalanDtmManagerGetIncrementalMethod.invoke(null, null)).booleanValue();
  565                       if (incremental) {
  566                           super.endDocument();
  567                       }
  568                   } catch (Exception ignore) {}
  569               }
  570           }
  571           this.finishedDocument = true;
  572           this.logicSheetParameters = null;
  573           this.transformerHandler = null;
  574           this.transformerValidity = null;
  575           this.exceptionDuringSetConsumer = null;
  576           this.errorListener = null;
  577           super.recycle();
  578       }
  579   
  580       /**
  581        * Fix for stopping hanging threads of Xalan
  582        */
  583       public void endDocument()
  584       throws SAXException {
  585           try {
  586               super.endDocument();
  587           } catch(Exception e) {
  588               
  589               Throwable realEx = this.errorListener.getThrowable();
  590               if (realEx == null) realEx = e;
  591               
  592               if (realEx instanceof RuntimeException) {
  593                   throw (RuntimeException)realEx;
  594               }
  595               
  596               if (realEx instanceof SAXException) {
  597                   throw (SAXException)realEx;
  598               }
  599               
  600               if (realEx instanceof Error) {
  601                   throw (Error)realEx;
  602               }
  603               
  604               throw new NestableRuntimeException(realEx);
  605           }
  606           this.finishedDocument = true;
  607       }
  608   
  609       /* (non-Javadoc)
  610        * @see org.xml.sax.ContentHandler#startDocument()
  611        */
  612       public void startDocument() throws SAXException {
  613           // did an exception occur during setConsumer?
  614           // if so, throw it here
  615           if ( this.exceptionDuringSetConsumer != null ) {
  616               throw this.exceptionDuringSetConsumer;
  617           }
  618           this.finishedDocument = false;
  619           super.startDocument();
  620       }
  621   }

Save This Page
Home » cocoon-2.1.11-src » org.apache » cocoon » transformation » [javadoc | source]