/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xalan.templates;

// Java imports
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import java.text.DecimalFormatSymbols;

import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;

// Xalan imports
import org.apache.xml.utils.SystemIDResolver;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.StringVector;
import org.apache.xpath.XPath;

// DOM Imports
//import org.w3c.dom.Node;
//import org.w3c.dom.Document;
import org.apache.xml.dtm.DTM;

// SAX2 Imports
import javax.xml.transform.TransformerException;
import org.xml.sax.Locator;

import javax.xml.transform.SourceLocator;

/**
 * Represents a stylesheet element.
 * <p>All properties in this class have a fixed form of bean-style property
 * accessors for all properties that represent XSL attributes or elements.
 * These properties have setter method names accessed generically by the
 * processor, and so these names must be fixed according to the system
 * defined in the <a href="XSLTAttributeDef#getSetterMethodName">getSetterMethodName</a>
 * function.</p>
 * <p><pre>
 * <!ENTITY % top-level "
 *  (xsl:import*,
 *   (xsl:include
 *   | xsl:strip-space
 *   | xsl:preserve-space
 *   | xsl:output
 *   | xsl:key
 *   | xsl:decimal-format
 *   | xsl:attribute-set
 *   | xsl:variable
 *   | xsl:param
 *   | xsl:template
 *   | xsl:namespace-alias
 *   %non-xsl-top-level;)*)
 * ">
 *
 * <!ENTITY % top-level-atts '
 *   extension-element-prefixes CDATA #IMPLIED
 *   exclude-result-prefixes CDATA #IMPLIED
 *   id ID #IMPLIED
 *   version NMTOKEN #REQUIRED
 *   xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
 *   %space-att;
 * '>
 *
 * <!ELEMENT xsl:stylesheet %top-level;>
 * <!ATTLIST xsl:stylesheet %top-level-atts;>
 *
 * <!ELEMENT xsl:transform %top-level;>
 * <!ATTLIST xsl:transform %top-level-atts;>
 *
 * </p></pre>
 * @see <a href="http://www.w3.org/TR/xslt#section-Stylesheet-Structure">section-Stylesheet-Structure in XSLT Specification</a>
 */
public class Stylesheet extends ElemTemplateElement
        implements java.io.Serializable /* , Document */
{

  /**
   * Constructor for a Stylesheet.
   * @param parent  The including or importing stylesheet.
   */
  public Stylesheet(Stylesheet parent)
  {

    if (null != parent)
    {
      m_stylesheetParent = parent;
      m_stylesheetRoot = parent.getStylesheetRoot();
    }
  }

  /**
   * Get the owning stylesheet.  This looks up the
   * inheritance chain until it calls getStylesheet
   * on a Stylesheet object, which will return itself.
   *
   * @return The owning stylesheet, itself.
   */
  public Stylesheet getStylesheet()
  {
    return this;
  }

  /**
   * Tell if this can be cast to a StylesheetComposed, meaning, you
   * can ask questions from getXXXComposed functions.
   *
   * @return False if this is not a StylesheetComposed
   */
  public boolean isAggregatedType()
  {
    return false;
  }

  /**
   * Tell if this is the root of the stylesheet tree.
   *
   * @return False is this is not the root of the stylesheet tree.
   */
  public boolean isRoot()
  {
    return false;
  }

  /**
   * Extension to be used when serializing to disk.
   */
  public static final String STYLESHEET_EXT = ".lxc";

  /**
   * Read the stylesheet from a serialization stream.
   *
   * @param stream Input stream to read from
   *
   * @throws IOException
   * @throws TransformerException
   */
  private void readObject(ObjectInputStream stream)
          throws IOException, TransformerException
  {

    // System.out.println("Reading Stylesheet");
    try
    {
      stream.defaultReadObject();
    }
    catch (ClassNotFoundException cnfe)
    {
      throw new TransformerException(cnfe);
    }

    // System.out.println("Done reading Stylesheet");
  }

  /**
   * Write out the given output stream 
   *
   *
   * @param stream The output stream to write out
   *
   * @throws IOException
   */
  private void writeObject(ObjectOutputStream stream) throws IOException
  {

    // System.out.println("Writing Stylesheet");
    stream.defaultWriteObject();

    // System.out.println("Done writing Stylesheet");
  }

  //============== XSLT Properties =================

  /**
   * The "xmlns:xsl" property.
   * @serial
   */
  private String m_XmlnsXsl;

  /**
   * Set the "xmlns:xsl" property.
   * @see <a href="http://www.w3.org/TR/xslt#xslt-namespace">xslt-namespace in XSLT Specification</a>
   *
   * @param v The value to be set for the "xmlns:xsl" property.
   */
  public void setXmlnsXsl(String v)
  {
    m_XmlnsXsl = v;
  }

  /**
   * Get the "xmlns:xsl" property.
   * @see <a href="http://www.w3.org/TR/xslt#xslt-namespace">xslt-namespace in XSLT Specification</a>
   *
   * @return The value of the "xmlns:xsl" property.
   */
  public String getXmlnsXsl()
  {
    return m_XmlnsXsl;
  }

  /**
   * The "extension-element-prefixes" property, actually contains URIs.
   * @serial
   */
  private StringVector m_ExtensionElementURIs;

  /**
   * Set the "extension-element-prefixes" property.
   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
   *
   * @param v The value to be set for the "extension-element-prefixes" 
   * property: a vector of extension element URIs.
   */
  public void setExtensionElementPrefixes(StringVector v)
  {
    m_ExtensionElementURIs = v;
  }

  /**
   * Get and "extension-element-prefix" property.
   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
   *
   * @param i Index of extension element URI in list 
   *
   * @return The extension element URI at the given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public String getExtensionElementPrefix(int i)
          throws ArrayIndexOutOfBoundsException
  {

    if (null == m_ExtensionElementURIs)
      throw new ArrayIndexOutOfBoundsException();

    return m_ExtensionElementURIs.elementAt(i);
  }

  /**
   * Get the number of "extension-element-prefixes" Strings.
   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
   *
   * @return Number of URIs in the list
   */
  public int getExtensionElementPrefixCount()
  {
    return (null != m_ExtensionElementURIs)
           ? m_ExtensionElementURIs.size() : 0;
  }

  /**
   * Find out if this contains a given "extension-element-prefix" property.
   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
   *
   * @param uri URI of extension element to look for
   *
   * @return True if the given URI was found in the list 
   */
  public boolean containsExtensionElementURI(String uri)
  {

    if (null == m_ExtensionElementURIs)
      return false;

    return m_ExtensionElementURIs.contains(uri);
  }

  /**
   * The "exclude-result-prefixes" property.
   * @serial
   */
  private StringVector m_ExcludeResultPrefixs;

  /**
   * Set the "exclude-result-prefixes" property.
   * The designation of a namespace as an excluded namespace is
   * effective within the subtree of the stylesheet rooted at
   * the element bearing the exclude-result-prefixes or
   * xsl:exclude-result-prefixes attribute; a subtree rooted
   * at an xsl:stylesheet element does not include any stylesheets
   * imported or included by children of that xsl:stylesheet element.
   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
   *
   * @param v A StringVector of prefixes to exclude 
   */
  public void setExcludeResultPrefixes(StringVector v)
  {
    m_ExcludeResultPrefixs = v;
  }

  /**
   * Get an "exclude-result-prefix" property.
   * The designation of a namespace as an excluded namespace is
   * effective within the subtree of the stylesheet rooted at
   * the element bearing the exclude-result-prefixes or
   * xsl:exclude-result-prefixes attribute; a subtree rooted
   * at an xsl:stylesheet element does not include any stylesheets
   * imported or included by children of that xsl:stylesheet element.
   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
   *
   * @param i Index of prefix to get in list 
   *
   * @return Prefix to be excluded at the given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public String getExcludeResultPrefix(int i)
          throws ArrayIndexOutOfBoundsException
  {

    if (null == m_ExcludeResultPrefixs)
      throw new ArrayIndexOutOfBoundsException();

    return m_ExcludeResultPrefixs.elementAt(i);
  }

  /**
   * Get the number of "exclude-result-prefixes" Strings.
   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
   *
   * @return The number of prefix strings to be excluded. 
   */
  public int getExcludeResultPrefixCount()
  {
    return (null != m_ExcludeResultPrefixs)
           ? m_ExcludeResultPrefixs.size() : 0;
  }

  /**
   * Get whether or not the passed prefix is contained flagged by
   * the "exclude-result-prefixes" property.
   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
   *
   * @param prefix non-null reference to prefix that might be excluded.
   * @param uri reference to namespace that prefix maps to
   *
   * @return true if the prefix should normally be excluded.>
   */
  public boolean containsExcludeResultPrefix(String prefix, String uri) 
  {

    if (null == m_ExcludeResultPrefixs || uri == null )
      return false;
    
    // This loop is ok here because this code only runs during
    // stylesheet compile time.
    for (int i =0; i< m_ExcludeResultPrefixs.size(); i++)
    {
      if (uri.equals(getNamespaceForPrefix(m_ExcludeResultPrefixs.elementAt(i))))
        return true;
    }
    
    return false;

  /*  if (prefix.length() == 0)
      prefix = Constants.ATTRVAL_DEFAULT_PREFIX;

    return m_ExcludeResultPrefixs.contains(prefix); */
  }

  /**
   * The "id" property.
   * @serial
   */
  private String m_Id;

  /**
   * Set the "id" property.
   * @see <a href="http://www.w3.org/TR/xslt#section-Embedding-Stylesheets">section-Embedding-Stylesheets in XSLT Specification</a>
   *
   * @param v Value for the "id" property.
   */
  public void setId(String v)
  {
    m_Id = v;
  }

  /**
   * Get the "id" property.
   * @see <a href="http://www.w3.org/TR/xslt#section-Embedding-Stylesheets">section-Embedding-Stylesheets in XSLT Specification</a>
   *
   * @return The value of the "id" property.
   */
  public String getId()
  {
    return m_Id;
  }

  /**
   * The "version" property.
   * @serial
   */
  private String m_Version;

  /**
   * Set the "version" property.
   * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
   *
   * @param v Value for the "version" property.
   */
  public void setVersion(String v)
  {
    m_Version = v;
  }

  /**
   * Get the "version" property.
   * @see <a href="http://www.w3.org/TR/xslt#forwards">forwards in XSLT Specification</a>
   *
   * @return The value of the "version" property.
   */
  public String getVersion()
  {
    return m_Version;
  }

  /**
   * The "xsl:import" list.
   * @serial
   */
  private Vector m_imports;

  /**
   * Add a stylesheet to the "import" list.
   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
   *
   * @param v Stylesheet to add to the import list
   */
  public void setImport(StylesheetComposed v)
  {

    if (null == m_imports)
      m_imports = new Vector();

    // I'm going to insert the elements in backwards order,
    // so I can walk them 0 to n.
    m_imports.addElement(v);
  }

  /**
   * Get a stylesheet from the "import" list.
   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
   *
   * @param i Index of the stylesheet to get
   *
   * @return The stylesheet at the given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public StylesheetComposed getImport(int i)
          throws ArrayIndexOutOfBoundsException
  {

    if (null == m_imports)
      throw new ArrayIndexOutOfBoundsException();

    return (StylesheetComposed) m_imports.elementAt(i);
  }

  /**
   * Get the number of imported stylesheets.
   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
   *
   * @return the number of imported stylesheets.
   */
  public int getImportCount()
  {
    return (null != m_imports) ? m_imports.size() : 0;
  }

  /**
   * The "xsl:include" properties.
   * @serial
   */
  private Vector m_includes;

  /**
   * Add a stylesheet to the "include" list.
   * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
   *
   * @param v Stylesheet to add to the "include" list  
   */
  public void setInclude(Stylesheet v)
  {

    if (null == m_includes)
      m_includes = new Vector();

    m_includes.addElement(v);
  }

  /**
   * Get the stylesheet at the given in index in "include" list
   * @see <a href="http://www.w3.org/TR/xslt#include">include in XSLT Specification</a>
   *
   * @param i Index of stylesheet to get
   *
   * @return Stylesheet at the given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public Stylesheet getInclude(int i) throws ArrayIndexOutOfBoundsException
  {

    if (null == m_includes)
      throw new ArrayIndexOutOfBoundsException();

    return (Stylesheet) m_includes.elementAt(i);
  }

  /**
   * Get the number of included stylesheets.
   * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
   *
   * @return the number of included stylesheets.
   */
  public int getIncludeCount()
  {
    return (null != m_includes) ? m_includes.size() : 0;
  }

  /**
   * Table of tables of element decimal-format.
   * @see DecimalFormatProperties
   * @serial
   */
  Stack m_DecimalFormatDeclarations;

  /**
   * Process the xsl:decimal-format element.
   *
   * @param edf Decimal-format element to push into stack  
   */
  public void setDecimalFormat(DecimalFormatProperties edf)
  {

    if (null == m_DecimalFormatDeclarations)
      m_DecimalFormatDeclarations = new Stack();

    // Elements are pushed in by order of importance
    // so that when recomposed, they get overiden properly.
    m_DecimalFormatDeclarations.push(edf);
  }

  /**
   * Get an "xsl:decimal-format" property.
   * 
   * @see DecimalFormatProperties
   * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
   *
   * @param name The qualified name of the decimal format property.
   * @return null if not found, otherwise a DecimalFormatProperties
   * object, from which you can get a DecimalFormatSymbols object.
   */
  public DecimalFormatProperties getDecimalFormat(QName name)
  {

    if (null == m_DecimalFormatDeclarations)
      return null;

    int n = getDecimalFormatCount();

    for (int i = (n - 1); i >= 0; i++)
    {
      DecimalFormatProperties dfp = getDecimalFormat(i);

      if (dfp.getName().equals(name))
        return dfp;
    }

    return null;
  }

  /**
   * Get an "xsl:decimal-format" property.
   * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
   * @see DecimalFormatProperties
   *
   * @param i Index of decimal-format property in stack
   *
   * @return The decimal-format property at the given index 
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public DecimalFormatProperties getDecimalFormat(int i)
          throws ArrayIndexOutOfBoundsException
  {

    if (null == m_DecimalFormatDeclarations)
      throw new ArrayIndexOutOfBoundsException();

    return (DecimalFormatProperties) m_DecimalFormatDeclarations.elementAt(i);
  }

  /**
   * Get the number of xsl:decimal-format declarations.
   * @see DecimalFormatProperties
   *
   * @return the number of xsl:decimal-format declarations.
   */
  public int getDecimalFormatCount()
  {
    return (null != m_DecimalFormatDeclarations)
           ? m_DecimalFormatDeclarations.size() : 0;
  }

  /**
   * The "xsl:strip-space" properties,
   * A lookup table of all space stripping elements.
   * @serial
   */
  private Vector m_whitespaceStrippingElements;

  /**
   * Set the "xsl:strip-space" properties.
   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
   *
   * @param wsi WhiteSpaceInfo element to add to list 
   */
  public void setStripSpaces(WhiteSpaceInfo wsi)
  {

    if (null == m_whitespaceStrippingElements)
    {
      m_whitespaceStrippingElements = new Vector();
    }

    m_whitespaceStrippingElements.addElement(wsi);
  }

  /**
   * Get an "xsl:strip-space" property.
   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
   *
   * @param i Index of WhiteSpaceInfo to get
   *
   * @return WhiteSpaceInfo at given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public WhiteSpaceInfo getStripSpace(int i) throws ArrayIndexOutOfBoundsException
  {

    if (null == m_whitespaceStrippingElements)
      throw new ArrayIndexOutOfBoundsException();

    return (WhiteSpaceInfo) m_whitespaceStrippingElements.elementAt(i);
  }

  /**
   * Get the number of "xsl:strip-space" properties.
   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
   *
   * @return the number of "xsl:strip-space" properties.
   */
  public int getStripSpaceCount()
  {
    return (null != m_whitespaceStrippingElements)
           ? m_whitespaceStrippingElements.size() : 0;
  }

  /**
   * The "xsl:preserve-space" property,
   * A lookup table of all space preserving elements.
   * @serial
   */
  private Vector m_whitespacePreservingElements;

  /**
   * Set the "xsl:preserve-space" property.
   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
   *
   * @param wsi WhiteSpaceInfo element to add to list
   */
  public void setPreserveSpaces(WhiteSpaceInfo wsi)
  {

    if (null == m_whitespacePreservingElements)
    {
      m_whitespacePreservingElements = new Vector();
    }

    m_whitespacePreservingElements.addElement(wsi);
  }

  /**
   * Get a "xsl:preserve-space" property.
   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
   *
   * @param i Index of WhiteSpaceInfo to get
   *
   * @return WhiteSpaceInfo at the given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public WhiteSpaceInfo getPreserveSpace(int i) throws ArrayIndexOutOfBoundsException
  {

    if (null == m_whitespacePreservingElements)
      throw new ArrayIndexOutOfBoundsException();

    return (WhiteSpaceInfo) m_whitespacePreservingElements.elementAt(i);
  }

  /**
   * Get the number of "xsl:preserve-space" properties.
   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
   *
   * @return the number of "xsl:preserve-space" properties.
   */
  public int getPreserveSpaceCount()
  {
    return (null != m_whitespacePreservingElements)
           ? m_whitespacePreservingElements.size() : 0;
  }

  /**
   * The "xsl:output" properties.  This is a vector of OutputProperties objects.
   * @serial
   */
  private Vector m_output;

  /**
   * Set the "xsl:output" property.
   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
   *
   * @param v non-null reference to the OutputProperties object to be 
   *          added to the collection.
   */
  public void setOutput(OutputProperties v)
  {
    if (null == m_output)
    {
      m_output = new Vector();
    }

    m_output.addElement(v);
  }

  /**
   * Get an "xsl:output" property.
   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
   *
   * @param i Index of OutputFormatExtended to get
   *
   * @return non-null reference to an OutputProperties object.
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public OutputProperties getOutput(int i) throws ArrayIndexOutOfBoundsException
  {

    if (null == m_output)
      throw new ArrayIndexOutOfBoundsException();

    return (OutputProperties) m_output.elementAt(i);
  }

  /**
   * Get the number of "xsl:output" properties.
   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
   *
   * @return The number of OutputProperties objects contained in this stylesheet.
   */
  public int getOutputCount()
  {
    return (null != m_output)
           ? m_output.size() : 0;
  }

  /**
   * The "xsl:key" property.
   * @serial
   */
  private Vector m_keyDeclarations;

  /**
   * Set the "xsl:key" property.
   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
   *
   * @param v KeyDeclaration element to add to the list of key declarations 
   */
  public void setKey(KeyDeclaration v)
  {

    if (null == m_keyDeclarations)
      m_keyDeclarations = new Vector();

    m_keyDeclarations.addElement(v);
  }

  /**
   * Get an "xsl:key" property.
   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
   *
   * @param i Index of KeyDeclaration element to get
   *
   * @return KeyDeclaration element at given index in list 
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public KeyDeclaration getKey(int i) throws ArrayIndexOutOfBoundsException
  {

    if (null == m_keyDeclarations)
      throw new ArrayIndexOutOfBoundsException();

    return (KeyDeclaration) m_keyDeclarations.elementAt(i);
  }

  /**
   * Get the number of "xsl:key" properties.
   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
   *
   * @return the number of "xsl:key" properties.
   */
  public int getKeyCount()
  {
    return (null != m_keyDeclarations) ? m_keyDeclarations.size() : 0;
  }

  /**
   * The "xsl:attribute-set" property.
   * @serial
   */
  private Vector m_attributeSets;

  /**
   * Set the "xsl:attribute-set" property.
   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
   *
   * @param attrSet ElemAttributeSet to add to the list of attribute sets
   */
  public void setAttributeSet(ElemAttributeSet attrSet)
  {

    if (null == m_attributeSets)
    {
      m_attributeSets = new Vector();
    }

    m_attributeSets.addElement(attrSet);
  }

  /**
   * Get an "xsl:attribute-set" property.
   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
   *
   * @param i Index of ElemAttributeSet to get in list
   *
   * @return ElemAttributeSet at the given index
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public ElemAttributeSet getAttributeSet(int i)
          throws ArrayIndexOutOfBoundsException
  {

    if (null == m_attributeSets)
      throw new ArrayIndexOutOfBoundsException();

    return (ElemAttributeSet) m_attributeSets.elementAt(i);
  }

  /**
   * Get the number of "xsl:attribute-set" properties.
   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
   *
   * @return the number of "xsl:attribute-set" properties.
   */
  public int getAttributeSetCount()
  {
    return (null != m_attributeSets) ? m_attributeSets.size() : 0;
  }

  /**
   * The "xsl:variable" and "xsl:param" properties.
   * @serial
   */
  private Vector m_topLevelVariables;

  /**
   * Set the "xsl:variable" property.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @param v ElemVariable object to add to list of top level variables
   */
  public void setVariable(ElemVariable v)
  {

    if (null == m_topLevelVariables)
      m_topLevelVariables = new Vector();

    m_topLevelVariables.addElement(v);
  }
  
  /**
   * Get an "xsl:variable" or "xsl:param" property.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @param qname non-null reference to the qualified name of the variable.
   *
   * @return The ElemVariable with the given name in the list or null
   */
  public ElemVariable getVariableOrParam(QName qname)
  {

    if (null != m_topLevelVariables)
    {
      int n = getVariableOrParamCount();

      for (int i = 0; i < n; i++)
      {
        ElemVariable var = (ElemVariable) getVariableOrParam(i);

        if (var.getName().equals(qname))
          return var;
      }
    }

    return null;
  }


  /**
   * Get an "xsl:variable" property.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @param qname Qualified name of the xsl:variable to get 
   *
   * @return reference to the variable named by qname, or null if not found.
   */
  public ElemVariable getVariable(QName qname)
  {

    if (null != m_topLevelVariables)
    {
      int n = getVariableOrParamCount();

      for (int i = 0; i < n; i++)
      {
        ElemVariable var = getVariableOrParam(i);
        if((var.getXSLToken() == Constants.ELEMNAME_VARIABLE) &&
           (var.getName().equals(qname)))
          return var;
      }
    }

    return null;
  }

  /**
   * Get an "xsl:variable" property.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @param i Index of variable to get in the list
   *
   * @return ElemVariable at the given index in the list 
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public ElemVariable getVariableOrParam(int i) throws ArrayIndexOutOfBoundsException
  {

    if (null == m_topLevelVariables)
      throw new ArrayIndexOutOfBoundsException();

    return (ElemVariable) m_topLevelVariables.elementAt(i);
  }

  /**
   * Get the number of "xsl:variable" properties.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @return the number of "xsl:variable" properties.
   */
  public int getVariableOrParamCount()
  {
    return (null != m_topLevelVariables) ? m_topLevelVariables.size() : 0;
  }

  /**
   * Set an "xsl:param" property.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @param v A non-null ElemParam reference.
   */
  public void setParam(ElemParam v)
  {
    setVariable(v);
  }

  /**
   * Get an "xsl:param" property.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @param qname non-null reference to qualified name of the parameter.
   *
   * @return ElemParam with the given name in the list or null
   */
  public ElemParam getParam(QName qname)
  {

    if (null != m_topLevelVariables)
    {
      int n = getVariableOrParamCount();

      for (int i = 0; i < n; i++)
      {
        ElemVariable var = getVariableOrParam(i);
        if((var.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE) &&
           (var.getName().equals(qname)))
          return (ElemParam)var;
      }
    }

    return null;
  }

  /**
   * The "xsl:template" properties.
   * @serial
   */
  private Vector m_templates;

  /**
   * Set an "xsl:template" property.
   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
   *
   * @param v ElemTemplate to add to list of templates
   */
  public void setTemplate(ElemTemplate v)
  {

    if (null == m_templates)
      m_templates = new Vector();

    m_templates.addElement(v);
    v.setStylesheet(this);
  }

  /**
   * Get an "xsl:template" property.
   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
   *
   * @param i Index of ElemTemplate in the list to get
   *
   * @return ElemTemplate at the given index in the list
   *
   * @throws TransformerException
   */
  public ElemTemplate getTemplate(int i) throws TransformerException
  {

    if (null == m_templates)
      throw new ArrayIndexOutOfBoundsException();

    return (ElemTemplate) m_templates.elementAt(i);
  }

  /**
   * Get the number of "xsl:template" properties.
   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
   *
   * @return the number of "xsl:template" properties.
   */
  public int getTemplateCount()
  {
    return (null != m_templates) ? m_templates.size() : 0;
  }

  /**
   * The "xsl:namespace-alias" properties.
   * @serial
   */
  private Vector m_prefix_aliases;

  /**
   * Set the "xsl:namespace-alias" property.
   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
   *
   * @param na NamespaceAlias elemeent to add to the list
   */
  public void setNamespaceAlias(NamespaceAlias na)
  {

    if (m_prefix_aliases == null)
      m_prefix_aliases = new Vector();

    m_prefix_aliases.addElement(na);
  }

  /**
   * Get an "xsl:namespace-alias" property.
   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
   *
   * @param i Index of NamespaceAlias element to get from the list 
   *
   * @return NamespaceAlias element at the given index in the list
   *
   * @throws ArrayIndexOutOfBoundsException
   */
  public NamespaceAlias getNamespaceAlias(int i)
          throws ArrayIndexOutOfBoundsException
  {

    if (null == m_prefix_aliases)
      throw new ArrayIndexOutOfBoundsException();

    return (NamespaceAlias) m_prefix_aliases.elementAt(i);
  }

  /**
   * Get the number of "xsl:namespace-alias" properties.
   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
   *
   * @return the number of "xsl:namespace-alias" properties.
   */
  public int getNamespaceAliasCount()
  {
    return (null != m_prefix_aliases) ? m_prefix_aliases.size() : 0;
  }

  /**
   * The "non-xsl-top-level" properties.
   * @serial
   */
  private Hashtable m_NonXslTopLevel;

  /**
   * Set found a non-xslt element.
   * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
   *
   * @param name Qualified name of the element
   * @param obj The element object
   */
  public void setNonXslTopLevel(QName name, Object obj)
  {

    if (null == m_NonXslTopLevel)
      m_NonXslTopLevel = new Hashtable();

    m_NonXslTopLevel.put(name, obj);
  }

  /**
   * Get a non-xslt element.
   * @see <a href="http://www.w3.org/TR/xslt#stylesheet-element">stylesheet-element in XSLT Specification</a>
   *
   * @param name Qualified name of the element to get
   *
   * @return The object associate with the given name 
   */
  public Object getNonXslTopLevel(QName name)
  {
    return (null != m_NonXslTopLevel) ? m_NonXslTopLevel.get(name) : null;
  }

  // =========== End top-level XSLT properties ===========

  /**
   * The base URL of the XSL document.
   * @serial
   */
  private String m_href = null;

  /** The doctype-public element.
   *  @serial          */
  private String m_publicId;

  /** The doctype-system element.
   *  @serial          */
  private String m_systemId;

  /**
   * Get the base identifier with which this stylesheet is associated.
   *
   * @return the base identifier with which this stylesheet is associated.
   */
  public String getHref()
  {
    return m_href;
  }

  /**
   * Set the base identifier with which this stylesheet is associated.
   *
   * @param baseIdent the base identifier with which this stylesheet is associated.
   */
  public void setHref(String baseIdent)
  {
    m_href = baseIdent;
  }

  /**
   * Set the location information for this element.
   *
   * @param locator SourceLocator object with location information  
   */
  public void setLocaterInfo(SourceLocator locator)
  {

    if (null != locator)
    {
      m_publicId = locator.getPublicId();
      m_systemId = locator.getSystemId();

      if (null != m_systemId)
      {
        try
        {
          m_href = SystemIDResolver.getAbsoluteURI(m_systemId, null);
        }
        catch (TransformerException se)
        {

          // Ignore this for right now
        }
      }

      super.setLocaterInfo(locator);
    }
  }

  /**
   * The root of the stylesheet, where all the tables common
   * to all stylesheets are kept.
   * @serial
   */
  private StylesheetRoot m_stylesheetRoot;

  /**
   * Get the root of the stylesheet, where all the tables common
   * to all stylesheets are kept.
   *
   * @return the root of the stylesheet
   */
  public StylesheetRoot getStylesheetRoot()
  {
    return m_stylesheetRoot;
  }

  /**
   * Set the root of the stylesheet, where all the tables common
   * to all stylesheets are kept.
   *
   * @param v the root of the stylesheet
   */
  public void setStylesheetRoot(StylesheetRoot v)
  {
    m_stylesheetRoot = v;
  }

  /**
   * The parent of the stylesheet.  This will be null if this
   * is the root stylesheet.
   * @serial
   */
  private Stylesheet m_stylesheetParent;

  /**
   * Get the parent of the stylesheet.  This will be null if this
   * is the root stylesheet.
   *
   * @return the parent of the stylesheet.
   */
  public Stylesheet getStylesheetParent()
  {
    return m_stylesheetParent;
  }

  /**
   * Set the parent of the stylesheet.  This should be null if this
   * is the root stylesheet.
   *
   * @param v the parent of the stylesheet.
   */
  public void setStylesheetParent(Stylesheet v)
  {
    m_stylesheetParent = v;
  }

  /**
   * Get the owning aggregated stylesheet, or this
   * stylesheet if it is aggregated.
   *
   * @return the owning aggregated stylesheet or itself
   */
  public StylesheetComposed getStylesheetComposed()
  {

    Stylesheet sheet = this;

    while (!sheet.isAggregatedType())
    {
      sheet = sheet.getStylesheetParent();
    }

    return (StylesheetComposed) sheet;
  }

  /**
   * Get the type of the node.  We'll pretend we're a Document.
   *
   * @return the type of the node: document node.
   */
  public short getNodeType()
  {
    return DTM.DOCUMENT_NODE;
  }

  /**
   * Get an integer representation of the element type.
   *
   * @return An integer representation of the element, defined in the
   *     Constants class.
   * @see org.apache.xalan.templates.Constants
   */
  public int getXSLToken()
  {
    return Constants.ELEMNAME_STYLESHEET;
  }

  /**
   * Return the node name.
   *
   * @return The node name
   */
  public String getNodeName()
  {
    return Constants.ELEMNAME_STYLESHEET_STRING;
  }

  /**
   * Replace an "xsl:template" property.
   * This is a hook for CompilingStylesheetHandler, to allow
   * us to access a template, compile it, instantiate it,
   * and replace the original with the compiled instance.
   * ADDED 9/5/2000 to support compilation experiment
   *
   * @param v Compiled template to replace with
   * @param i Index of template to be replaced
   *
   * @throws TransformerException
   */
  public void replaceTemplate(ElemTemplate v, int i) throws TransformerException
  {

    if (null == m_templates)
      throw new ArrayIndexOutOfBoundsException();

    replaceChild(v, (ElemTemplateElement)m_templates.elementAt(i));
    m_templates.setElementAt(v, i);
    v.setStylesheet(this);
  }
  
    /**
     * Call the children visitors.
     * @param visitor The visitor whose appropriate method will be called.
     */
    protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
    {
      int s = getImportCount();
      for (int j = 0; j < s; j++)
      {
      	getImport(j).callVisitors(visitor);
      }
   
      s = getIncludeCount();
      for (int j = 0; j < s; j++)
      {
      	getInclude(j).callVisitors(visitor);
      }

      s = getOutputCount();
      for (int j = 0; j < s; j++)
      {
        visitor.visitTopLevelInstruction(getOutput(j));
      }

      // Next, add in the attribute-set elements

      s = getAttributeSetCount();
      for (int j = 0; j < s; j++)
      {
      	ElemAttributeSet attrSet = getAttributeSet(j);
        if (visitor.visitTopLevelInstruction(attrSet))
        {
          attrSet.callChildVisitors(visitor);
        }
      }
      // Now the decimal-formats

      s = getDecimalFormatCount();
      for (int j = 0; j < s; j++)
      {
        visitor.visitTopLevelInstruction(getDecimalFormat(j));
      }

      // Now the keys

      s = getKeyCount();
      for (int j = 0; j < s; j++)
      {
        visitor.visitTopLevelInstruction(getKey(j));
      }

      // And the namespace aliases

      s = getNamespaceAliasCount();
      for (int j = 0; j < s; j++)
      {
        visitor.visitTopLevelInstruction(getNamespaceAlias(j));
      }

      // Next comes the templates

      s = getTemplateCount();
      for (int j = 0; j < s; j++)
      {
        try
        {
          ElemTemplate template = getTemplate(j);
          if (visitor.visitTopLevelInstruction(template))
          {
            template.callChildVisitors(visitor);
          }
        }
        catch (TransformerException te)
        {
          throw new org.apache.xml.utils.WrappedRuntimeException(te);
        }
      }

      // Then, the variables

      s = getVariableOrParamCount();
      for (int j = 0; j < s; j++)
      {
      	ElemVariable var = getVariableOrParam(j);
        if (visitor.visitTopLevelVariableOrParamDecl(var))
        {
          var.callChildVisitors(visitor);
        }
      }

      // And lastly the whitespace preserving and stripping elements

      s = getStripSpaceCount();
      for (int j = 0; j < s; j++)
      {
        visitor.visitTopLevelInstruction(getStripSpace(j));
      }

      s = getPreserveSpaceCount();
      for (int j = 0; j < s; j++)
      {
        visitor.visitTopLevelInstruction(getPreserveSpace(j));
      }
      
      if(null != m_NonXslTopLevel)
      {
      	java.util.Enumeration enum = m_NonXslTopLevel.elements();
      	while(enum.hasMoreElements())
      	{
      	  ElemTemplateElement elem = (ElemTemplateElement)enum.nextElement();
          if (visitor.visitTopLevelInstruction(elem))
          {
            elem.callChildVisitors(visitor);
          }
      		
      	}
      }
    }
        
          
  /**
   * Accept a visitor and call the appropriate method 
   * for this class.
   * 
   * @param visitor The visitor whose appropriate method will be called.
   * @return true if the children of the object should be visited.
   */
  protected boolean accept(XSLTVisitor visitor)
  {
  	return visitor.visitStylesheet(this);
  }

  
}
