19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: ProcessorInclude.java 469349 2006-10-31 03:06:50Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xalan.processor;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.XMLConstants;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.Source;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.URIResolver;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.dom.DOMSource;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.sax.SAXSource;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.stream.StreamSource;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.SystemIDResolver;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.TreeWalker;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node;
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Attributes;
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.InputSource;
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.XMLReader;
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.helpers.XMLReaderFactory;
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * TransformerFactory class for xsl:include markup.
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class ProcessorInclude extends XSLTElementProcessor
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = -4570078731972673481L;
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The base URL of the XSL document.
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private String m_href = null;
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the base identifier with which this stylesheet is associated.
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return non-null reference to the href attribute string, or
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         null if setHref has not been called.
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getHref()
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_href;
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the base identifier with which this stylesheet is associated.
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param baseIdent Should be a non-null reference to a valid URL string.
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setHref(String baseIdent)
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Validate?
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_href = baseIdent;
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the stylesheet type associated with an included stylesheet
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the type of the stylesheet
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected int getStylesheetType()
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return StylesheetHandler.STYPE_INCLUDE;
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the error number associated with this type of stylesheet including itself
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the appropriate error number
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected String getStylesheetInclErr()
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return XSLTErrorResources.ER_STYLESHEET_INCLUDES_ITSELF;
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Receive notification of the start of an xsl:include element.
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param handler The calling StylesheetHandler/TemplatesBuilder.
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param uri The Namespace URI, or the empty string if the
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        element has no Namespace URI or if Namespace
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        processing is not being performed.
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param localName The local name (without prefix), or the
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        empty string if Namespace processing is not being
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        performed.
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param rawName The raw XML 1.0 name (with prefix), or the
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        empty string if raw names are not available.
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param attributes The attributes attached to the element.  If
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        there are no attributes, it shall be an empty
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        Attributes object.
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws org.xml.sax.SAXException Any SAX exception, possibly
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void startElement(
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws org.xml.sax.SAXException
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    setPropertiesFromAttributes(handler, rawName, attributes, this);
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Get the Source from the user's URIResolver (if any).
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Source sourceFromURIResolver = getSourceFromUriResolver(handler);
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Get the system ID of the included/imported stylesheet module
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String hrefUrl = getBaseURIOfIncludedStylesheet(handler, sourceFromURIResolver);
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (handler.importStackContains(hrefUrl))
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new org.xml.sax.SAXException(
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XSLMessages.createMessage(
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          getStylesheetInclErr(), new Object[]{ hrefUrl }));  //"(StylesheetHandler) "+hrefUrl+" is directly or indirectly importing itself!");
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Push the system ID and corresponding Source
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // on some stacks for later retrieval during parse() time.
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.pushImportURL(hrefUrl);
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.pushImportSource(sourceFromURIResolver);
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int savedStylesheetType = handler.getStylesheetType();
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.setStylesheetType(this.getStylesheetType());
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.pushNewNamespaceSupport();
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        parse(handler, uri, localName, rawName, attributes);
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      finally
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        handler.setStylesheetType(savedStylesheetType);
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        handler.popImportURL();
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        handler.popImportSource();
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        handler.popNamespaceSupport();
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch(TransformerException te)
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.error(te.getMessage(), te);
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set off a new parse for an included or imported stylesheet.  This will
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * set the {@link StylesheetHandler} to a new state, and recurse in with
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a new set of parse events.  Once this function returns, the state of
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the StylesheetHandler should be restored.
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param uri The Namespace URI, which should be the XSLT namespace.
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param localName The local name (without prefix), which should be "include" or "import".
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param rawName The qualified name (with prefix).
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param attributes The list of attributes on the xsl:include or xsl:import element.
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws org.xml.sax.SAXException Any SAX exception, possibly
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *            wrapping another exception.
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected void parse(
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws org.xml.sax.SAXException
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TransformerFactoryImpl processor = handler.getStylesheetProcessor();
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    URIResolver uriresolver = processor.getURIResolver();
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Source source = null;
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // The base identifier, an aboslute URI
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // that is associated with the included/imported
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // stylesheet module is known in this method,
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // so this method does the pushing of the
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // base ID onto the stack.
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != uriresolver)
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // There is a user provided URI resolver.
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // At the startElement() call we would
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // have tried to obtain a Source from it
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // which we now retrieve
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        source = handler.peekSourceFromURIResolver();
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null != source && source instanceof DOMSource)
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Node node = ((DOMSource)source).getNode();
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // There is a user provided URI resolver.
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // At the startElement() call we would
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // have already pushed the system ID, obtained
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // from either the source.getSystemId(), if non-null
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // or from SystemIDResolver.getAbsoluteURI() as a backup
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // which we now retrieve.
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          String systemId = handler.peekImportURL();
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // Push the absolute URI of the included/imported
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // stylesheet module onto the stack.
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (systemId != null)
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              handler.pushBaseIndentifier(systemId);
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          TreeWalker walker = new TreeWalker(handler, new org.apache.xml.utils.DOM2Helper(), systemId);
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          try
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            walker.traverse(node);
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          catch(org.xml.sax.SAXException se)
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new TransformerException(se);
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (systemId != null)
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            handler.popBaseIndentifier();
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return;
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(null == source)
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String absURL = SystemIDResolver.getAbsoluteURI(getHref(),
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                          handler.getBaseIdentifier());
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        source = new StreamSource(absURL);
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // possible callback to a class that over-rides this method.
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      source = processSource(handler, source);
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XMLReader reader = null;
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(source instanceof SAXSource)
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        SAXSource saxSource = (SAXSource)source;
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        reader = saxSource.getXMLReader(); // may be null
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      InputSource inputSource = SAXSource.sourceToInputSource(source);
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == reader)
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Use JAXP1.1 ( if possible )
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try {
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          javax.xml.parsers.SAXParserFactory factory=
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                     javax.xml.parsers.SAXParserFactory.newInstance();
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          factory.setNamespaceAware( true );
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (handler.getStylesheetProcessor().isSecureProcessing())
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            try
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            catch (org.xml.sax.SAXException se) {}
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          javax.xml.parsers.SAXParser jaxpParser=
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                 factory.newSAXParser();
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          reader=jaxpParser.getXMLReader();
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } catch( javax.xml.parsers.ParserConfigurationException ex ) {
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throw new org.xml.sax.SAXException( ex );
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throw new org.xml.sax.SAXException( ex1.toString() );
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        catch( NoSuchMethodError ex2 )
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        catch (AbstractMethodError ame){}
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == reader)
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        reader = XMLReaderFactory.createXMLReader();
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != reader)
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        reader.setContentHandler(handler);
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Push the absolute URI of the included/imported
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // stylesheet module onto the stack.
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        handler.pushBaseIndentifier(inputSource.getSystemId());
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        try
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          reader.parse(inputSource);
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        finally
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          handler.popBaseIndentifier();
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (IOException ioe)
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.error(XSLTErrorResources.ER_IOEXCEPTION,
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    new Object[]{ getHref() }, ioe);
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch(TransformerException te)
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      handler.error(te.getMessage(), te);
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This method does nothing, but a class that extends this class could
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * over-ride it and do some processing of the source.
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param handler The calling StylesheetHandler/TemplatesBuilder.
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param source The source of the included stylesheet.
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the same or an equivalent source to what was passed in.
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected Source processSource(StylesheetHandler handler, Source source)
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return source;
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the Source object for the included or imported stylesheet module
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * obtained from the user's URIResolver, if there is no user provided
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * URIResolver null is returned.
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Source getSourceFromUriResolver(StylesheetHandler handler)
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException {
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Source s = null;
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            TransformerFactoryImpl processor = handler.getStylesheetProcessor();
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            URIResolver uriresolver = processor.getURIResolver();
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (uriresolver != null) {
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String href = getHref();
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                String base = handler.getBaseIdentifier();
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                s = uriresolver.resolve(href,base);
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return s;
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the base URI of the included or imported stylesheet,
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * if the user provided a URIResolver, then get the Source
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * object for the stylsheet from it, and get the systemId
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * from that Source object, otherwise try to recover by
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * using the SysteIDResolver to figure out the base URI.
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param handler The handler that processes the stylesheet as SAX events,
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * and maintains state
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param s The Source object from a URIResolver, for the included stylesheet module,
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * so this will be null if there is no URIResolver set.
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private String getBaseURIOfIncludedStylesheet(StylesheetHandler handler, Source s)
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException {
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String baseURI;
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String idFromUriResolverSource;
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (s != null && (idFromUriResolverSource = s.getSystemId()) != null) {
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // We have a Source obtained from a users's URIResolver,
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // and the system ID is set on it, so return that as the base URI
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            baseURI = idFromUriResolverSource;
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // The user did not provide a URIResolver, or it did not
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // return a Source for the included stylesheet module, or
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // the Source has no system ID set, so we fall back to using
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // the system ID Resolver to take the href and base
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // to generate the baseURI of the included stylesheet.
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            baseURI = SystemIDResolver.getAbsoluteURI(getHref(), handler
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    .getBaseIdentifier());
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return baseURI;
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
397