14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/*
24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file
44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information
54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file
64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License.
84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at
94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *
104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *
124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software
134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and
164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License.
174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/*
194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: TransformerFactoryImpl.java 468640 2006-10-28 06:53:53Z minchau $
204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xalan.processor;
224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.io.BufferedInputStream;
244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.io.IOException;
254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.io.InputStream;
264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.util.Enumeration;
274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.util.Properties;
284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.XMLConstants;
304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.ErrorListener;
314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.Source;
324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.Templates;
334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.Transformer;
344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.TransformerConfigurationException;
354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.TransformerException;
364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.URIResolver;
374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.dom.DOMResult;
384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.dom.DOMSource;
394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.sax.SAXResult;
404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.sax.SAXSource;
414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.sax.SAXTransformerFactory;
424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.sax.TemplatesHandler;
434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.sax.TransformerHandler;
444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.stream.StreamResult;
454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.stream.StreamSource;
464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.res.XSLMessages;
484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources;
494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.TrAXFilter;
504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.TransformerIdentityImpl;
514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.TransformerImpl;
524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.XalanProperties;
534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;
554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.DefaultErrorHandler;
564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.SystemIDResolver;
574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.TreeWalker;
584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.StylesheetPIHandler;
594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.StopParseException;
604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.Node;
624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.InputSource;
644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.XMLFilter;
654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.XMLReader;
664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.helpers.XMLReaderFactory;
674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/**
694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * The TransformerFactoryImpl, which implements the TRaX TransformerFactory
704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * interface, processes XSLT stylesheets into a Templates object
714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * (a StylesheetRoot).
724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class TransformerFactoryImpl extends SAXTransformerFactory
744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{
754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * The path/filename of the property file: XSLTInfo.properties
774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Maintenance note: see also
784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <code>org.apache.xpath.functions.FuncSystemProperty.XSLT_PROPERTIES</code>
794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public static final String XSLT_PROPERTIES =
814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    "org/apache/xalan/res/XSLTInfo.properties";
824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <p>State of secure processing feature.</p>
854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private boolean m_isSecureProcessing = false;
874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Constructor TransformerFactoryImpl
904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public TransformerFactoryImpl()
934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** Static string to be used for incremental feature */
974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public static final String FEATURE_INCREMENTAL =
984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                             "http://xml.apache.org/xalan/features/incremental";
994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** Static string to be used for optimize feature */
1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public static final String FEATURE_OPTIMIZE =
1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                             "http://xml.apache.org/xalan/features/optimize";
1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** Static string to be used for source_location feature */
1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public static final String FEATURE_SOURCE_LOCATION =
1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                             XalanProperties.SOURCE_LOCATION;
1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public javax.xml.transform.Templates processFromNode(Node node)
1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try
1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      TemplatesHandler builder = newTemplatesHandler();
1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      TreeWalker walker = new TreeWalker(builder,
1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                                         new org.apache.xml.utils.DOM2Helper(),
1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                                         builder.getSystemId());
1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      walker.traverse(node);
1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return builder.getTemplates();
1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (org.xml.sax.SAXException se)
1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (m_errorListener != null)
1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError(new TransformerException(se));
1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerConfigurationException ex)
1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex;
1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerException ex)
1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException(ex);
1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        return null;
1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Should remove this later... but right now diagnostics from
1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // TransformerConfigurationException are not good.
1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // se.printStackTrace();
1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new TransformerConfigurationException(XSLMessages.createMessage(XSLTErrorResources.ER_PROCESSFROMNODE_FAILED, null), se);
1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        //"processFromNode failed", se);
1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (TransformerConfigurationException tce)
1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // Assume it's already been reported to the error listener.
1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw tce;
1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   /* catch (TransformerException tce)
1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // Assume it's already been reported to the error listener.
1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new TransformerConfigurationException(tce.getMessage(), tce);
1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }*/
1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (Exception e)
1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (m_errorListener != null)
1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError(new TransformerException(e));
1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerConfigurationException ex)
1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex;
1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerException ex)
1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException(ex);
1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        return null;
1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Should remove this later... but right now diagnostics from
1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // TransformerConfigurationException are not good.
1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // se.printStackTrace();
1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new TransformerConfigurationException(XSLMessages.createMessage(XSLTErrorResources.ER_PROCESSFROMNODE_FAILED, null), e); //"processFromNode failed",
1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                                                    //e);
1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * The systemID that was specified in
1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * processFromNode(Node node, String systemID).
1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private String m_DOMsystemID = null;
1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * The systemID that was specified in
2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * processFromNode(Node node, String systemID).
2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return The systemID, or null.
2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  String getDOMsystemID()
2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return m_DOMsystemID;
2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Process the stylesheet from a DOM tree, if the
2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * processor supports the "http://xml.org/trax/features/dom/input"
2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * feature.
2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param node A DOM tree which must contain
2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * valid transform instructions that this processor understands.
2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param systemID The systemID from where xsl:includes and xsl:imports
2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * should be resolved from.
2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A Templates object capable of being used for transformation purposes.
2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  javax.xml.transform.Templates processFromNode(Node node, String systemID)
2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_DOMsystemID = systemID;
2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return processFromNode(node);
2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get InputSource specification(s) that are associated with the
2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * given document specified in the source param,
2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * via the xml-stylesheet processing instruction
2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * (see http://www.w3.org/TR/xml-stylesheet/), and that matches
2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * the given criteria.  Note that it is possible to return several stylesheets
2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * that match the criteria, in which case they are applied as if they were
2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * a list of imports or cascades.
2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <p>Note that DOM2 has it's own mechanism for discovering stylesheets.
2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Therefore, there isn't a DOM version of this method.</p>
2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param source The XML source that is to be searched.
2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param media The media attribute to be matched.  May be null, in which
2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *              case the prefered templates will be used (i.e. alternate = no).
2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param title The value of the title attribute to match.  May be null.
2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param charset The value of the charset attribute to match.  May be null.
2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A Source object capable of being used to create a Templates object.
2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public Source getAssociatedStylesheet(
2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          Source source, String media, String title, String charset)
2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            throws TransformerConfigurationException
2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    String baseID;
2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    InputSource isource = null;
2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    Node node = null;
2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    XMLReader reader = null;
2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (source instanceof DOMSource)
2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      DOMSource dsource = (DOMSource) source;
2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      node = dsource.getNode();
2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      baseID = dsource.getSystemId();
2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else
2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      isource = SAXSource.sourceToInputSource(source);
2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      baseID = isource.getSystemId();
2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // What I try to do here is parse until the first startElement
2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // is found, then throw a special exception in order to terminate
2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // the parse.
2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    StylesheetPIHandler handler = new StylesheetPIHandler(baseID, media,
2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                                    title, charset);
2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Use URIResolver. Patch from Dmitri Ilyin
2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (m_uriResolver != null)
2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      handler.setURIResolver(m_uriResolver);
2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
2894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try
2914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
2924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (null != node)
2934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
2944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        TreeWalker walker = new TreeWalker(handler, new org.apache.xml.utils.DOM2Helper(), baseID);
2954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
2964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        walker.traverse(node);
2974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
2984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
2994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
3004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Use JAXP1.1 ( if possible )
3024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
3034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
3044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          javax.xml.parsers.SAXParserFactory factory =
3054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            javax.xml.parsers.SAXParserFactory.newInstance();
3064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          factory.setNamespaceAware(true);
3084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          if (m_isSecureProcessing)
3104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          {
3114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            try
3124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            {
3134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson              factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
3144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            }
3154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            catch (org.xml.sax.SAXException e) {}
3164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          }
3174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
3194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          reader = jaxpParser.getXMLReader();
3214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
3224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (javax.xml.parsers.ParserConfigurationException ex)
3234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
3244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new org.xml.sax.SAXException(ex);
3254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
3264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (javax.xml.parsers.FactoryConfigurationError ex1)
3274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
3284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new org.xml.sax.SAXException(ex1.toString());
3294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
3304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (NoSuchMethodError ex2){}
3314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (AbstractMethodError ame){}
3324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        if (null == reader)
3344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
3354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          reader = XMLReaderFactory.createXMLReader();
3364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
3374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Need to set options!
3394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        reader.setContentHandler(handler);
3404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        reader.parse(isource);
3414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
3424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
3434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (StopParseException spe)
3444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
3454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // OK, good.
3474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
3484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (org.xml.sax.SAXException se)
3494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
3504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new TransformerConfigurationException(
3514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        "getAssociatedStylesheets failed", se);
3524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
3534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (IOException ioe)
3544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
3554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new TransformerConfigurationException(
3564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        "getAssociatedStylesheets failed", ioe);
3574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
3584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return handler.getAssociatedStylesheet();
3604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
3614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
3634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Create a new Transformer object that performs a copy
3644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * of the source to the result.
3654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
3664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A Transformer object that may be used to perform a transformation
3674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * in a single thread, never null.
3684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
3694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException May throw this during
3704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *            the parse when it is constructing the
3714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *            Templates object and fails.
3724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
3734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public TemplatesHandler newTemplatesHandler()
3744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
3754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
3764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return new StylesheetHandler(this);
3774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
3784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
3794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
3804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <p>Set a feature for this <code>TransformerFactory</code> and <code>Transformer</code>s
3814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * or <code>Template</code>s created by this factory.</p>
3824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
3834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <p>
3844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Feature names are fully qualified {@link java.net.URI}s.
3854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Implementations may define their own features.
3864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * An {@link TransformerConfigurationException} is thrown if this <code>TransformerFactory</code> or the
3874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <code>Transformer</code>s or <code>Template</code>s it creates cannot support the feature.
3884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * It is possible for an <code>TransformerFactory</code> to expose a feature value but be unable to change its state.
3894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * </p>
3904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
3914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <p>See {@link javax.xml.transform.TransformerFactory} for full documentation of specific features.</p>
3924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
3934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param name Feature name.
3944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param value Is feature state <code>true</code> or <code>false</code>.
3954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
3964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException if this <code>TransformerFactory</code>
3974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *   or the <code>Transformer</code>s or <code>Template</code>s it creates cannot support this feature.
3984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws NullPointerException If the <code>name</code> parameter is null.
3994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
4004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public void setFeature(String name, boolean value)
4014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson	  throws TransformerConfigurationException {
4024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	// feature name cannot be null
4044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	if (name == null) {
4054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	    throw new NullPointerException(
4064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                  XSLMessages.createMessage(
4074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson                      XSLTErrorResources.ER_SET_FEATURE_NULL_NAME, null));
4084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	}
4094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	// secure processing?
4114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
4124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	    m_isSecureProcessing = value;
4134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	}
4144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	// This implementation does not support the setting of a feature other than
4154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	// the secure processing feature.
4164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  	else
4174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
4184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new TransformerConfigurationException(
4194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          XSLMessages.createMessage(
4204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            XSLTErrorResources.ER_UNSUPPORTED_FEATURE,
4214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            new Object[] {name}));
4224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
4234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
4244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
4264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Look up the value of a feature.
4274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * <p>The feature name is any fully-qualified URI.  It is
4284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * possible for an TransformerFactory to recognize a feature name but
4294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * to be unable to return its value; this is especially true
4304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * in the case of an adapter for a SAX1 Parser, which has
4314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * no way of knowing whether the underlying parser is
4324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * validating, for example.</p>
4334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
4344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param name The feature name, which is a fully-qualified URI.
4354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return The current state of the feature (true or false).
4364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
4374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public boolean getFeature(String name) {
4384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // feature name cannot be null
4404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (name == null)
4414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
4424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    	throw new NullPointerException(
4434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            XSLMessages.createMessage(
4444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            XSLTErrorResources.ER_GET_FEATURE_NULL_NAME, null));
4454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
4464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Try first with identity comparison, which
4484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // will be faster.
4494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if ((DOMResult.FEATURE == name) || (DOMSource.FEATURE == name)
4504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            || (SAXResult.FEATURE == name) || (SAXSource.FEATURE == name)
4514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            || (StreamResult.FEATURE == name)
4524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            || (StreamSource.FEATURE == name)
4534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            || (SAXTransformerFactory.FEATURE == name)
4544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            || (SAXTransformerFactory.FEATURE_XMLFILTER == name))
4554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return true;
4564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else if ((DOMResult.FEATURE.equals(name))
4574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (DOMSource.FEATURE.equals(name))
4584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (SAXResult.FEATURE.equals(name))
4594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (SAXSource.FEATURE.equals(name))
4604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (StreamResult.FEATURE.equals(name))
4614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (StreamSource.FEATURE.equals(name))
4624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (SAXTransformerFactory.FEATURE.equals(name))
4634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson             || (SAXTransformerFactory.FEATURE_XMLFILTER.equals(name)))
4644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return true;
4654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // secure processing?
4664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING))
4674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return m_isSecureProcessing;
4684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else
4694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // unknown feature
4704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return false;
4714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
4724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
4744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Flag set by FEATURE_OPTIMIZE.
4754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * This feature specifies whether to Optimize stylesheet processing. By
4764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * default it is set to true.
4774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
4784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private boolean m_optimize = true;
4794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** Flag set by FEATURE_SOURCE_LOCATION.
4814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * This feature specifies whether the transformation phase should
4824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * keep track of line and column numbers for the input source
4834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * document. Note that this works only when that
4844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * information is available from the source -- in other words, if you
4854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * pass in a DOM, there's little we can do for you.
4864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
4874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * The default is false. Setting it true may significantly
4884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * increase storage cost per node.
4894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
4904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private boolean m_source_location = false;
4914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
4924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
4934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Flag set by FEATURE_INCREMENTAL.
4944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * This feature specifies whether to produce output incrementally, rather than
4954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * waiting to finish parsing the input before generating any output. By
4964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * default this attribute is set to false.
4974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
4984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private boolean m_incremental = false;
4994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
5004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
5014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Allows the user to set specific attributes on the underlying
5024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * implementation.
5034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
5044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param name The name of the attribute.
5054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param value The value of the attribute; Boolean or String="true"|"false"
5064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
5074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws IllegalArgumentException thrown if the underlying
5084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * implementation doesn't recognize the attribute.
5094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
5104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public void setAttribute(String name, Object value)
5114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws IllegalArgumentException
5124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
5134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (name.equals(FEATURE_INCREMENTAL))
5144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
5154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if(value instanceof Boolean)
5164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Accept a Boolean object..
5184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        m_incremental = ((Boolean)value).booleanValue();
5194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else if(value instanceof String)
5214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // .. or a String object
5234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        m_incremental = (new Boolean((String)value)).booleanValue();
5244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
5264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Give a more meaningful error message
5284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_BAD_VALUE, new Object[]{name, value})); //name + " bad value " + value);
5294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson	}
5314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else if (name.equals(FEATURE_OPTIMIZE))
5324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
5334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if(value instanceof Boolean)
5344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Accept a Boolean object..
5364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        m_optimize = ((Boolean)value).booleanValue();
5374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else if(value instanceof String)
5394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // .. or a String object
5414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        m_optimize = (new Boolean((String)value)).booleanValue();
5424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
5444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Give a more meaningful error message
5464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_BAD_VALUE, new Object[]{name, value})); //name + " bad value " + value);
5474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
5494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
5504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Custom Xalan feature: annotate DTM with SAX source locator fields.
5514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // This gets used during SAX2DTM instantiation.
5524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    //
5534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // %REVIEW% Should the name of this field really be in XalanProperties?
5544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // %REVIEW% I hate that it's a global static, but didn't want to change APIs yet.
5554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else if(name.equals(FEATURE_SOURCE_LOCATION))
5564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
5574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if(value instanceof Boolean)
5584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Accept a Boolean object..
5604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        m_source_location = ((Boolean)value).booleanValue();
5614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else if(value instanceof String)
5634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // .. or a String object
5654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        m_source_location = (new Boolean((String)value)).booleanValue();
5664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
5684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
5694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Give a more meaningful error message
5704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_BAD_VALUE, new Object[]{name, value})); //name + " bad value " + value);
5714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
5724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
5734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
5744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else
5754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
5764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUPPORTED, new Object[]{name})); //name + "not supported");
5774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
5784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
5794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
5804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
5814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Allows the user to retrieve specific attributes on the underlying
5824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * implementation.
5834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
5844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param name The name of the attribute.
5854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return value The value of the attribute.
5864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
5874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws IllegalArgumentException thrown if the underlying
5884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * implementation doesn't recognize the attribute.
5894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
5904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public Object getAttribute(String name) throws IllegalArgumentException
5914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
5924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (name.equals(FEATURE_INCREMENTAL))
5934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
5944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return new Boolean(m_incremental);
5954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
5964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else if (name.equals(FEATURE_OPTIMIZE))
5974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
5984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return new Boolean(m_optimize);
5994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
6004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else if (name.equals(FEATURE_SOURCE_LOCATION))
6014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
6024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return new Boolean(m_source_location);
6034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
6044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else
6054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_ATTRIB_VALUE_NOT_RECOGNIZED, new Object[]{name})); //name + " attribute not recognized");
6064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
6074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
6094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Create an XMLFilter that uses the given source as the
6104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * transformation instructions.
6114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param src The source of the transformation instructions.
6134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return An XMLFilter object, or null if this feature is not supported.
6154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
6174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
6184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public XMLFilter newXMLFilter(Source src)
6194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
6204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
6214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    Templates templates = newTemplates(src);
6234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if( templates==null ) return null;
6244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return newXMLFilter(templates);
6264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
6274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
6294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Create an XMLFilter that uses the given source as the
6304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * transformation instructions.
6314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param templates non-null reference to Templates object.
6334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return An XMLFilter object, or null if this feature is not supported.
6354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
6374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
6384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public XMLFilter newXMLFilter(Templates templates)
6394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
6404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
6414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try
6424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
6434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return new TrAXFilter(templates);
6444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
6454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch( TransformerConfigurationException ex )
6464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
6474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if( m_errorListener != null)
6484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
6494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
6504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
6514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError( ex );
6524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          return null;
6534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
6544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch( TransformerConfigurationException ex1 )
6554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
6564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex1;
6574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
6584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch( TransformerException ex1 )
6594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
6604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException(ex1);
6614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
6624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
6634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw ex;
6644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
6654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
6664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
6684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get a TransformerHandler object that can process SAX
6694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * ContentHandler events into a Result, based on the transformation
6704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * instructions specified by the argument.
6714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param src The source of the transformation instructions.
6734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return TransformerHandler ready to transform SAX events.
6754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
6774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
6784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public TransformerHandler newTransformerHandler(Source src)
6794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
6804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
6814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    Templates templates = newTemplates(src);
6834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if( templates==null ) return null;
6844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return newTransformerHandler(templates);
6864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
6874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
6884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
6894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get a TransformerHandler object that can process SAX
6904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * ContentHandler events into a Result, based on the Templates argument.
6914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param templates The source of the transformation instructions.
6934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
6944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return TransformerHandler ready to transform SAX events.
6954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
6964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
6974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public TransformerHandler newTransformerHandler(Templates templates)
6984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
6994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
7004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try {
7014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      TransformerImpl transformer =
7024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        (TransformerImpl) templates.newTransformer();
7034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      transformer.setURIResolver(m_uriResolver);
7044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      TransformerHandler th =
7054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        (TransformerHandler) transformer.getInputContentHandler(true);
7064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
7074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return th;
7084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
7094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch( TransformerConfigurationException ex )
7104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
7114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if( m_errorListener != null )
7124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
7134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
7144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
7154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError( ex );
7164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          return null;
7174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
7184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerConfigurationException ex1 )
7194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
7204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex1;
7214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
7224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerException ex1 )
7234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
7244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException(ex1);
7254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
7264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
7274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
7284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw ex;
7294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
7304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
7314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
7324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
7334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//  /** The identity transform string, for support of newTransformerHandler()
7344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//   *  and newTransformer().  */
7354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//  private static final String identityTransform =
7364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//    "<xsl:stylesheet " + "xmlns:xsl='http://www.w3.org/1999/XSL/Transform' "
7374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//    + "version='1.0'>" + "<xsl:template match='/|node()'>"
7384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//    + "<xsl:copy-of select='.'/>" + "</xsl:template>" + "</xsl:stylesheet>";
7394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//
7404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//  /** The identity transform Templates, built from identityTransform,
7414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//   *  for support of newTransformerHandler() and newTransformer().  */
7424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson//  private static Templates m_identityTemplate = null;
7434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
7444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
7454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get a TransformerHandler object that can process SAX
7464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * ContentHandler events into a Result.
7474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
7484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return TransformerHandler ready to transform SAX events.
7494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
7504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException
7514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
7524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public TransformerHandler newTransformerHandler()
7534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
7544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
7554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return new TransformerIdentityImpl(m_isSecureProcessing);
7564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
7574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
7584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
7594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Process the source into a Transformer object.  Care must
7604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * be given to know that this object can not be used concurrently
7614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * in multiple threads.
7624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
7634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param source An object that holds a URL, input stream, etc.
7644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
7654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A Transformer object capable of
7664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * being used for transformation purposes in a single thread.
7674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
7684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException May throw this during the parse when it
7694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *            is constructing the Templates object and fails.
7704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
7714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public Transformer newTransformer(Source source)
7724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
7734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
7744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try
7754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
7764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      Templates tmpl=newTemplates( source );
7774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      /* this can happen if an ErrorListener is present and it doesn't
7784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson         throw any exception in fatalError.
7794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson         The spec says: "a Transformer must use this interface
7804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson         instead of throwing an exception" - the newTemplates() does
7814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson         that, and returns null.
7824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      */
7834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if( tmpl==null ) return null;
7844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      Transformer transformer = tmpl.newTransformer();
7854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      transformer.setURIResolver(m_uriResolver);
7864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return transformer;
7874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
7884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch( TransformerConfigurationException ex )
7894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
7904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if( m_errorListener != null )
7914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
7924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
7934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
7944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError( ex );
7952583639a965660e62e2a4552049619f84af37021Jesse Wilson          return null; // TODO: but the API promises to never return null...
7964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
7974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch( TransformerConfigurationException ex1 )
7984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
7994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex1;
8004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
8014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch( TransformerException ex1 )
8024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
8034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException( ex1 );
8044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
8054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
8064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw ex;
8074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
8084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
8094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
8114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Create a new Transformer object that performs a copy
8124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * of the source to the result.
8134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
8144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A Transformer object capable of
8154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * being used for transformation purposes in a single thread.
8164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
8174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException May throw this during
8184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *            the parse when it is constructing the
8194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *            Templates object and it fails.
8204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
8214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public Transformer newTransformer() throws TransformerConfigurationException
8224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
8234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return new TransformerIdentityImpl(m_isSecureProcessing);
8244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
8254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
8274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Process the source into a Templates object, which is likely
8284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * a compiled representation of the source. This Templates object
8294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * may then be used concurrently across multiple threads.  Creating
8304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * a Templates object allows the TransformerFactory to do detailed
8314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * performance optimization of transformation instructions, without
8324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * penalizing runtime transformation.
8334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
8344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param source An object that holds a URL, input stream, etc.
8354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A Templates object capable of being used for transformation purposes.
8364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
8374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws TransformerConfigurationException May throw this during the parse when it
8384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *            is constructing the Templates object and fails.
8394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
8404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public Templates newTemplates(Source source)
8414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws TransformerConfigurationException
8424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
8434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    String baseID = source.getSystemId();
8454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (null != baseID) {
8474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson       baseID = SystemIDResolver.getAbsoluteURI(baseID);
8484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
8494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (source instanceof DOMSource)
8524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
8534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      DOMSource dsource = (DOMSource) source;
8544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      Node node = dsource.getNode();
8554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (null != node)
8574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        return processFromNode(node, baseID);
8584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
8594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
8604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        String messageStr = XSLMessages.createMessage(
8614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          XSLTErrorResources.ER_ILLEGAL_DOMSOURCE_INPUT, null);
8624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new IllegalArgumentException(messageStr);
8644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
8654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
8664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    TemplatesHandler builder = newTemplatesHandler();
8684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    builder.setSystemId(baseID);
8694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try
8714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
8724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      InputSource isource = SAXSource.sourceToInputSource(source);
8734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      isource.setSystemId(baseID);
8744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      XMLReader reader = null;
8754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (source instanceof SAXSource)
8774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        reader = ((SAXSource) source).getXMLReader();
8784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (null == reader)
8804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
8814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        // Use JAXP1.1 ( if possible )
8834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
8844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
8854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          javax.xml.parsers.SAXParserFactory factory =
8864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            javax.xml.parsers.SAXParserFactory.newInstance();
8874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          factory.setNamespaceAware(true);
8894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          if (m_isSecureProcessing)
8914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          {
8924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            try
8934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            {
8944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson              factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
8954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            }
8964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson            catch (org.xml.sax.SAXException se) {}
8974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          }
8984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
8994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
9004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          reader = jaxpParser.getXMLReader();
9024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (javax.xml.parsers.ParserConfigurationException ex)
9044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new org.xml.sax.SAXException(ex);
9064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (javax.xml.parsers.FactoryConfigurationError ex1)
9084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new org.xml.sax.SAXException(ex1.toString());
9104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (NoSuchMethodError ex2){}
9124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (AbstractMethodError ame){}
9134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
9144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (null == reader)
9164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        reader = XMLReaderFactory.createXMLReader();
9174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // If you set the namespaces to true, we'll end up getting double
9194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // xmlns attributes.  Needs to be fixed.  -sb
9204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
9214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      reader.setContentHandler(builder);
9224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      reader.parse(isource);
9234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
9244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (org.xml.sax.SAXException se)
9254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
9264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (m_errorListener != null)
9274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
9284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
9294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError(new TransformerException(se));
9314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerConfigurationException ex1)
9334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex1;
9354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerException ex1)
9374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException(ex1);
9394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
9414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
9424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
9434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new TransformerConfigurationException(se.getMessage(), se);
9444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
9454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
9464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch (Exception e)
9474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
9484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      if (m_errorListener != null)
9494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
9504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        try
9514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          m_errorListener.fatalError(new TransformerException(e));
9534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          return null;
9544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerConfigurationException ex1)
9564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw ex1;
9584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        catch (TransformerException ex1)
9604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        {
9614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throw new TransformerConfigurationException(ex1);
9624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        }
9634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
9644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      else
9654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
9664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        throw new TransformerConfigurationException(e.getMessage(), e);
9674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
9684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
9694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return builder.getTemplates();
9714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
9724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
9744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * The object that implements the URIResolver interface,
9754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * or null.
9764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
9774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  URIResolver m_uriResolver;
9784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
9804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Set an object that will be used to resolve URIs used in
9814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * xsl:import, etc.  This will be used as the default for the
9824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * transformation.
9834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param resolver An object that implements the URIResolver interface,
9844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * or null.
9854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
9864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public void setURIResolver(URIResolver resolver)
9874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
9884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_uriResolver = resolver;
9894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
9904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
9914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
9924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get the object that will be used to resolve URIs used in
9934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * xsl:import, etc.  This will be used as the default for the
9944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * transformation.
9954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
9964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return The URIResolver that was set with setURIResolver.
9974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
9984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public URIResolver getURIResolver()
9994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
10004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return m_uriResolver;
10014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
10024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
10034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** The error listener.   */
10044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private ErrorListener m_errorListener = new org.apache.xml.utils.DefaultErrorHandler(false);
10054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
10064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
10074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get the error listener in effect for the TransformerFactory.
10084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
10094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return A non-null reference to an error listener.
10104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
10114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public ErrorListener getErrorListener()
10124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
10134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return m_errorListener;
10144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
10154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
10164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
10174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Set an error listener for the TransformerFactory.
10184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
10194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param listener Must be a non-null reference to an ErrorListener.
10204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
10214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @throws IllegalArgumentException if the listener argument is null.
10224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
10234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public void setErrorListener(ErrorListener listener)
10244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson          throws IllegalArgumentException
10254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
10264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
10274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (null == listener)
10284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_ERRORLISTENER, null));
10294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // "ErrorListener");
10304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
10314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    m_errorListener = listener;
10324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
10334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
10344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
10354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Return the state of the secure processing feature.
10364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
10374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return state of the secure processing feature.
10384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
10394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public boolean isSecureProcessing()
10404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
10414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return m_isSecureProcessing;
10424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
10434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson}
1044