Save This Page
Home » Open-JDK-6.b17-src » com.sun.org.apache.xalan » internal » xsltc » trax » [javadoc | source]
    1   /*
    2    * reserved comment block
    3    * DO NOT REMOVE OR ALTER!
    4    */
    5   /*
    6    * Copyright 2001-2004 The Apache Software Foundation.
    7    *
    8    * Licensed under the Apache License, Version 2.0 (the "License");
    9    * you may not use this file except in compliance with the License.
   10    * You may obtain a copy of the License at
   11    *
   12    *     http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing, software
   15    * distributed under the License is distributed on an "AS IS" BASIS,
   16    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   17    * See the License for the specific language governing permissions and
   18    * limitations under the License.
   19    */
   20   /*
   21    * $Id: TransformerImpl.java,v 1.10 2007/06/13 01:57:09 joehw Exp $
   22    */
   23   
   24   package com.sun.org.apache.xalan.internal.xsltc.trax;
   25   
   26   import java.io.File;
   27   import java.io.FileOutputStream;
   28   import java.io.IOException;
   29   import java.io.InputStream;
   30   import java.io.OutputStream;
   31   import java.io.Reader;
   32   import java.io.Writer;
   33   import java.net.URI;
   34   import java.net.URL;
   35   import java.net.URLConnection;
   36   import java.net.UnknownServiceException;
   37   import java.util.Enumeration;
   38   import java.util.Properties;
   39   import java.util.StringTokenizer;
   40   import java.util.Vector;
   41   import java.lang.reflect.Constructor;
   42   
   43   import javax.xml.parsers.DocumentBuilder;
   44   import javax.xml.parsers.DocumentBuilderFactory;
   45   import javax.xml.parsers.ParserConfigurationException;
   46   import javax.xml.stream.XMLEventReader;
   47   import javax.xml.stream.XMLStreamReader;
   48   import javax.xml.transform.ErrorListener;
   49   import javax.xml.transform.OutputKeys;
   50   import javax.xml.transform.Result;
   51   import javax.xml.transform.Source;
   52   import javax.xml.transform.Transformer;
   53   import javax.xml.transform.TransformerException;
   54   import javax.xml.transform.URIResolver;
   55   import javax.xml.transform.dom.DOMResult;
   56   import javax.xml.transform.dom.DOMSource;
   57   import javax.xml.transform.sax.SAXResult;
   58   import javax.xml.transform.sax.SAXSource;
   59   import javax.xml.transform.stax.StAXResult;
   60   import javax.xml.transform.stax.StAXSource;
   61   import javax.xml.transform.stream.StreamResult;
   62   import javax.xml.transform.stream.StreamSource;
   63   
   64   import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
   65   
   66   import com.sun.org.apache.xalan.internal.xsltc.DOM;
   67   import com.sun.org.apache.xalan.internal.xsltc.DOMCache;
   68   import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
   69   import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
   70   import com.sun.org.apache.xalan.internal.xsltc.Translet;
   71   import com.sun.org.apache.xalan.internal.xsltc.TransletException;
   72   import com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory;
   73   import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
   74   import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
   75   import com.sun.org.apache.xalan.internal.xsltc.dom.DOMWSFilter;
   76   import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
   77   import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager;
   78   import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
   79   import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
   80   import com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory;
   81   
   82   import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
   83   import com.sun.org.apache.xml.internal.utils.XMLReaderManager;
   84   
   85   import org.xml.sax.ContentHandler;
   86   import org.xml.sax.InputSource;
   87   import org.xml.sax.SAXException;
   88   import org.xml.sax.XMLReader;
   89   import org.xml.sax.ext.LexicalHandler;
   90   
   91   /**
   92    * @author Morten Jorgensen
   93    * @author G. Todd Miller
   94    * @author Santiago Pericas-Geertsen
   95    */
   96   public final class TransformerImpl extends Transformer
   97       implements DOMCache, ErrorListener
   98   {
   99       private final static String EMPTY_STRING = "";
  100       private final static String NO_STRING    = "no";
  101       private final static String YES_STRING   = "yes";
  102       private final static String XML_STRING   = "xml";
  103   
  104       private final static String LEXICAL_HANDLER_PROPERTY =
  105           "http://xml.org/sax/properties/lexical-handler";
  106       private static final String NAMESPACE_FEATURE =
  107           "http://xml.org/sax/features/namespaces";
  108   
  109       /**
  110        * Namespace prefixes feature for {@link XMLReader}.
  111        */
  112       private static final String NAMESPACE_PREFIXES_FEATURE =
  113           "http://xml.org/sax/features/namespace-prefixes";
  114   
  115       /**
  116        * A reference to the translet or null if the identity transform.
  117        */
  118       private AbstractTranslet _translet = null;
  119   
  120       /**
  121        * The output method of this transformation.
  122        */
  123       private String _method = null;
  124   
  125       /**
  126        * The output encoding of this transformation.
  127        */
  128       private String _encoding = null;
  129   
  130       /**
  131        * The systemId set in input source.
  132        */
  133       private String _sourceSystemId = null;
  134   
  135       /**
  136        * An error listener for runtime errors.
  137        */
  138       private ErrorListener _errorListener = this;
  139   
  140       /**
  141        * A reference to a URI resolver for calls to document().
  142        */
  143       private URIResolver _uriResolver = null;
  144   
  145       /**
  146        * Output properties of this transformer instance.
  147        */
  148       private Properties _properties, _propertiesClone;
  149   
  150       /**
  151        * A reference to an output handler factory.
  152        */
  153       private TransletOutputHandlerFactory _tohFactory = null;
  154   
  155       /**
  156        * A reference to a internal DOM represenation of the input.
  157        */
  158       private DOM _dom = null;
  159   
  160       /**
  161        * Number of indent spaces to add when indentation is on.
  162        */
  163       private int _indentNumber;
  164   
  165       /**
  166        * A reference to the transformer factory that this templates
  167        * object belongs to.
  168        */
  169       private TransformerFactoryImpl _tfactory = null;
  170   
  171       /**
  172        * A reference to the output stream, if we create one in our code.
  173        */
  174       private OutputStream _ostream = null;
  175   
  176       /**
  177        * A reference to the XSLTCDTMManager which is used to build the DOM/DTM
  178        * for this transformer.
  179        */
  180       private XSLTCDTMManager _dtmManager = null;
  181   
  182       /**
  183        * A reference to an object that creates and caches XMLReader objects.
  184        */
  185       private XMLReaderManager _readerManager = XMLReaderManager.getInstance();
  186   
  187       /**
  188        * A flag indicating whether we use incremental building of the DTM.
  189        */
  190       //private boolean _isIncremental = false;
  191   
  192       /**
  193        * A flag indicating whether this transformer implements the identity
  194        * transform.
  195        */
  196       private boolean _isIdentity = false;
  197   
  198       /**
  199        * State of the secure processing feature.
  200        */
  201       private boolean _isSecureProcessing = false;
  202   
  203       /**
  204        * A hashtable to store parameters for the identity transform. These
  205        * are not needed during the transformation, but we must keep track of
  206        * them to be fully complaint with the JAXP API.
  207        */
  208       private Hashtable _parameters = null;
  209   
  210       /**
  211        * This class wraps an ErrorListener into a MessageHandler in order to
  212        * capture messages reported via xsl:message.
  213        */
  214       static class MessageHandler
  215              extends com.sun.org.apache.xalan.internal.xsltc.runtime.MessageHandler
  216       {
  217           private ErrorListener _errorListener;
  218   
  219           public MessageHandler(ErrorListener errorListener) {
  220               _errorListener = errorListener;
  221           }
  222   
  223           public void displayMessage(String msg) {
  224               if(_errorListener == null) {
  225                   System.err.println(msg);
  226               }
  227               else {
  228                   try {
  229                       _errorListener.warning(new TransformerException(msg));
  230                   }
  231                   catch (TransformerException e) {
  232                       // ignored
  233                   }
  234               }
  235           }
  236       }
  237   
  238       protected TransformerImpl(Properties outputProperties, int indentNumber,
  239           TransformerFactoryImpl tfactory)
  240       {
  241           this(null, outputProperties, indentNumber, tfactory);
  242           _isIdentity = true;
  243           // _properties.put(OutputKeys.METHOD, "xml");
  244       }
  245   
  246       protected TransformerImpl(Translet translet, Properties outputProperties,
  247           int indentNumber, TransformerFactoryImpl tfactory)
  248       {
  249           _translet = (AbstractTranslet) translet;
  250           _properties = createOutputProperties(outputProperties);
  251           _propertiesClone = (Properties) _properties.clone();
  252           _indentNumber = indentNumber;
  253           _tfactory = tfactory;
  254           //_isIncremental = tfactory._incremental;
  255       }
  256   
  257       /**
  258        * Return the state of the secure processing feature.
  259        */
  260       public boolean isSecureProcessing() {
  261           return _isSecureProcessing;
  262       }
  263   
  264       /**
  265        * Set the state of the secure processing feature.
  266        */
  267       public void setSecureProcessing(boolean flag) {
  268           _isSecureProcessing = flag;
  269       }
  270   
  271       /**
  272        * Returns the translet wrapped inside this Transformer or
  273        * null if this is the identity transform.
  274        */
  275       protected AbstractTranslet getTranslet() {
  276           return _translet;
  277       }
  278   
  279       public boolean isIdentity() {
  280           return _isIdentity;
  281       }
  282   
  283       /**
  284        * Implements JAXP's Transformer.transform()
  285        *
  286        * @param source Contains the input XML document
  287        * @param result Will contain the output from the transformation
  288        * @throws TransformerException
  289        */
  290       public void transform(Source source, Result result)
  291           throws TransformerException
  292       {
  293           if (!_isIdentity) {
  294               if (_translet == null) {
  295                   ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_TRANSLET_ERR);
  296                   throw new TransformerException(err.toString());
  297               }
  298               // Pass output properties to the translet
  299               transferOutputProperties(_translet);
  300           }
  301   
  302           final SerializationHandler toHandler = getOutputHandler(result);
  303           if (toHandler == null) {
  304               ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_HANDLER_ERR);
  305               throw new TransformerException(err.toString());
  306           }
  307   
  308           if (_uriResolver != null && !_isIdentity) {
  309               _translet.setDOMCache(this);
  310           }
  311   
  312           // Pass output properties to handler if identity
  313           if (_isIdentity) {
  314               transferOutputProperties(toHandler);
  315           }
  316   
  317           transform(source, toHandler, _encoding);
  318           try{
  319               if (result instanceof DOMResult) {
  320                   ((DOMResult)result).setNode(_tohFactory.getNode());
  321               } else if (result instanceof StAXResult) {
  322                     if (((StAXResult) result).getXMLEventWriter() != null)
  323                   {
  324                       (_tohFactory.getXMLEventWriter()).flush();
  325                   }
  326                   else if (((StAXResult) result).getXMLStreamWriter() != null) {
  327                       (_tohFactory.getXMLStreamWriter()).flush();
  328                       //result = new StAXResult(_tohFactory.getXMLStreamWriter());
  329                   }
  330               }
  331           } catch (Exception e) {
  332               System.out.println("Result writing error");
  333           }
  334       }
  335   
  336       /**
  337        * Create an output handler for the transformation output based on
  338        * the type and contents of the TrAX Result object passed to the
  339        * transform() method.
  340        */
  341       public SerializationHandler getOutputHandler(Result result)
  342           throws TransformerException
  343       {
  344           // Get output method using get() to ignore defaults
  345           _method = (String) _properties.get(OutputKeys.METHOD);
  346   
  347           // Get encoding using getProperty() to use defaults
  348           _encoding = (String) _properties.getProperty(OutputKeys.ENCODING);
  349   
  350           _tohFactory = TransletOutputHandlerFactory.newInstance();
  351           _tohFactory.setEncoding(_encoding);
  352           if (_method != null) {
  353               _tohFactory.setOutputMethod(_method);
  354           }
  355   
  356           // Set indentation number in the factory
  357           if (_indentNumber >= 0) {
  358               _tohFactory.setIndentNumber(_indentNumber);
  359           }
  360   
  361           // Return the content handler for this Result object
  362           try {
  363               // Result object could be SAXResult, DOMResult, or StreamResult
  364               if (result instanceof SAXResult) {
  365                   final SAXResult target = (SAXResult)result;
  366                   final ContentHandler handler = target.getHandler();
  367   
  368                   _tohFactory.setHandler(handler);
  369   
  370                   /**
  371                    * Fix for bug 24414
  372                    * If the lexicalHandler is set then we need to get that
  373                    * for obtaining the lexical information
  374                    */
  375                   LexicalHandler lexicalHandler = target.getLexicalHandler();
  376   
  377                   if (lexicalHandler != null ) {
  378                       _tohFactory.setLexicalHandler(lexicalHandler);
  379                   }
  380   
  381                   _tohFactory.setOutputType(TransletOutputHandlerFactory.SAX);
  382                   return _tohFactory.getSerializationHandler();
  383               }
  384               else if (result instanceof StAXResult) {
  385                   if (((StAXResult) result).getXMLEventWriter() != null)
  386                       _tohFactory.setXMLEventWriter(((StAXResult) result).getXMLEventWriter());
  387                   else if (((StAXResult) result).getXMLStreamWriter() != null)
  388                       _tohFactory.setXMLStreamWriter(((StAXResult) result).getXMLStreamWriter());
  389                   _tohFactory.setOutputType(TransletOutputHandlerFactory.STAX);
  390                   return _tohFactory.getSerializationHandler();
  391               }
  392               else if (result instanceof DOMResult) {
  393                   _tohFactory.setNode(((DOMResult) result).getNode());
  394                   _tohFactory.setNextSibling(((DOMResult) result).getNextSibling());
  395                   _tohFactory.setOutputType(TransletOutputHandlerFactory.DOM);
  396                   return _tohFactory.getSerializationHandler();
  397               }
  398               else if (result instanceof StreamResult) {
  399                   // Get StreamResult
  400                   final StreamResult target = (StreamResult) result;
  401   
  402                   // StreamResult may have been created with a java.io.File,
  403                   // java.io.Writer, java.io.OutputStream or just a String
  404                   // systemId.
  405   
  406                   _tohFactory.setOutputType(TransletOutputHandlerFactory.STREAM);
  407   
  408                   // try to get a Writer from Result object
  409                   final Writer writer = target.getWriter();
  410                   if (writer != null) {
  411                       _tohFactory.setWriter(writer);
  412                       return _tohFactory.getSerializationHandler();
  413                   }
  414   
  415                   // or try to get an OutputStream from Result object
  416                   final OutputStream ostream = target.getOutputStream();
  417                   if (ostream != null) {
  418                       _tohFactory.setOutputStream(ostream);
  419                       return _tohFactory.getSerializationHandler();
  420                   }
  421   
  422                   // or try to get just a systemId string from Result object
  423                   String systemId = result.getSystemId();
  424                   if (systemId == null) {
  425                       ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_RESULT_ERR);
  426                       throw new TransformerException(err.toString());
  427                   }
  428   
  429                   // System Id may be in one of several forms, (1) a uri
  430                   // that starts with 'file:', (2) uri that starts with 'http:'
  431                   // or (3) just a filename on the local system.
  432                   URL url = null;
  433                   if (systemId.startsWith("file:")) {
  434                       // if StreamResult(File) or setSystemID(File) was used,
  435                       // the systemId will be URI encoded as a result of File.toURI(),
  436                       // it must be decoded for use by URL
  437                       try{
  438                           Class clazz =   ObjectFactory.findProviderClass("java.net.URI", ObjectFactory.findClassLoader(), true);
  439                           Constructor  construct   = clazz.getConstructor(new Class[] {java.lang.String.class} );
  440                           URI uri = (URI) construct.newInstance(new Object[]{systemId}) ;
  441                           systemId = "file:";
  442   
  443                           String host = uri.getHost(); // decoded String
  444                           String path = uri.getPath(); //decoded String
  445                           if (path == null) {
  446                            path = "";
  447                           }
  448   
  449                           // if host (URI authority) then file:// + host + path
  450                           // else just path (may be absolute or relative)
  451                           if (host != null) {
  452                            systemId += "//" + host + path;
  453                           } else {
  454                            systemId += "//" + path;
  455                           }
  456                       }
  457                       catch(ClassNotFoundException e){
  458                           // running on J2SE 1.3 which doesn't have URI Class so OK to ignore
  459                           //ClassNotFoundException.
  460                       }
  461                       catch (Exception  exception) {
  462                           // URI exception which means nothing can be done so OK to ignore
  463                       }
  464   
  465                       url = new URL(systemId);
  466                       _ostream = new FileOutputStream(url.getFile());
  467                       _tohFactory.setOutputStream(_ostream);
  468                       return _tohFactory.getSerializationHandler();
  469                   }
  470                   else if (systemId.startsWith("http:")) {
  471                       url = new URL(systemId);
  472                       final URLConnection connection = url.openConnection();
  473                       _tohFactory.setOutputStream(_ostream = connection.getOutputStream());
  474                       return _tohFactory.getSerializationHandler();
  475                   }
  476                   else {
  477                       // system id is just a filename
  478                       url = new File(systemId).toURL();
  479                       _tohFactory.setOutputStream(
  480                           _ostream = new FileOutputStream(url.getFile()));
  481                       return _tohFactory.getSerializationHandler();
  482                   }
  483               }
  484           }
  485           // If we cannot write to the location specified by the SystemId
  486           catch (UnknownServiceException e) {
  487               throw new TransformerException(e);
  488           }
  489           catch (ParserConfigurationException e) {
  490               throw new TransformerException(e);
  491           }
  492           // If we cannot create the file specified by the SystemId
  493           catch (IOException e) {
  494               throw new TransformerException(e);
  495           }
  496           return null;
  497       }
  498   
  499       /**
  500        * Set the internal DOM that will be used for the next transformation
  501        */
  502       protected void setDOM(DOM dom) {
  503           _dom = dom;
  504       }
  505   
  506       /**
  507        * Builds an internal DOM from a TrAX Source object
  508        */
  509       private DOM getDOM(Source source) throws TransformerException {
  510           try {
  511               DOM dom = null;
  512   
  513               if (source != null) {
  514                   DTMWSFilter wsfilter;
  515                   if (_translet != null && _translet instanceof StripFilter) {
  516                       wsfilter = new DOMWSFilter(_translet);
  517                    } else {
  518                       wsfilter = null;
  519                    }
  520   
  521                    boolean hasIdCall = (_translet != null) ? _translet.hasIdCall()
  522                                                            : false;
  523   
  524                    if (_dtmManager == null) {
  525                        _dtmManager =
  526                            (XSLTCDTMManager)_tfactory.getDTMManagerClass()
  527                                                      .newInstance();
  528                    }
  529                    dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true,
  530                                                 false, false, 0, hasIdCall);
  531               } else if (_dom != null) {
  532                    dom = _dom;
  533                    _dom = null;  // use only once, so reset to 'null'
  534               } else {
  535                    return null;
  536               }
  537   
  538               if (!_isIdentity) {
  539                   // Give the translet the opportunity to make a prepass of
  540                   // the document, in case it can extract useful information early
  541                   _translet.prepassDocument(dom);
  542               }
  543   
  544               return dom;
  545   
  546           }
  547           catch (Exception e) {
  548               if (_errorListener != null) {
  549                   postErrorToListener(e.getMessage());
  550               }
  551               throw new TransformerException(e);
  552           }
  553       }
  554   
  555       /**
  556        * Returns the {@link com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl}
  557        * object that create this <code>Transformer</code>.
  558        */
  559       protected TransformerFactoryImpl getTransformerFactory() {
  560           return _tfactory;
  561       }
  562   
  563       /**
  564        * Returns the {@link com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory}
  565        * object that create the <code>TransletOutputHandler</code>.
  566        */
  567       protected TransletOutputHandlerFactory getTransletOutputHandlerFactory() {
  568           return _tohFactory;
  569       }
  570   
  571       private void transformIdentity(Source source, SerializationHandler handler)
  572           throws Exception
  573       {
  574           // Get systemId from source
  575           if (source != null) {
  576               _sourceSystemId = source.getSystemId();
  577           }
  578   
  579           if (source instanceof StreamSource) {
  580               final StreamSource stream = (StreamSource) source;
  581               final InputStream streamInput = stream.getInputStream();
  582               final Reader streamReader = stream.getReader();
  583               final XMLReader reader = _readerManager.getXMLReader();
  584   
  585               try {
  586                   // Hook up reader and output handler
  587                   try {
  588                       reader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
  589                       reader.setFeature(NAMESPACE_PREFIXES_FEATURE, true);
  590                   } catch (SAXException e) {
  591                       // Falls through
  592                   }
  593                   reader.setContentHandler(handler);
  594   
  595                   // Create input source from source
  596                   InputSource input;
  597                   if (streamInput != null) {
  598                       input = new InputSource(streamInput);
  599                       input.setSystemId(_sourceSystemId);
  600                   }
  601                   else if (streamReader != null) {
  602                       input = new InputSource(streamReader);
  603                       input.setSystemId(_sourceSystemId);
  604                   }
  605                   else if (_sourceSystemId != null) {
  606                       input = new InputSource(_sourceSystemId);
  607                   }
  608                   else {
  609                       ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
  610                       throw new TransformerException(err.toString());
  611                   }
  612   
  613                   // Start pushing SAX events
  614                   reader.parse(input);
  615               } finally {
  616                   _readerManager.releaseXMLReader(reader);
  617               }
  618           } else if (source instanceof SAXSource) {
  619               final SAXSource sax = (SAXSource) source;
  620               XMLReader reader = sax.getXMLReader();
  621               final InputSource input = sax.getInputSource();
  622               boolean userReader = true;
  623   
  624               try {
  625                   // Create a reader if not set by user
  626                   if (reader == null) {
  627                       reader = _readerManager.getXMLReader();
  628                       userReader = false;
  629                   }
  630   
  631                   // Hook up reader and output handler
  632                   try {
  633                       reader.setProperty(LEXICAL_HANDLER_PROPERTY, handler);
  634                       reader.setFeature(NAMESPACE_PREFIXES_FEATURE, true);
  635                   } catch (SAXException e) {
  636                       // Falls through
  637                   }
  638                   reader.setContentHandler(handler);
  639   
  640                   // Start pushing SAX events
  641                   reader.parse(input);
  642               } finally {
  643                   if (!userReader) {
  644                       _readerManager.releaseXMLReader(reader);
  645                   }
  646               }
  647           } else if (source instanceof StAXSource) {
  648               final StAXSource staxSource = (StAXSource)source;
  649               StAXEvent2SAX staxevent2sax = null;
  650               StAXStream2SAX staxStream2SAX = null;
  651               if (staxSource.getXMLEventReader() != null) {
  652                   final XMLEventReader xmlEventReader = staxSource.getXMLEventReader();
  653                   staxevent2sax = new StAXEvent2SAX(xmlEventReader);
  654                   staxevent2sax.setContentHandler(handler);
  655                   staxevent2sax.parse();
  656                   handler.flushPending();
  657               } else if (staxSource.getXMLStreamReader() != null) {
  658                   final XMLStreamReader xmlStreamReader = staxSource.getXMLStreamReader();
  659                   staxStream2SAX = new StAXStream2SAX(xmlStreamReader);
  660                   staxStream2SAX.setContentHandler(handler);
  661                   staxStream2SAX.parse();
  662                   handler.flushPending();
  663               }
  664           } else if (source instanceof DOMSource) {
  665               final DOMSource domsrc = (DOMSource) source;
  666               new DOM2TO(domsrc.getNode(), handler).parse();
  667           } else if (source instanceof XSLTCSource) {
  668               final DOM dom = ((XSLTCSource) source).getDOM(null, _translet);
  669               ((SAXImpl)dom).copy(handler);
  670           } else {
  671               ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_SOURCE_ERR);
  672               throw new TransformerException(err.toString());
  673           }
  674       }
  675   
  676       /**
  677        * Internal transformation method - uses the internal APIs of XSLTC
  678        */
  679       private void transform(Source source, SerializationHandler handler,
  680           String encoding) throws TransformerException
  681       {
  682           try {
  683               /*
  684                * According to JAXP1.2, new SAXSource()/StreamSource()
  685                * should create an empty input tree, with a default root node.
  686                * new DOMSource()creates an empty document using DocumentBuilder.
  687                * newDocument(); Use DocumentBuilder.newDocument() for all 3
  688                * situations, since there is no clear spec. how to create
  689                * an empty tree when both SAXSource() and StreamSource() are used.
  690                */
  691               if ((source instanceof StreamSource && source.getSystemId()==null
  692                   && ((StreamSource)source).getInputStream()==null &&
  693                   ((StreamSource)source).getReader()==null)||
  694                   (source instanceof SAXSource &&
  695                   ((SAXSource)source).getInputSource()==null &&
  696                   ((SAXSource)source).getXMLReader()==null )||
  697                   (source instanceof DOMSource &&
  698                   ((DOMSource)source).getNode()==null)){
  699                           DocumentBuilderFactory builderF =
  700                                   DocumentBuilderFactory.newInstance();
  701                           DocumentBuilder builder =
  702                                   builderF.newDocumentBuilder();
  703                           String systemID = source.getSystemId();
  704                           source = new DOMSource(builder.newDocument());
  705   
  706                           // Copy system ID from original, empty Source to new
  707                           if (systemID != null) {
  708                             source.setSystemId(systemID);
  709                           }
  710               }
  711               if (_isIdentity) {
  712                   transformIdentity(source, handler);
  713               } else {
  714                   _translet.transform(getDOM(source), handler);
  715               }
  716           } catch (TransletException e) {
  717               if (_errorListener != null) postErrorToListener(e.getMessage());
  718               throw new TransformerException(e);
  719           } catch (RuntimeException e) {
  720               if (_errorListener != null) postErrorToListener(e.getMessage());
  721               throw new TransformerException(e);
  722           } catch (Exception e) {
  723               if (_errorListener != null) postErrorToListener(e.getMessage());
  724               throw new TransformerException(e);
  725           } finally {
  726               _dtmManager = null;
  727           }
  728   
  729           // If we create an output stream for the Result, we need to close it after the transformation.
  730           if (_ostream != null) {
  731               try {
  732                   _ostream.close();
  733               }
  734               catch (IOException e) {}
  735               _ostream = null;
  736           }
  737       }
  738   
  739       /**
  740        * Implements JAXP's Transformer.getErrorListener()
  741        * Get the error event handler in effect for the transformation.
  742        *
  743        * @return The error event handler currently in effect
  744        */
  745       public ErrorListener getErrorListener() {
  746           return _errorListener;
  747       }
  748   
  749       /**
  750        * Implements JAXP's Transformer.setErrorListener()
  751        * Set the error event listener in effect for the transformation.
  752        * Register a message handler in the translet in order to forward
  753        * xsl:messages to error listener.
  754        *
  755        * @param listener The error event listener to use
  756        * @throws IllegalArgumentException
  757        */
  758       public void setErrorListener(ErrorListener listener)
  759           throws IllegalArgumentException {
  760           if (listener == null) {
  761               ErrorMsg err = new ErrorMsg(ErrorMsg.ERROR_LISTENER_NULL_ERR,
  762                                           "Transformer");
  763               throw new IllegalArgumentException(err.toString());
  764           }
  765           _errorListener = listener;
  766   
  767           // Register a message handler to report xsl:messages
  768       if (_translet != null)
  769           _translet.setMessageHandler(new MessageHandler(_errorListener));
  770       }
  771   
  772       /**
  773        * Inform TrAX error listener of an error
  774        */
  775       private void postErrorToListener(String message) {
  776           try {
  777               _errorListener.error(new TransformerException(message));
  778           }
  779           catch (TransformerException e) {
  780               // ignored - transformation cannot be continued
  781           }
  782       }
  783   
  784       /**
  785        * Inform TrAX error listener of a warning
  786        */
  787       private void postWarningToListener(String message) {
  788           try {
  789               _errorListener.warning(new TransformerException(message));
  790           }
  791           catch (TransformerException e) {
  792               // ignored - transformation cannot be continued
  793           }
  794       }
  795   
  796       /**
  797        * The translet stores all CDATA sections set in the <xsl:output> element
  798        * in a Hashtable. This method will re-construct the whitespace separated
  799        * list of elements given in the <xsl:output> element.
  800        */
  801       private String makeCDATAString(Hashtable cdata) {
  802           // Return a 'null' string if no CDATA section elements were specified
  803           if (cdata == null) return null;
  804   
  805           StringBuffer result = new StringBuffer();
  806   
  807           // Get an enumeration of all the elements in the hashtable
  808           Enumeration elements = cdata.keys();
  809           if (elements.hasMoreElements()) {
  810               result.append((String)elements.nextElement());
  811               while (elements.hasMoreElements()) {
  812                   String element = (String)elements.nextElement();
  813                   result.append(' ');
  814                   result.append(element);
  815               }
  816           }
  817   
  818           return(result.toString());
  819       }
  820   
  821       /**
  822        * Implements JAXP's Transformer.getOutputProperties().
  823        * Returns a copy of the output properties for the transformation. This is
  824        * a set of layered properties. The first layer contains properties set by
  825        * calls to setOutputProperty() and setOutputProperties() on this class,
  826        * and the output settings defined in the stylesheet's <xsl:output>
  827        * element makes up the second level, while the default XSLT output
  828        * settings are returned on the third level.
  829        *
  830        * @return Properties in effect for this Transformer
  831        */
  832       public Properties getOutputProperties() {
  833           return (Properties) _properties.clone();
  834       }
  835   
  836       /**
  837        * Implements JAXP's Transformer.getOutputProperty().
  838        * Get an output property that is in effect for the transformation. The
  839        * property specified may be a property that was set with setOutputProperty,
  840        * or it may be a property specified in the stylesheet.
  841        *
  842        * @param name A non-null string that contains the name of the property
  843        * @throws IllegalArgumentException if the property name is not known
  844        */
  845       public String getOutputProperty(String name)
  846           throws IllegalArgumentException
  847       {
  848           if (!validOutputProperty(name)) {
  849               ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
  850               throw new IllegalArgumentException(err.toString());
  851           }
  852           return _properties.getProperty(name);
  853       }
  854   
  855       /**
  856        * Implements JAXP's Transformer.setOutputProperties().
  857        * Set the output properties for the transformation. These properties
  858        * will override properties set in the Templates with xsl:output.
  859        * Unrecognised properties will be quitely ignored.
  860        *
  861        * @param properties The properties to use for the Transformer
  862        * @throws IllegalArgumentException Never, errors are ignored
  863        */
  864       public void setOutputProperties(Properties properties)
  865           throws IllegalArgumentException
  866       {
  867           if (properties != null) {
  868               final Enumeration names = properties.propertyNames();
  869   
  870               while (names.hasMoreElements()) {
  871                   final String name = (String) names.nextElement();
  872   
  873                   // Ignore lower layer properties
  874                   if (isDefaultProperty(name, properties)) continue;
  875   
  876                   if (validOutputProperty(name)) {
  877                       _properties.setProperty(name, properties.getProperty(name));
  878                   }
  879                   else {
  880                       ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
  881                       throw new IllegalArgumentException(err.toString());
  882                   }
  883               }
  884           }
  885           else {
  886               _properties = _propertiesClone;
  887           }
  888       }
  889   
  890       /**
  891        * Implements JAXP's Transformer.setOutputProperty().
  892        * Get an output property that is in effect for the transformation. The
  893        * property specified may be a property that was set with
  894        * setOutputProperty(), or it may be a property specified in the stylesheet.
  895        *
  896        * @param name The name of the property to set
  897        * @param value The value to assign to the property
  898        * @throws IllegalArgumentException Never, errors are ignored
  899        */
  900       public void setOutputProperty(String name, String value)
  901           throws IllegalArgumentException
  902       {
  903           if (!validOutputProperty(name)) {
  904               ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
  905               throw new IllegalArgumentException(err.toString());
  906           }
  907           _properties.setProperty(name, value);
  908       }
  909   
  910       /**
  911        * Internal method to pass any properties to the translet prior to
  912        * initiating the transformation
  913        */
  914       private void transferOutputProperties(AbstractTranslet translet)
  915       {
  916           // Return right now if no properties are set
  917           if (_properties == null) return;
  918   
  919           // Get a list of all the defined properties
  920           Enumeration names = _properties.propertyNames();
  921           while (names.hasMoreElements()) {
  922               // Note the use of get() instead of getProperty()
  923               String name  = (String) names.nextElement();
  924               String value = (String) _properties.get(name);
  925   
  926               // Ignore default properties
  927               if (value == null) continue;
  928   
  929               // Pass property value to translet - override previous setting
  930               if (name.equals(OutputKeys.ENCODING)) {
  931                   translet._encoding = value;
  932               }
  933               else if (name.equals(OutputKeys.METHOD)) {
  934                   translet._method = value;
  935               }
  936               else if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
  937                   translet._doctypePublic = value;
  938               }
  939               else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
  940                   translet._doctypeSystem = value;
  941               }
  942               else if (name.equals(OutputKeys.MEDIA_TYPE)) {
  943                   translet._mediaType = value;
  944               }
  945               else if (name.equals(OutputKeys.STANDALONE)) {
  946                   translet._standalone = value;
  947               }
  948               else if (name.equals(OutputKeys.VERSION)) {
  949                   translet._version = value;
  950               }
  951               else if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) {
  952                   translet._omitHeader =
  953                       (value != null && value.toLowerCase().equals("yes"));
  954               }
  955               else if (name.equals(OutputKeys.INDENT)) {
  956                   translet._indent =
  957                       (value != null && value.toLowerCase().equals("yes"));
  958               }
  959               else if (name.equals(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL +"indent-amount")) {
  960                    if (value != null) {
  961                        translet._indentamount = Integer.parseInt(value);
  962                    }
  963               }
  964               else if (name.equals(OutputPropertiesFactory.S_BUILTIN_EXTENSIONS_UNIVERSAL +"indent-amount")) {
  965                    if (value != null) {
  966                        translet._indentamount = Integer.parseInt(value);
  967                    }
  968               }
  969               else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) {
  970                   if (value != null) {
  971                       translet._cdata = null; // clear previous setting
  972                       StringTokenizer e = new StringTokenizer(value);
  973                       while (e.hasMoreTokens()) {
  974                           translet.addCdataElement(e.nextToken());
  975                       }
  976                   }
  977               }
  978           }
  979       }
  980   
  981       /**
  982        * This method is used to pass any properties to the output handler
  983        * when running the identity transform.
  984        */
  985       public void transferOutputProperties(SerializationHandler handler)
  986       {
  987           // Return right now if no properties are set
  988           if (_properties == null) return;
  989   
  990           String doctypePublic = null;
  991           String doctypeSystem = null;
  992   
  993           // Get a list of all the defined properties
  994           Enumeration names = _properties.propertyNames();
  995           while (names.hasMoreElements()) {
  996               // Note the use of get() instead of getProperty()
  997               String name  = (String) names.nextElement();
  998               String value = (String) _properties.get(name);
  999   
 1000               // Ignore default properties
 1001               if (value == null) continue;
 1002   
 1003               // Pass property value to translet - override previous setting
 1004               if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
 1005                   doctypePublic = value;
 1006               }
 1007               else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
 1008                   doctypeSystem = value;
 1009               }
 1010               else if (name.equals(OutputKeys.MEDIA_TYPE)) {
 1011                   handler.setMediaType(value);
 1012               }
 1013               else if (name.equals(OutputKeys.STANDALONE)) {
 1014                   handler.setStandalone(value);
 1015               }
 1016               else if (name.equals(OutputKeys.VERSION)) {
 1017                   handler.setVersion(value);
 1018               }
 1019               else if (name.equals(OutputKeys.OMIT_XML_DECLARATION)) {
 1020                   handler.setOmitXMLDeclaration(
 1021                       value != null && value.toLowerCase().equals("yes"));
 1022               }
 1023               else if (name.equals(OutputKeys.INDENT)) {
 1024                   handler.setIndent(
 1025                       value != null && value.toLowerCase().equals("yes"));
 1026               }
 1027               else if (name.equals(OutputPropertiesFactory.S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL +"indent-amount")) {
 1028                   if (value != null) {
 1029                       handler.setIndentAmount(Integer.parseInt(value));
 1030                   }
 1031               }
 1032               else if (name.equals(OutputPropertiesFactory.S_BUILTIN_EXTENSIONS_UNIVERSAL +"indent-amount")) {
 1033                   if (value != null) {
 1034                       handler.setIndentAmount(Integer.parseInt(value));
 1035                   }
 1036               }
 1037               else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) {
 1038                   if (value != null) {
 1039                       StringTokenizer e = new StringTokenizer(value);
 1040                       Vector uriAndLocalNames = null;
 1041                       while (e.hasMoreTokens()) {
 1042                           final String token = e.nextToken();
 1043   
 1044                           // look for the last colon, as the String may be
 1045                           // something like "http://abc.com:local"
 1046                           int lastcolon = token.lastIndexOf(':');
 1047                           String uri;
 1048                           String localName;
 1049                           if (lastcolon > 0) {
 1050                               uri = token.substring(0, lastcolon);
 1051                               localName = token.substring(lastcolon+1);
 1052                           } else {
 1053                               // no colon at all, lets hope this is the
 1054                               // local name itself then
 1055                               uri = null;
 1056                               localName = token;
 1057                           }
 1058   
 1059                           if (uriAndLocalNames == null) {
 1060                               uriAndLocalNames = new Vector();
 1061                           }
 1062                           // add the uri/localName as a pair, in that order
 1063                           uriAndLocalNames.addElement(uri);
 1064                           uriAndLocalNames.addElement(localName);
 1065                       }
 1066                       handler.setCdataSectionElements(uriAndLocalNames);
 1067                   }
 1068               }
 1069           }
 1070   
 1071           // Call setDoctype() if needed
 1072           if (doctypePublic != null || doctypeSystem != null) {
 1073               handler.setDoctype(doctypeSystem, doctypePublic);
 1074           }
 1075       }
 1076   
 1077       /**
 1078        * Internal method to create the initial set of properties. There
 1079        * are two layers of properties: the default layer and the base layer.
 1080        * The latter contains properties defined in the stylesheet or by
 1081        * the user using this API.
 1082        */
 1083       private Properties createOutputProperties(Properties outputProperties) {
 1084           final Properties defaults = new Properties();
 1085           setDefaults(defaults, "xml");
 1086   
 1087           // Copy propeties set in stylesheet to base
 1088           final Properties base = new Properties(defaults);
 1089           if (outputProperties != null) {
 1090               final Enumeration names = outputProperties.propertyNames();
 1091               while (names.hasMoreElements()) {
 1092                   final String name = (String) names.nextElement();
 1093                   base.setProperty(name, outputProperties.getProperty(name));
 1094               }
 1095           }
 1096           else {
 1097               base.setProperty(OutputKeys.ENCODING, _translet._encoding);
 1098               if (_translet._method != null)
 1099                   base.setProperty(OutputKeys.METHOD, _translet._method);
 1100           }
 1101   
 1102           // Update defaults based on output method
 1103           final String method = base.getProperty(OutputKeys.METHOD);
 1104           if (method != null) {
 1105               if (method.equals("html")) {
 1106                   setDefaults(defaults,"html");
 1107               }
 1108               else if (method.equals("text")) {
 1109                   setDefaults(defaults,"text");
 1110               }
 1111           }
 1112   
 1113           return base;
 1114       }
 1115   
 1116           /**
 1117            * Internal method to get the default properties from the
 1118            * serializer factory and set them on the property object.
 1119            * @param props a java.util.Property object on which the properties are set.
 1120            * @param method The output method type, one of "xml", "text", "html" ...
 1121            */
 1122           private void setDefaults(Properties props, String method)
 1123           {
 1124                   final Properties method_props =
 1125                           OutputPropertiesFactory.getDefaultMethodProperties(method);
 1126                   {
 1127                           final Enumeration names = method_props.propertyNames();
 1128                           while (names.hasMoreElements())
 1129                           {
 1130                                   final String name = (String)names.nextElement();
 1131                                   props.setProperty(name, method_props.getProperty(name));
 1132                           }
 1133                   }
 1134           }
 1135       /**
 1136        * Verifies if a given output property name is a property defined in
 1137        * the JAXP 1.1 / TrAX spec
 1138        */
 1139       private boolean validOutputProperty(String name) {
 1140           return (name.equals(OutputKeys.ENCODING) ||
 1141                   name.equals(OutputKeys.METHOD) ||
 1142                   name.equals(OutputKeys.INDENT) ||
 1143                   name.equals(OutputKeys.DOCTYPE_PUBLIC) ||
 1144                   name.equals(OutputKeys.DOCTYPE_SYSTEM) ||
 1145                   name.equals(OutputKeys.CDATA_SECTION_ELEMENTS) ||
 1146                   name.equals(OutputKeys.MEDIA_TYPE) ||
 1147                   name.equals(OutputKeys.OMIT_XML_DECLARATION)   ||
 1148                   name.equals(OutputKeys.STANDALONE) ||
 1149                   name.equals(OutputKeys.VERSION) ||
 1150                   name.charAt(0) == '{');
 1151       }
 1152   
 1153       /**
 1154        * Checks if a given output property is default (2nd layer only)
 1155        */
 1156       private boolean isDefaultProperty(String name, Properties properties) {
 1157           return (properties.get(name) == null);
 1158       }
 1159   
 1160       /**
 1161        * Implements JAXP's Transformer.setParameter()
 1162        * Add a parameter for the transformation. The parameter is simply passed
 1163        * on to the translet - no validation is performed - so any unused
 1164        * parameters are quitely ignored by the translet.
 1165        *
 1166        * @param name The name of the parameter
 1167        * @param value The value to assign to the parameter
 1168        */
 1169       public void setParameter(String name, Object value) {
 1170   
 1171           if (value == null) {
 1172               ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_SET_PARAM_VALUE, name);
 1173               throw new IllegalArgumentException(err.toString());
 1174           }
 1175   
 1176           if (_isIdentity) {
 1177               if (_parameters == null) {
 1178                   _parameters = new Hashtable();
 1179               }
 1180               _parameters.put(name, value);
 1181           }
 1182           else {
 1183               _translet.addParameter(name, value);
 1184           }
 1185       }
 1186   
 1187       /**
 1188        * Implements JAXP's Transformer.clearParameters()
 1189        * Clear all parameters set with setParameter. Clears the translet's
 1190        * parameter stack.
 1191        */
 1192       public void clearParameters() {
 1193           if (_isIdentity && _parameters != null) {
 1194               _parameters.clear();
 1195           }
 1196           else {
 1197               _translet.clearParameters();
 1198           }
 1199       }
 1200   
 1201       /**
 1202        * Implements JAXP's Transformer.getParameter()
 1203        * Returns the value of a given parameter. Note that the translet will not
 1204        * keep values for parameters that were not defined in the stylesheet.
 1205        *
 1206        * @param name The name of the parameter
 1207        * @return An object that contains the value assigned to the parameter
 1208        */
 1209       public final Object getParameter(String name) {
 1210           if (_isIdentity) {
 1211               return (_parameters != null) ? _parameters.get(name) : null;
 1212           }
 1213           else {
 1214               return _translet.getParameter(name);
 1215           }
 1216       }
 1217   
 1218       /**
 1219        * Implements JAXP's Transformer.getURIResolver()
 1220        * Set the object currently used to resolve URIs used in document().
 1221        *
 1222        * @return  The URLResolver object currently in use
 1223        */
 1224       public URIResolver getURIResolver() {
 1225           return _uriResolver;
 1226       }
 1227   
 1228       /**
 1229        * Implements JAXP's Transformer.setURIResolver()
 1230        * Set an object that will be used to resolve URIs used in document().
 1231        *
 1232        * @param resolver The URIResolver to use in document()
 1233        */
 1234       public void setURIResolver(URIResolver resolver) {
 1235           _uriResolver = resolver;
 1236       }
 1237   
 1238       /**
 1239        * This class should only be used as a DOMCache for the translet if the
 1240        * URIResolver has been set.
 1241        *
 1242        * The method implements XSLTC's DOMCache interface, which is used to
 1243        * plug in an external document loader into a translet. This method acts
 1244        * as an adapter between TrAX's URIResolver interface and XSLTC's
 1245        * DOMCache interface. This approach is simple, but removes the
 1246        * possibility of using external document caches with XSLTC.
 1247        *
 1248        * @param baseURI The base URI used by the document call.
 1249        * @param href The href argument passed to the document function.
 1250        * @param translet A reference to the translet requesting the document
 1251        */
 1252       public DOM retrieveDocument(String baseURI, String href, Translet translet) {
 1253           try {
 1254               // Argument to document function was: document('');
 1255               if (href.length() == 0) {
 1256                   href = new String(baseURI);
 1257               }
 1258   
 1259               /*
 1260                *  Fix for bug 24188
 1261                *  Incase the _uriResolver.resolve(href,base) is null
 1262                *  try to still  retrieve the document before returning null
 1263                *  and throwing the FileNotFoundException in
 1264                *  com.sun.org.apache.xalan.internal.xsltc.dom.LoadDocument
 1265                *
 1266                */
 1267               Source resolvedSource = _uriResolver.resolve(href, baseURI);
 1268               if (resolvedSource == null)  {
 1269                   StreamSource streamSource = new StreamSource(
 1270                        SystemIDResolver.getAbsoluteURI(href, baseURI));
 1271                   return getDOM(streamSource) ;
 1272               }
 1273   
 1274               return getDOM(resolvedSource);
 1275           }
 1276           catch (TransformerException e) {
 1277               if (_errorListener != null)
 1278                   postErrorToListener("File not found: " + e.getMessage());
 1279               return(null);
 1280           }
 1281       }
 1282   
 1283       /**
 1284        * Receive notification of a recoverable error.
 1285        * The transformer must continue to provide normal parsing events after
 1286        * invoking this method. It should still be possible for the application
 1287        * to process the document through to the end.
 1288        *
 1289        * @param e The warning information encapsulated in a transformer
 1290        * exception.
 1291        * @throws TransformerException if the application chooses to discontinue
 1292        * the transformation (always does in our case).
 1293        */
 1294       public void error(TransformerException e)
 1295           throws TransformerException
 1296       {
 1297           Throwable wrapped = e.getException();
 1298           if (wrapped != null) {
 1299               System.err.println(new ErrorMsg(ErrorMsg.ERROR_PLUS_WRAPPED_MSG,
 1300                                               e.getMessageAndLocation(),
 1301                                               wrapped.getMessage()));
 1302           } else {
 1303               System.err.println(new ErrorMsg(ErrorMsg.ERROR_MSG,
 1304                                               e.getMessageAndLocation()));
 1305           }
 1306           throw e;
 1307       }
 1308   
 1309       /**
 1310        * Receive notification of a non-recoverable error.
 1311        * The application must assume that the transformation cannot continue
 1312        * after the Transformer has invoked this method, and should continue
 1313        * (if at all) only to collect addition error messages. In fact,
 1314        * Transformers are free to stop reporting events once this method has
 1315        * been invoked.
 1316        *
 1317        * @param e The warning information encapsulated in a transformer
 1318        * exception.
 1319        * @throws TransformerException if the application chooses to discontinue
 1320        * the transformation (always does in our case).
 1321        */
 1322       public void fatalError(TransformerException e)
 1323           throws TransformerException
 1324       {
 1325           Throwable wrapped = e.getException();
 1326           if (wrapped != null) {
 1327               System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_PLUS_WRAPPED_MSG,
 1328                                               e.getMessageAndLocation(),
 1329                                               wrapped.getMessage()));
 1330           } else {
 1331               System.err.println(new ErrorMsg(ErrorMsg.FATAL_ERR_MSG,
 1332                                               e.getMessageAndLocation()));
 1333           }
 1334           throw e;
 1335       }
 1336   
 1337       /**
 1338        * Receive notification of a warning.
 1339        * Transformers can use this method to report conditions that are not
 1340        * errors or fatal errors. The default behaviour is to take no action.
 1341        * After invoking this method, the Transformer must continue with the
 1342        * transformation. It should still be possible for the application to
 1343        * process the document through to the end.
 1344        *
 1345        * @param e The warning information encapsulated in a transformer
 1346        * exception.
 1347        * @throws TransformerException if the application chooses to discontinue
 1348        * the transformation (never does in our case).
 1349        */
 1350       public void warning(TransformerException e)
 1351           throws TransformerException
 1352       {
 1353           Throwable wrapped = e.getException();
 1354           if (wrapped != null) {
 1355               System.err.println(new ErrorMsg(ErrorMsg.WARNING_PLUS_WRAPPED_MSG,
 1356                                               e.getMessageAndLocation(),
 1357                                               wrapped.getMessage()));
 1358           } else {
 1359               System.err.println(new ErrorMsg(ErrorMsg.WARNING_MSG,
 1360                                               e.getMessageAndLocation()));
 1361           }
 1362       }
 1363   
 1364       /**
 1365        * This method resets  the Transformer to its original configuration
 1366        * Transformer code is reset to the same state it was when it was
 1367        * created
 1368        * @since 1.5
 1369        */
 1370       public void reset() {
 1371   
 1372           _method = null;
 1373           _encoding = null;
 1374           _sourceSystemId = null;
 1375           _errorListener = this;
 1376           _uriResolver = null;
 1377           _dom = null;
 1378           _parameters = null;
 1379           _indentNumber = 0;
 1380           setOutputProperties (null);
 1381   
 1382       }
 1383   }

Save This Page
Home » Open-JDK-6.b17-src » com.sun.org.apache.xalan » internal » xsltc » trax » [javadoc | source]