You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by ga...@locus.apache.org on 2000/11/30 10:57:40 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/transformer KeyManager.java TransformerImpl.java

garyp       00/11/30 01:57:39

  Modified:    java/src/org/apache/xalan/processor
                        CompilingStylesheetHandler.java
                        ProcessorDecimalFormat.java ProcessorImport.java
                        ProcessorInclude.java ProcessorKey.java
                        ProcessorNamespaceAlias.java
                        ProcessorOutputElem.java
                        ProcessorPreserveSpace.java
                        ProcessorStripSpace.java StylesheetHandler.java
               java/src/org/apache/xalan/res XSLTErrorResources.java
               java/src/org/apache/xalan/templates
                        DecimalFormatProperties.java ElemAttributeSet.java
                        ElemForEach.java ElemTemplate.java
                        ElemTemplateElement.java ElemUse.java
                        ElemVariable.java FuncFormatNumb.java
                        KeyDeclaration.java NamespaceAlias.java
                        OutputFormatExtended.java Stylesheet.java
                        StylesheetComposed.java StylesheetRoot.java
                        TemplateList.java WhiteSpaceInfo.java
               java/src/org/apache/xalan/transformer KeyManager.java
                        TransformerImpl.java
  Added:       java/src/org/apache/xalan/templates Recomposable.java
                        RecomposableBase.java RecomposableImpl.java
  Removed:     java/src/org/apache/xalan/templates WhitespaceList.java
  Log:
  Implement new recompose() design.
  Correct template match order to precedence, then priority.
  Check for circular includes as well as import.
  Improve some recompositions.
  
  Revision  Changes    Path
  1.19      +2 -2      xml-xalan/java/src/org/apache/xalan/processor/CompilingStylesheetHandler.java
  
  Index: CompilingStylesheetHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/CompilingStylesheetHandler.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- CompilingStylesheetHandler.java	2000/11/23 04:57:23	1.18
  +++ CompilingStylesheetHandler.java	2000/11/30 09:57:29	1.19
  @@ -156,7 +156,7 @@
             int nIncludes = sheet.getIncludeCountComposed();
             for(int k = nIncludes-1; k >= -1; k--)
             {
  -            Stylesheet included = (-1 == k) ? sheet : sheet.getIncludeComposed(k);
  +            Stylesheet included = sheet.getIncludeComposed(k);
               int n = included.getTemplateCount();
               for(int i = 0; i < n; i++)
               {
  @@ -545,7 +545,7 @@
       org.apache.xml.utils.QName[] attributeSetsNames=((org.apache.xalan.templates.ElemUse)ete).getUseAttributeSets();
       if(null != attributeSetsNames)
       {
  -        org.apache.xalan.templates.StylesheetComposed stylesheet=ete.getStylesheetComposed();
  +        org.apache.xalan.templates.StylesheetRoot stylesheet=ete.getStylesheetRoot();
           int nNames = attributeSetsNames.length;
           for(int i = 0; i < nNames; i++)
           {
  
  
  
  1.5       +1 -1      xml-xalan/java/src/org/apache/xalan/processor/ProcessorDecimalFormat.java
  
  Index: ProcessorDecimalFormat.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorDecimalFormat.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ProcessorDecimalFormat.java	2000/11/22 23:25:51	1.4
  +++ ProcessorDecimalFormat.java	2000/11/30 09:57:29	1.5
  @@ -99,7 +99,7 @@
               throws org.xml.sax.SAXException
     {
   
  -    DecimalFormatProperties dfp = new DecimalFormatProperties();
  +    DecimalFormatProperties dfp = new DecimalFormatProperties(handler.nextUid());
   
       setPropertiesFromAttributes(handler, rawName, attributes, dfp);
       handler.getStylesheet().setDecimalFormat(dfp);
  
  
  
  1.10      +14 -44    xml-xalan/java/src/org/apache/xalan/processor/ProcessorImport.java
  
  Index: ProcessorImport.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorImport.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ProcessorImport.java	2000/11/23 04:57:23	1.9
  +++ ProcessorImport.java	2000/11/30 09:57:29	1.10
  @@ -86,53 +86,23 @@
   {
   
     /**
  -   * Receive notification of the start of an xsl:import element.
  +   * Get the stylesheet type associated with an imported stylesheet
      *
  -   * @param handler The calling StylesheetHandler/TemplatesBuilder.
  -   * @param uri The Namespace URI, or the empty string if the
  -   *        element has no Namespace URI or if Namespace
  -   *        processing is not being performed.
  -   * @param localName The local name (without prefix), or the
  -   *        empty string if Namespace processing is not being
  -   *        performed.
  -   * @param rawName The raw XML 1.0 name (with prefix), or the
  -   *        empty string if raw names are not available.
  -   * @param attributes The attributes attached to the element.  If
  -   *        there are no attributes, it shall be an empty
  -   *        Attributes object.
  +   * @return the type of the stylesheet
      */
  -  public void startElement(
  -          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
  -            throws org.xml.sax.SAXException
  +  protected int getStylesheetType()
     {
  -
  -    setPropertiesFromAttributes(handler, rawName, attributes, this);
  -
  -    String hrefUrl = getHref();
  -
  -    if (handler.importStackContains(hrefUrl))
  -    {
  -      throw new org.xml.sax.SAXException(
  -        XSLMessages.createMessage(
  -          XSLTErrorResources.ER_IMPORTING_ITSELF, new Object[]{ hrefUrl }));  //"(StylesheetHandler) "+hrefUrl+" is directly or indirectly importing itself!");
  -    }
  -
  -    handler.pushImportURL(hrefUrl);
  -
  -    int savedStylesheetType = handler.getStylesheetType();
  -
  -    handler.setStylesheetType(StylesheetHandler.STYPE_IMPORT);
  -    handler.pushNewNamespaceSupport();
  +    return StylesheetHandler.STYPE_IMPORT;
  +  }
   
  -    try
  -    {
  -      parse(handler, uri, localName, rawName, attributes);
  -    }
  -    finally
  -    {
  -      handler.setStylesheetType(savedStylesheetType);
  -      handler.popImportURL();
  -      handler.popNamespaceSupport();
  -    }
  +  /**
  +   * Get the error number associated with this type of stylesheet importing itself
  +   *
  +   * @return the appropriate error number
  +   */
  +  protected int getStylesheetInclErr()
  +  {
  +    return XSLTErrorResources.ER_IMPORTING_ITSELF;
     }
  +
   }
  
  
  
  1.14      +34 -3     xml-xalan/java/src/org/apache/xalan/processor/ProcessorInclude.java
  
  Index: ProcessorInclude.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorInclude.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ProcessorInclude.java	2000/11/23 04:57:24	1.13
  +++ ProcessorInclude.java	2000/11/30 09:57:30	1.14
  @@ -122,6 +122,26 @@
     }
   
     /**
  +   * Get the stylesheet type associated with an included stylesheet
  +   *
  +   * @return the type of the stylesheet
  +   */
  +  protected int getStylesheetType()
  +  {
  +    return StylesheetHandler.STYPE_INCLUDE;
  +  }
  +
  +  /**
  +   * Get the error number associated with this type of stylesheet including itself
  +   *
  +   * @return the appropriate error number
  +   */
  +  protected int getStylesheetInclErr()
  +  {
  +    return XSLTErrorResources.ER_STYLESHEET_INCLUDES_ITSELF;
  +  }
  +
  +  /**
      * Receive notification of the start of an xsl:include element.
      *
      * @param handler The calling StylesheetHandler/TemplatesBuilder.
  @@ -145,11 +165,23 @@
               throws org.xml.sax.SAXException
     {
   
  +
       setPropertiesFromAttributes(handler, rawName, attributes, this);
   
  +    String hrefUrl = getHref();
  +
  +    if (handler.importStackContains(hrefUrl))
  +    {
  +      throw new org.xml.sax.SAXException(
  +        XSLMessages.createMessage(
  +          getStylesheetInclErr(), new Object[]{ hrefUrl }));  //"(StylesheetHandler) "+hrefUrl+" is directly or indirectly importing itself!");
  +    }
  +
  +    handler.pushImportURL(hrefUrl);
  +
       int savedStylesheetType = handler.getStylesheetType();
   
  -    handler.setStylesheetType(StylesheetHandler.STYPE_INCLUDE);
  +    handler.setStylesheetType(this.getStylesheetType());
       handler.pushNewNamespaceSupport();
   
       try
  @@ -159,9 +191,8 @@
       finally
       {
         handler.setStylesheetType(savedStylesheetType);
  +      handler.popImportURL();
         handler.popNamespaceSupport();
  -
  -      // handler.popStylesheet();
       }
     }
   
  
  
  
  1.9       +1 -1      xml-xalan/java/src/org/apache/xalan/processor/ProcessorKey.java
  
  Index: ProcessorKey.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorKey.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ProcessorKey.java	2000/11/22 23:25:52	1.8
  +++ ProcessorKey.java	2000/11/30 09:57:30	1.9
  @@ -103,7 +103,7 @@
               throws org.xml.sax.SAXException
     {
   
  -    KeyDeclaration kd = new KeyDeclaration();
  +    KeyDeclaration kd = new KeyDeclaration(handler.getStylesheet(), handler.nextUid());
   
       kd.setDOMBackPointer(handler.getOriginatingNode());
       kd.setLocaterInfo(handler.getLocator());
  
  
  
  1.6       +1 -1      xml-xalan/java/src/org/apache/xalan/processor/ProcessorNamespaceAlias.java
  
  Index: ProcessorNamespaceAlias.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorNamespaceAlias.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ProcessorNamespaceAlias.java	2000/11/22 23:25:53	1.5
  +++ ProcessorNamespaceAlias.java	2000/11/30 09:57:30	1.6
  @@ -99,7 +99,7 @@
               throws org.xml.sax.SAXException
     {
   
  -    NamespaceAlias na = new NamespaceAlias();
  +    NamespaceAlias na = new NamespaceAlias(handler.nextUid());
   
       setPropertiesFromAttributes(handler, rawName, attributes, na);
       handler.getStylesheet().setNamespaceAlias(na);
  
  
  
  1.8       +1 -1      xml-xalan/java/src/org/apache/xalan/processor/ProcessorOutputElem.java
  
  Index: ProcessorOutputElem.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorOutputElem.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ProcessorOutputElem.java	2000/11/22 23:25:53	1.7
  +++ ProcessorOutputElem.java	2000/11/30 09:57:30	1.8
  @@ -96,7 +96,7 @@
               throws org.xml.sax.SAXException
     {
   
  -    OutputFormatExtended ofe = new OutputFormatExtended();
  +    OutputFormatExtended ofe = new OutputFormatExtended(handler.nextUid());
   
       setPropertiesFromAttributes(handler, rawName, attributes, ofe);
       handler.getStylesheet().setOutput(ofe);
  
  
  
  1.7       +1 -5      xml-xalan/java/src/org/apache/xalan/processor/ProcessorPreserveSpace.java
  
  Index: ProcessorPreserveSpace.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorPreserveSpace.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ProcessorPreserveSpace.java	2000/11/22 23:25:54	1.6
  +++ ProcessorPreserveSpace.java	2000/11/30 09:57:30	1.7
  @@ -135,11 +135,7 @@
       for (int i = 0; i < xpaths.size(); i++)
       {
         WhiteSpaceInfo wsi = new WhiteSpaceInfo((XPath) xpaths.elementAt(i), false, thisSheet);
  -
  -      // We do the push and pop here to force StylesheetHandler to assign us a Uid.
  -
  -      handler.pushElemTemplateElement(wsi);
  -      wsi = (WhiteSpaceInfo) handler.popElemTemplateElement();
  +      wsi.setUid(handler.nextUid());
   
         thisSheet.setPreserveSpaces(wsi);
       }
  
  
  
  1.7       +1 -6      xml-xalan/java/src/org/apache/xalan/processor/ProcessorStripSpace.java
  
  Index: ProcessorStripSpace.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/ProcessorStripSpace.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ProcessorStripSpace.java	2000/11/22 23:25:54	1.6
  +++ ProcessorStripSpace.java	2000/11/30 09:57:30	1.7
  @@ -102,12 +102,7 @@
       for (int i = 0; i < xpaths.size(); i++)
       {
         WhiteSpaceInfo wsi = new WhiteSpaceInfo((XPath) xpaths.elementAt(i), true, thisSheet);
  -
  -      // We do the push and pop here to force StylesheetHandler to assign us a Uid
  -      // like a real ElementTemplateElement.
  -
  -      handler.pushElemTemplateElement(wsi);
  -      wsi = (WhiteSpaceInfo) handler.popElemTemplateElement();
  +      wsi.setUid(handler.nextUid());
   
         thisSheet.setStripSpaces(wsi);
       }
  
  
  
  1.28      +12 -2     xml-xalan/java/src/org/apache/xalan/processor/StylesheetHandler.java
  
  Index: StylesheetHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/processor/StylesheetHandler.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- StylesheetHandler.java	2000/11/23 04:57:24	1.27
  +++ StylesheetHandler.java	2000/11/30 09:57:30	1.28
  @@ -1231,10 +1231,20 @@
       }
     }
   
  -  /** NEEDSDOC Field m_docOrderCount */
  +  /** An increasing number that is used to indicate the order in which this element
  +   *  was encountered during the parse of the XSLT tree.
  +   */
     private int m_docOrderCount = 0;
   
     /**
  +   * Returns the next m_docOrderCount number and increments the number for future use.
  +   */
  +  int nextUid()
  +  {
  +    return m_docOrderCount++;
  +  }
  +
  +  /**
      * Push the current XSLTElementProcessor to the top of the stack.  As a
      * side-effect, set the document order index (simply because this is a
      * convenient place to set it).
  @@ -1246,7 +1256,7 @@
     {
   
       if (elem.getUid() == -1)
  -      elem.setUid(m_docOrderCount++);
  +      elem.setUid(nextUid());
   
       m_elems.push(elem);
     }
  
  
  
  1.11      +2 -2      xml-xalan/java/src/org/apache/xalan/res/XSLTErrorResources.java
  
  Index: XSLTErrorResources.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/res/XSLTErrorResources.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- XSLTErrorResources.java	2000/11/23 04:57:30	1.10
  +++ XSLTErrorResources.java	2000/11/30 09:57:31	1.11
  @@ -1244,7 +1244,7 @@
     static
     {
       contents[WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED + MAX_CODE][1] =
  -      "Only one default xsl:decimal-format declaration is allowed. The last one will be used.";
  +      "Only one default xsl:decimal-format declaration is allowed.";
     }
   
     /** WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE          */
  @@ -1253,7 +1253,7 @@
     static
     {
       contents[WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE + MAX_CODE][1] =
  -      "xsl:decimal-format names must be unique. The last one will be used.";
  +      "xsl:decimal-format names must be unique. Name \"{0}\" has been duplicated.";
     }
   
     /** WG_ILLEGAL_ATTRIBUTE          */
  
  
  
  1.7       +28 -2     xml-xalan/java/src/org/apache/xalan/templates/DecimalFormatProperties.java
  
  Index: DecimalFormatProperties.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/DecimalFormatProperties.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- DecimalFormatProperties.java	2000/11/23 04:57:47	1.6
  +++ DecimalFormatProperties.java	2000/11/30 09:57:32	1.7
  @@ -93,7 +93,7 @@
    * </pre>
    * @see <a href="http://www.w3.org/TR/xslt#format-number">format-number in XSLT Specification</a>
    */
  -public class DecimalFormatProperties
  +public class DecimalFormatProperties implements RecomposableBase
   {
   
     /** NEEDSDOC Field m_dfs          */
  @@ -103,7 +103,7 @@
      * Constructor DecimalFormatProperties
      *
      */
  -  public DecimalFormatProperties()
  +  public DecimalFormatProperties(int docOrderNumber)
     {
   
       m_dfs = new java.text.DecimalFormatSymbols();
  @@ -111,6 +111,8 @@
       // Set default values, they can be overiden if necessary.  
       m_dfs.setInfinity(Constants.ATTRVAL_INFINITY);
       m_dfs.setNaN(Constants.ATTRVAL_NAN);
  +
  +    m_docOrderNumber = docOrderNumber;
     }
   
     /**
  @@ -412,4 +414,28 @@
     {
       return m_dfs.getPatternSeparator();
     }
  +
  +  /**
  +   *  The document order number, analogous to the same field in an ElemTemplateElement.
  +   */
  +  protected int m_docOrderNumber;
  +
  +  /**
  +   * Get the UID (document order index).
  +   *
  +   * @return Index of this child
  +   */
  +  public int getUid()
  +  {
  +    return m_docOrderNumber;
  +  }
  +
  +  /**
  +   * This function is called to recompose() all of the decimal format properties elements.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeDecimalFormats(this);
  +  }
  +
   }
  
  
  
  1.5       +11 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemAttributeSet.java
  
  Index: ElemAttributeSet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemAttributeSet.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ElemAttributeSet.java	2000/11/23 04:57:47	1.4
  +++ ElemAttributeSet.java	2000/11/30 09:57:32	1.5
  @@ -202,4 +202,15 @@
   
       return super.appendChild(newChild);
     }
  +
  +  /**
  +   * This function is called during recomposition to
  +   * control how this element is composed.
  +   * @param root The root stylesheet for this transformation.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeAttributeSets(this);
  +  }
  +
   }
  
  
  
  1.10      +1 -1      xml-xalan/java/src/org/apache/xalan/templates/ElemForEach.java
  
  Index: ElemForEach.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemForEach.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ElemForEach.java	2000/11/23 04:57:51	1.9
  +++ ElemForEach.java	2000/11/30 09:57:32	1.10
  @@ -408,7 +408,7 @@
           {
             if (needToFindTemplate)
             {
  -            template = tl.getTemplate(xctxt, child, mode, quiet);
  +            template = tl.getTemplate(xctxt, child, mode, -1, quiet);
   
               // If that didn't locate a node, fall back to a default template rule.
               // See http://www.w3.org/TR/xslt#built-in-rule.
  
  
  
  1.7       +11 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemTemplate.java
  
  Index: ElemTemplate.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplate.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ElemTemplate.java	2000/11/23 04:57:53	1.6
  +++ ElemTemplate.java	2000/11/30 09:57:32	1.7
  @@ -381,4 +381,15 @@
         //"sourceNode is null in handleApplyTemplatesInstruction!");
       }
     }
  +
  +  /**
  +   * This function is called during recomposition to
  +   * control how this element is composed.
  +   * @param root The root stylesheet for this transformation.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeTemplates(this);
  +  }
  +
   }
  
  
  
  1.24      +34 -1     xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java
  
  Index: ElemTemplateElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- ElemTemplateElement.java	2000/11/23 04:57:53	1.23
  +++ ElemTemplateElement.java	2000/11/30 09:57:32	1.24
  @@ -109,7 +109,7 @@
    * @see Stylesheet
    */
   public class ElemTemplateElement extends UnImplNode
  -        implements PrefixResolver, Serializable, SourceLocator
  +        implements PrefixResolver, Serializable, SourceLocator, Recomposable
   {
   
     /**
  @@ -223,6 +223,12 @@
     }
   
     /**
  +   * This function is called during recomposition to
  +   * control how this element is composed.
  +   */
  +  public void recompose(StylesheetRoot root){}
  +
  +  /**
      * This function is called after everything else has been
      * recomposed, and allows the template to set remaining
      * values that may be based on some other property that
  @@ -1114,4 +1120,31 @@
     {
       m_DOMBackPointer = n;
     }
  +
  +  /**
  +   * Compares this object with the specified object for precedence order.
  +   * The order is determined by the getImportCountComposed() of the containing
  +   * composed stylesheet and the getUid() of this element.
  +   * Returns a negative integer, zero, or a positive integer as this
  +   * object is less than, equal to, or greater than the specified object.
  +   * @param o The object to be compared to this object
  +   * @returns a negative integer, zero, or a positive integer as this object is
  +   *          less than, equal to, or greater than the specified object.
  +   * @throws ClassCastException if the specified object's
  +   *         type prevents it from being compared to this Object.
  +   */
  +  public int compareTo(Object o) throws ClassCastException {
  +    
  +    Recomposable ro = (Recomposable) o;
  +    int roPrecedence = ro.getStylesheetComposed().getImportCountComposed();
  +    int myPrecedence = this.getStylesheetComposed().getImportCountComposed();
  +
  +    if (myPrecedence < roPrecedence)
  +      return -1;
  +    else if (myPrecedence > roPrecedence)
  +      return 1;
  +    else
  +      return this.getUid() - ro.getUid();
  +  }
  +
   }
  
  
  
  1.7       +2 -2      xml-xalan/java/src/org/apache/xalan/templates/ElemUse.java
  
  Index: ElemUse.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemUse.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ElemUse.java	2000/11/23 04:57:54	1.6
  +++ ElemUse.java	2000/11/30 09:57:32	1.7
  @@ -159,7 +159,7 @@
      * @throws TransformerException
      */
     private void applyAttrSets(
  -          TransformerImpl transformer, StylesheetComposed stylesheet, QName attributeSetsNames[], Node sourceNode, QName mode)
  +          TransformerImpl transformer, StylesheetRoot stylesheet, QName attributeSetsNames[], Node sourceNode, QName mode)
               throws TransformerException
     {
   
  @@ -215,7 +215,7 @@
   
       if (null != m_attributeSetsNames)
       {
  -      applyAttrSets(transformer, getStylesheetRoot().getStylesheetComposed(),
  +      applyAttrSets(transformer, getStylesheetRoot(),
                       m_attributeSetsNames, sourceNode, mode);
       }
     }
  
  
  
  1.7       +11 -0     xml-xalan/java/src/org/apache/xalan/templates/ElemVariable.java
  
  Index: ElemVariable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemVariable.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ElemVariable.java	2000/11/23 04:57:55	1.6
  +++ ElemVariable.java	2000/11/30 09:57:32	1.7
  @@ -293,4 +293,15 @@
   
       return var;
     }
  +
  +  /**
  +   * This function is called during recomposition to
  +   * control how this element is composed.
  +   * @param root The root stylesheet for this transformation.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeVariables(this);
  +  }
  +
   }
  
  
  
  1.11      +1 -1      xml-xalan/java/src/org/apache/xalan/templates/FuncFormatNumb.java
  
  Index: FuncFormatNumb.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/FuncFormatNumb.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- FuncFormatNumb.java	2000/11/23 04:57:55	1.10
  +++ FuncFormatNumb.java	2000/11/30 09:57:32	1.11
  @@ -97,7 +97,7 @@
       // A bit of an ugly hack to get our context.
       ElemTemplateElement templElem =
         (ElemTemplateElement) xctxt.getNamespaceContext();
  -    StylesheetComposed ss = templElem.getStylesheetComposed();
  +    StylesheetRoot ss = templElem.getStylesheetRoot();
       java.text.DecimalFormat formatter = null;
       java.text.DecimalFormatSymbols dfs = null;
       double num = getArg0().execute(xctxt).num();
  
  
  
  1.5       +23 -0     xml-xalan/java/src/org/apache/xalan/templates/KeyDeclaration.java
  
  Index: KeyDeclaration.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/KeyDeclaration.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- KeyDeclaration.java	2000/11/23 04:57:56	1.4
  +++ KeyDeclaration.java	2000/11/30 09:57:32	1.5
  @@ -72,6 +72,18 @@
   {
   
     /**
  +   * Constructs a new element representing the xsl:key.  The parameters
  +   * are needed to prioritize this key element as part of the recomposing
  +   * process.  For this element, they are not automatically created
  +   * because the element is never added on to the stylesheet parent.
  +   */
  +  public KeyDeclaration(Stylesheet parentNode, int docOrderNumber)
  +  {
  +    m_parentNode = parentNode;
  +    setUid(docOrderNumber);
  +  }
  +
  +  /**
      * The "name" property.
      */
     private QName m_name;
  @@ -195,4 +207,15 @@
     {
       return m_buildState;
     }
  +
  +  /**
  +   * This function is called during recomposition to
  +   * control how this element is composed.
  +   * @param root The root stylesheet for this transformation.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeKeys(this);
  +  }
  +
   }
  
  
  
  1.3       +35 -1     xml-xalan/java/src/org/apache/xalan/templates/NamespaceAlias.java
  
  Index: NamespaceAlias.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/NamespaceAlias.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NamespaceAlias.java	2000/10/30 18:50:04	1.2
  +++ NamespaceAlias.java	2000/11/30 09:57:32	1.3
  @@ -62,8 +62,18 @@
    * that one namespace URI is an alias for another namespace URI.
    * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
    */
  -public class NamespaceAlias
  +public class NamespaceAlias implements RecomposableBase
   {
  +  
  +  /**
  +   * Constructor NamespaceAlias
  +   *
  +   */
  +  public NamespaceAlias(int docOrderNumber)
  +  {
  +    super();
  +    m_docOrderNumber = docOrderNumber;
  +  }
   
     /**
      * The "stylesheet-prefix" attribute
  @@ -114,4 +124,28 @@
     {
       return m_ResultPrefix;
     }
  +
  +  /**
  +   *  The document order number, analogous to the same field in an ElemTemplateElement.
  +   */
  +  protected int m_docOrderNumber;
  +
  +  /**
  +   * Get the UID (document order index).
  +   *
  +   * @return Index of this child
  +   */
  +  public int getUid()
  +  {
  +    return m_docOrderNumber;
  +  }
  +
  +  /**
  +   * This function is called to recompose() all of the namespace alias properties elements.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeNamespaceAliases(this);
  +  }
  +
   }
  
  
  
  1.13      +28 -2     xml-xalan/java/src/org/apache/xalan/templates/OutputFormatExtended.java
  
  Index: OutputFormatExtended.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/OutputFormatExtended.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- OutputFormatExtended.java	2000/11/23 05:56:50	1.12
  +++ OutputFormatExtended.java	2000/11/30 09:57:32	1.13
  @@ -72,7 +72,7 @@
    * stylesheet.
    */
   public class OutputFormatExtended extends OutputFormat
  -	implements java.io.Serializable
  +	implements java.io.Serializable, RecomposableBase
   {
   
     // Flag to tell us when to record that an attribute 
  @@ -238,7 +238,7 @@
     /**
      * Constructs a new output format with the default values.
      */
  -  public OutputFormatExtended()
  +  public OutputFormatExtended(int docOrderNumber)
     {
   
       super();
  @@ -246,6 +246,23 @@
       m_shouldRecordHasBeenSet = true;
   
       setPreserveSpace(true);
  +
  +    m_docOrderNumber = docOrderNumber;
  +  }
  +
  +  /**
  +   *  The document order number, analogous to the same field in an ElemTemplateElement.
  +   */
  +  protected int m_docOrderNumber;
  +
  +  /**
  +   * Get the UID (document order index).
  +   *
  +   * @return Index of this child
  +   */
  +  public int getUid()
  +  {
  +    return m_docOrderNumber;
     }
   
     /**
  @@ -625,4 +642,13 @@
   
       super.setNonEscapingElements(nonEscapingElements);
     }
  +
  +  /**
  +   * This function is called to recompose all of the output format extended elements.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeOutput(this);
  +  }
  +
   }
  
  
  
  1.17      +34 -15    xml-xalan/java/src/org/apache/xalan/templates/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/Stylesheet.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- Stylesheet.java	2000/11/23 04:57:56	1.16
  +++ Stylesheet.java	2000/11/30 09:57:32	1.17
  @@ -749,9 +749,9 @@
     }
   
     /**
  -   * The "xsl:output" property.
  +   * The "xsl:output" properties.  This is a vector of OutputFormatExtended objects.
      */
  -  private OutputFormatExtended m_output;
  +  private Vector m_output;
   
     /**
      * Set the "xsl:output" property.
  @@ -761,18 +761,43 @@
      */
     public void setOutput(OutputFormatExtended v)
     {
  -    m_output = 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>
  +   *
  +   * NEEDSDOC @param i
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   *
  +   * @throws ArrayIndexOutOfBoundsException
  +   */
  +  public OutputFormatExtended getOutput(int i) throws ArrayIndexOutOfBoundsException
  +  {
  +
  +    if (null == m_output)
  +      throw new ArrayIndexOutOfBoundsException();
  +
  +    return (OutputFormatExtended) m_output.elementAt(i);
     }
   
     /**
  -   * Get the "xsl:output" property.
  +   * Get the number of "xsl:output" properties.
      * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
      *
      * NEEDSDOC ($objectName$) @return
      */
  -  public OutputFormatExtended getOutput()
  +  public int getOutputCount()
     {
  -    return m_output;
  +    return (null != m_output)
  +           ? m_output.size() : 0;
     }
   
     /**
  @@ -844,9 +869,7 @@
         m_attributeSets = new Vector();
       }
   
  -    // Insert elements by order of importance so that
  -    // during recompose, they get properly overiden. 
  -    m_attributeSets.insertElementAt(attrSet, 0);
  +    m_attributeSets.addElement(attrSet);
     }
   
     /**
  @@ -897,9 +920,7 @@
       if (null == m_topLevelVariables)
         m_topLevelVariables = new Vector();
   
  -    // Always insert variables by order of importance so that 
  -    // during recompose, they get properly overiden. 
  -    m_topLevelVariables.insertElementAt(v, 0);
  +    m_topLevelVariables.addElement(v);
     }
     
     /**
  @@ -1093,9 +1114,7 @@
       if (m_prefix_aliases == null)
         m_prefix_aliases = new Vector();
   
  -    // Always insert elements by order of importance so that 
  -    // during recompose, they get properly overiden.
  -    m_prefix_aliases.insertElementAt(na, 0);
  +    m_prefix_aliases.addElement(na);
     }
   
     /**
  
  
  
  1.20      +121 -571  xml-xalan/java/src/org/apache/xalan/templates/StylesheetComposed.java
  
  Index: StylesheetComposed.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/StylesheetComposed.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- StylesheetComposed.java	2000/11/23 04:57:57	1.19
  +++ StylesheetComposed.java	2000/11/30 09:57:32	1.20
  @@ -117,22 +117,121 @@
       return true;
     }
   
  +  /**
  +   * Adds all recomposable values for this precedence level into the recomposableElements Vector
  +   * that was passed in as the first parameter.  All elements added to the
  +   * recomposableElements vector should implement the Recomposable interface.  That is,
  +   * we must be able to determine the precedence level and document order sequence.  Also,
  +   * they must have a compareTo method so that we can sort the Vector members according
  +   * to precedence and document order.  If the value to be added does not implement
  +   * Recomposable, then it must at least implement RecomposableBase.  In that case,
  +   * we wrap it in a RecomposableImpl object that adds the precedence and document order
  +   * features.
  +   * @param recomposableElements a Vector of Recomposable objects that we will add all of
  +   *        our recomposable objects to.
  +   */
  +  public void recompose(Vector recomposableElements) throws TransformerException
  +  {
  +
  +    recomposeImports();         // Calculate the number of this import.
  +    recomposeIncludes(this);    // Build the global include list for this stylesheet.
  +
  +    // Now add in all of the recomposable elements at this precedence level
  +
  +    int n = getIncludeCountComposed();
  +
  +    for (int i = -1; i < n; i++)
  +    {
  +      Stylesheet included = getIncludeComposed(i);
  +
  +      // Add in the output elements
  +
  +      int s = included.getOutputCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        OutputFormatExtended ofe = included.getOutput(j);
  +        recomposableElements.addElement(new RecomposableImpl(this, ofe.getUid(), ofe));
  +      }
  +
  +      // Next, add in the attribute-set elements
  +
  +      s = included.getAttributeSetCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        recomposableElements.addElement(included.getAttributeSet(j));
  +      }
  +
  +      // Now the decimal-formats
  +
  +      s = included.getDecimalFormatCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        DecimalFormatProperties dfp = included.getDecimalFormat(j);
  +        recomposableElements.addElement(new RecomposableImpl(this, dfp.getUid(), dfp));
  +      }
  +
  +      // Now the keys
  +
  +      s = included.getKeyCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        recomposableElements.addElement(included.getKey(j));
  +      }
  +
  +      // And the namespace aliases
  +
  +      s = included.getNamespaceAliasCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        NamespaceAlias nsa = included.getNamespaceAlias(j);
  +        recomposableElements.addElement(new RecomposableImpl(this, nsa.getUid(), nsa));
  +      }
  +
  +      // Next comes the templates
  +
  +      s = included.getTemplateCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        recomposableElements.addElement(included.getTemplate(j));
  +      }
  +
  +      // Then, the variables
  +
  +      s = included.getVariableOrParamCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        recomposableElements.addElement(included.getVariableOrParam(j));
  +      }
  +
  +      // And lastly the whitespace preserving and stripping elements
  +
  +      s = included.getStripSpaceCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        recomposableElements.addElement(included.getStripSpace(j));
  +      }
  +
  +      s = included.getPreserveSpaceCount();
  +      for (int j = 0; j < s; j++)
  +      {
  +        recomposableElements.addElement(included.getPreserveSpace(j));
  +      }
  +    }
  +  }
  +
     /** NEEDSDOC Field m_importNumber          */
     private int m_importNumber = -1;
   
  -  /** NEEDSDOC Field m_importCountComposed          */
  +  /** The precedence of this stylesheet in the global import list.
  +   *  The lowest precedence stylesheet is 0.  A higher
  +   *  number has a higher precedence.
  +   */
     private int m_importCountComposed;
   
     /**
  -   * Recalculate the number of this stylesheet in the global
  -   * import list.
  -   * <p>For example, suppose</p>
  -   * <p>stylesheet A imports stylesheets B and C in that order;</p>
  -   * <p>stylesheet B imports stylesheet D;</p>
  -   * <p>stylesheet C imports stylesheet E.</p>
  -   * <p>Then the order of import precedence (lowest first) is D, B, E, C, A.</p>
  -   * <p>If this were stylesheet C, then the importsComposed list
  -   * would be E, B, D (highest first).</p>
  +   * Recalculate the precedence of this stylesheet in the global
  +   * import list.  The lowest precedence stylesheet is 0.  A higher
  +   * number has a higher precedence.
      */
     void recomposeImports()
     {
  @@ -169,7 +268,8 @@
     }
   
     /**
  -   * Get the number of imported stylesheets.
  +   * Get the precedence of this stylesheet in the global import list.
  +   * The lowest precedence is 0.  A higher number has a higher precedence.
      * @see <a href="http://www.w3.org/TR/xslt#import">import in XSLT Specification</a>
      *
      * NEEDSDOC ($objectName$) @return
  @@ -185,9 +285,10 @@
     private transient Vector m_includesComposed;
   
     /**
  -   * Recompose the value of the composed include list.
  +   * Recompose the value of the composed include list.  Builds a composite
  +   * list of all stylesheets included by this stylesheet to any depth.
      *
  -   * NEEDSDOC @param including
  +   * @param including
      */
     void recomposeIncludes(Stylesheet including)
     {
  @@ -202,7 +303,6 @@
         for (int i = 0; i < n; i++)
         {
           Stylesheet included = including.getInclude(i);
  -
           m_includesComposed.addElement(included);
           recomposeIncludes(included);
         }
  @@ -223,6 +323,9 @@
             throws ArrayIndexOutOfBoundsException
     {
   
  +    if (-1 == i)
  +      return this;
  +
       if (null == m_includesComposed)
         throw new ArrayIndexOutOfBoundsException();
   
  @@ -241,464 +344,14 @@
     }
   
     /**
  -   * Table of DecimalFormatSymbols, keyed by QName.
  -   */
  -  private transient Hashtable m_decimalFormatSymbols;
  -
  -  /**
  -   * Given a valid element decimal-format name, return the
  -   * decimalFormatSymbols with that name.
  -   * <p>It is an error to declare either the default decimal-format or
  -   * a decimal-format with a given name more than once (even with
  -   * different import precedence), unless it is declared every
  -   * time with the same value for all attributes (taking into
  -   * account any default values).</p>
  -   * <p>Which means, as far as I can tell, the decimal-format
  -   * properties are not additive.</p>
  -   * @return null if name is not found.
  -   */
  -  void recomposeDecimalFormats()
  -  {
  -
  -    m_decimalFormatSymbols = new Hashtable();
  -
  -    // Loop for this stylesheet and all stylesheets included or of lower 
  -    // import precidence.
  -    int nImports = getImportCountComposed();
  -
  -    for (int i = -1; i < nImports; i++)
  -    {
  -      StylesheetComposed stylesheet = (i < 0) ? this : getImportComposed(i);
  -
  -      // Does this stylesheet contain it?
  -      int nDFPs = stylesheet.getDecimalFormatCount();
  -
  -      for (int dfpIndex = 0; dfpIndex < nDFPs; dfpIndex++)
  -      {
  -        DecimalFormatProperties dfp = stylesheet.getDecimalFormat(dfpIndex);
  -
  -        m_decimalFormatSymbols.put(dfp.getName(),
  -                                   dfp.getDecimalFormatSymbols());
  -      }
  -
  -      // Do the included stylesheets contain it?
  -      int nIncludes = stylesheet.getIncludeCountComposed();
  -
  -      for (int k = 0; k < nIncludes; k++)
  -      {
  -        Stylesheet included = stylesheet.getIncludeComposed(k);
  -
  -        nDFPs = included.getDecimalFormatCount();
  -
  -        for (int dfpIndex = 0; dfpIndex < nDFPs; dfpIndex++)
  -        {
  -          DecimalFormatProperties dfp = included.getDecimalFormat(dfpIndex);
  -
  -          m_decimalFormatSymbols.put(dfp.getName(),
  -                                     dfp.getDecimalFormatSymbols());
  -        }
  -      }
  -    }
  -  }
  -
  -  /**
  -   * Given a valid element decimal-format name, return the
  -   * decimalFormatSymbols with that name.
  -   * <p>It is an error to declare either the default decimal-format or
  -   * a decimal-format with a given name more than once (even with
  -   * different import precedence), unless it is declared every
  -   * time with the same value for all attributes (taking into
  -   * account any default values).</p>
  -   * <p>Which means, as far as I can tell, the decimal-format
  -   * properties are not additive.</p>
  -   *
  -   * NEEDSDOC @param name
  -   * @return null if name is not found.
  -   */
  -  public DecimalFormatSymbols getDecimalFormatComposed(QName name)
  -  {
  -    return (DecimalFormatSymbols) m_decimalFormatSymbols.get(name);
  -  }
  -
  -  /**
  -   * A list of properties that specify how to do space
  -   * stripping. This uses the same exact mechanism as Templates.
  -   */
  -  private WhitespaceList m_whiteSpaceInfoList;
  -
  -  /**
  -   * Compile a lookup table for WhiteSpaceInfo elements, which are built
  -   * from xsl:strip-space and xsl:preserve space information.
  -   * @return null if node is not matched.
  -   *
  -   * @throws TransformerException
  -   */
  -  void recomposeWhiteSpaceInfo() throws TransformerException
  -  {
  -
  -    int nIncludes = getIncludeCountComposed();
  -
  -    for (int k = -1; k < nIncludes; k++)
  -    {
  -      Stylesheet included = (-1 == k) ? this : getIncludeComposed(k);
  -      int n = included.getStripSpaceCount();
  -
  -      for (int i = 0; i < n; i++)
  -      {
  -        if (null == m_whiteSpaceInfoList)
  -          m_whiteSpaceInfoList = new WhitespaceList(this);
  -
  -        m_whiteSpaceInfoList.setTemplate(included.getStripSpace(i));
  -      }
  -
  -      n = included.getPreserveSpaceCount();
  -
  -      for (int i = 0; i < n; i++)
  -      {
  -        if (null == m_whiteSpaceInfoList)
  -          m_whiteSpaceInfoList = new WhitespaceList(this);
  -
  -        m_whiteSpaceInfoList.setTemplate(included.getPreserveSpace(i));
  -      }
  -    }
  -  }
  -
  -  /**
  -   * Check to see if the caller should bother with check for
  -   * whitespace nodes.
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public boolean shouldCheckWhitespace()
  -  {
  -
  -    if (null != m_whiteSpaceInfoList)
  -      return true;
  -
  -    int n = getImportCountComposed();
  -
  -    for (int i = 0; i < n; i++)
  -    {
  -      StylesheetComposed imported = getImportComposed(i);
  -
  -      if (null != imported.m_whiteSpaceInfoList)
  -        return true;
  -    }
  -
  -    return false;
  -  }
  -
  -  /**
  -   * Get information about whether or not an element should strip whitespace.
  -   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
  -   *
  -   * NEEDSDOC @param support
  -   * NEEDSDOC @param targetElement
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   *
  -   * @throws TransformerException
  -   */
  -  public WhiteSpaceInfo getWhiteSpaceInfo(
  -          XPathContext support, Element targetElement) throws TransformerException
  -  {
  -
  -    if (null != m_whiteSpaceInfoList)
  -      return (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support,
  -              targetElement, null, false);
  -    else
  -      return null;
  -  }
  -
  -  /**
  -   * A list of all key declarations visible from this stylesheet and all
  -   * lesser stylesheets.
  -   */
  -  private transient Vector m_keyDecls;
  -
  -  /**
  -   * Recompose the key decls from this stylesheet and
  -   * all stylesheets within lesser import precedence.
  -   */
  -  void recomposeKeys()
  -  {
  -
  -    m_keyDecls = new Vector();
  -
  -    // Loop for this stylesheet and all stylesheets included or of lower 
  -    // import precidence.
  -    int nImports = getImportCountComposed();
  -
  -    for (int i = -1; i < nImports; i++)
  -    {
  -      StylesheetComposed stylesheet = (i < 0) ? this : getImportComposed(i);
  -
  -      // Does this stylesheet contain it?
  -      int nKeys = stylesheet.getKeyCount();
  -
  -      for (int keyIndex = 0; keyIndex < nKeys; keyIndex++)
  -      {
  -        KeyDeclaration keyDecl = stylesheet.getKey(keyIndex);
  -
  -        m_keyDecls.addElement(keyDecl);
  -      }
  -
  -      // Do the included stylesheets contain it?
  -      int nIncludes = stylesheet.getIncludeCountComposed();
  -
  -      for (int k = 0; k < nIncludes; k++)
  -      {
  -        Stylesheet included = stylesheet.getIncludeComposed(k);
  -
  -        nKeys = included.getKeyCount();
  -
  -        for (int keyIndex = 0; keyIndex < nKeys; keyIndex++)
  -        {
  -          KeyDeclaration keyDecl = included.getKey(keyIndex);
  -
  -          m_keyDecls.addElement(keyDecl);
  -        }
  -      }
  -    }
  -  }
  -
  -  /**
  -   * Get the composed "xsl:key" properties.
  -   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public Vector getKeysComposed()
  -  {
  -    return m_keyDecls;
  -  }
  -
  -  /**
  -   * Composed set of all included and imported attribute set properties.
  -   * Each entry is a vector of ElemAttributeSet objects.
  -   * <p>Note: Should this go on the StylesheetRoot class instead?</p>
  -   */
  -  private transient Hashtable m_attrSets;
  -
  -  /**
  -   * Recompose the attribute-set decls from this stylesheet and
  -   * all stylesheets within import precedence.
  -   */
  -  void recomposeAttributeSets()
  -  {
  -
  -    m_attrSets = new Hashtable();
  -
  -    // Loop for this stylesheet and all stylesheets included or of lower 
  -    // import precidence.
  -    int nImports = getImportCountComposed();
  -
  -    for (int i = -1; i < nImports; i++)
  -    {
  -      StylesheetComposed stylesheet = (i < 0) ? this : getImportComposed(i);
  -
  -      // Does this stylesheet contain it?
  -      int nAS = stylesheet.getAttributeSetCount();
  -
  -      for (int asIndex = 0; asIndex < nAS; asIndex++)
  -      {
  -        ElemAttributeSet attrSet = stylesheet.getAttributeSet(asIndex);
  -        Vector attrSetList = (Vector) m_attrSets.get(attrSet.getName());
  -
  -        if (null == attrSetList)
  -        {
  -          attrSetList = new Vector();
  -
  -          m_attrSets.put(attrSet.getName(), attrSetList);
  -        }
  -
  -        attrSetList.addElement(attrSet);
  -      }
  -
  -      // Do the included stylesheets contain it?
  -      int nIncludes = stylesheet.getIncludeCountComposed();
  -
  -      for (int k = 0; k < nIncludes; k++)
  -      {
  -        Stylesheet included = stylesheet.getIncludeComposed(k);
  -
  -        nAS = included.getAttributeSetCount();
  -
  -        for (int asIndex = 0; asIndex < nAS; asIndex++)
  -        {
  -          ElemAttributeSet attrSet = included.getAttributeSet(asIndex);
  -          Vector attrSetList = (Vector) m_attrSets.get(attrSet.getName());
  -
  -          if (null == attrSetList)
  -          {
  -            attrSetList = new Vector();
  -
  -            m_attrSets.put(attrSet.getName(), attrSetList);
  -          }
  -
  -          attrSetList.addElement(attrSet);
  -        }
  -      }
  -    }
  -  }
  -
  -  /**
  -   * Get a list "xsl:attribute-set" properties that match the qname.
  -   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
  -   *
  -   * NEEDSDOC @param name
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   *
  -   * @throws ArrayIndexOutOfBoundsException
  -   */
  -  public Vector getAttributeSetComposed(QName name)
  -          throws ArrayIndexOutOfBoundsException
  -  {
  -    return (Vector) m_attrSets.get(name);
  -  }
  -  
  -  /**
  -   * Composed set of all variables and params.
  -   * <p>Note: Should this go on the StylesheetRoot class instead?</p>
  -   */
  -  private transient Vector m_variables;
  -
  -  /**
  -   * Recompose the attribute-set decls from this stylesheet and
  -   * all stylesheets within import precedence.
  -   */
  -  void recomposeVariables()
  -  {
  -
  -    m_variables = new Vector();
  -
  -    // Loop for this stylesheet and all stylesheets included or of lower 
  -    // import precidence.
  -    int nImports = getImportCountComposed();
  -
  -    for (int i = -1; i < nImports; i++)
  -    {
  -      StylesheetComposed stylesheet = (i < 0) ? this : getImportComposed(i);
  -
  -      // Does this stylesheet contain it?
  -      int nVariables = stylesheet.getVariableOrParamCount();
  -
  -      for (int vIndex = 0; vIndex < nVariables; vIndex++)
  -      {
  -        ElemVariable elemVar = stylesheet.getVariableOrParam(vIndex);
  -
  -        // Don't overide higher priority variable        
  -        if (getVariableOrParamComposed(elemVar.getName()) == null)
  -          m_variables.addElement(elemVar);
  -      }
  -
  -      // Do the included stylesheets contain it?
  -      int nIncludes = stylesheet.getIncludeCountComposed();
  -
  -      for (int k = 0; k < nIncludes; k++)
  -      {
  -        Stylesheet included = stylesheet.getIncludeComposed(k);
  -
  -        nVariables = included.getVariableOrParamCount();
  -
  -        for (int vIndex = 0; vIndex < nVariables; vIndex++)
  -        {
  -          ElemVariable elemVar = included.getVariableOrParam(vIndex);
  -
  -          // Don't overide higher priority variable
  -          if (getVariableOrParamComposed(elemVar.getName()) == null)
  -            m_variables.addElement(elemVar);
  -        }
  -      }
  -    }
  -  }
  -
  -  /**
  -   * Get an "xsl:variable" property.
  -   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
  -   *
  -   * NEEDSDOC @param qname
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public ElemVariable getVariableOrParamComposed(QName qname)
  -  {
  -    if (null != m_variables)
  -    {
  -      int n = m_variables.size();
  -
  -      for (int i = 0; i < n; i++)
  -      {
  -        ElemVariable var = (ElemVariable)m_variables.elementAt(i);
  -        if(var.getName().equals(qname))
  -          return var;
  -      }
  -    }
  -
  -    return null;
  -  }
  -
  -  /**
  -   * Get all global "xsl:variable" properties in scope for this stylesheet.
  -   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public Vector getVariablesAndParamsComposed()
  -  {
  -    return m_variables;
  -  }
  -
  -  /**
  -   * The "xsl:template" properties.
  -   */
  -  private transient TemplateList m_templateList = new TemplateList(this);
  -
  -  /**
  -   * NEEDSDOC Method getTemplateListComposed 
  -   *
  -   *
  -   * NEEDSDOC (getTemplateListComposed) @return
  -   */
  -  public final TemplateList getTemplateListComposed()
  -  {
  -    return m_templateList;
  -  }
  -
  -  /**
  -   * Aggregate the list of templates and included templates into a single list.
  -   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  -   *
  -   * @throws TransformerException
  -   */
  -  public void recomposeTemplates() throws TransformerException
  -  {
  -
  -    int nIncludes = getIncludeCountComposed();
  -
  -    for (int k = nIncludes - 1; k >= -1; k--)
  -    {
  -      Stylesheet included = (-1 == k) ? this : getIncludeComposed(k);
  -      int n = included.getTemplateCount();
  -
  -      for (int i = 0; i < n; i++)
  -      {
  -        ElemTemplate template = included.getTemplate(i);
  -        m_templateList.setTemplate(template);
  -      }
  -    }
  -
  -    m_templateList.compose();
  -  }
  -
  -  /**
      * For compilation support, we need the option of overwriting
      * (rather than appending to) previous composition.
      * We could phase out the old API in favor of this one, but I'm
      * holding off until we've made up our minds about compilation.
      * ADDED 9/5/2000 to support compilation experiment
      * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  +   * NOTE: GLP 29-Nov-00 I've left this method in so that CompilingStylesheetHandler will compile.  However,
  +   *                     I'm not sure why it's needed or what it does and I've commented out the body.
      *
      * NEEDSDOC @param flushFirst
      *
  @@ -706,114 +359,11 @@
      */
     public void recomposeTemplates(boolean flushFirst) throws TransformerException
     {
  -
  +/***************************************  KEEP METHOD IN FOR COMPILATION
       if (flushFirst)
         m_templateList = new TemplateList(this);
   
       recomposeTemplates();
  -  }
  -
  -  /**
  -   * Get an "xsl:template" property by node match. This looks in the imports as
  -   * well as this stylesheet.
  -   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  -   *
  -   * NEEDSDOC @param support
  -   * NEEDSDOC @param targetNode
  -   * NEEDSDOC @param mode
  -   * NEEDSDOC @param quietConflictWarnings
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   *
  -   * @throws TransformerException
  -   */
  -  public ElemTemplate getTemplateComposed(
  -          XPathContext support, Node targetNode, QName mode, boolean quietConflictWarnings)
  -            throws TransformerException
  -  {
  -    return m_templateList.getTemplate(support, targetNode, mode,
  -                                      quietConflictWarnings);
  -  }
  -
  -  /**
  -   * Get an "xsl:template" property. This looks in the imports as
  -   * well as this stylesheet.
  -   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  -   *
  -   * NEEDSDOC @param qname
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public ElemTemplate getTemplateComposed(QName qname)
  -  {
  -    return m_templateList.getTemplate(qname);
  -  }
  -
  -  /**
  -   * Composed set of all params.
  -   * <p>Note: Should this go on the StylesheetRoot class instead?</p>
  -   */
  -  private transient Hashtable m_namespaceAliasComposed;
  -
  -  /**
  -   * Recompose the attribute-set decls from this stylesheet and
  -   * all stylesheets within import precedence.
  -   */
  -  void recomposeNamespaceAliases()
  -  {
  -
  -    m_namespaceAliasComposed = new Hashtable();
  -
  -    // Loop for this stylesheet and all stylesheets included or of lower 
  -    // import precidence.
  -    int nImports = getImportCountComposed();
  -
  -    for (int i = -1; i < nImports; i++)
  -    {
  -      StylesheetComposed stylesheet = (i < 0) ? this : getImportComposed(i);
  -
  -      // Does this stylesheet contain it?
  -      int nNSA = stylesheet.getNamespaceAliasCount();
  -
  -      for (int nsaIndex = 0; nsaIndex < nNSA; nsaIndex++)
  -      {
  -        NamespaceAlias nsAlias = stylesheet.getNamespaceAlias(nsaIndex);
  -
  -        m_namespaceAliasComposed.put(nsAlias.getStylesheetPrefix(),
  -                                     nsAlias.getResultPrefix());
  -      }
  -
  -      // Do the included stylesheets contain it?
  -      int nIncludes = stylesheet.getIncludeCountComposed();
  -
  -      for (int k = 0; k < nIncludes; k++)
  -      {
  -        Stylesheet included = stylesheet.getIncludeComposed(k);
  -
  -        nNSA = included.getNamespaceAliasCount();
  -
  -        for (int nsaIndex = 0; nsaIndex < nNSA; nsaIndex++)
  -        {
  -          NamespaceAlias nsAlias = included.getNamespaceAlias(nsaIndex);
  -
  -          m_namespaceAliasComposed.put(nsAlias.getStylesheetPrefix(),
  -                                       nsAlias.getResultPrefix());
  -        }
  -      }
  -    }
  -  }
  -
  -  /**
  -   * Get the "xsl:namespace-alias" property.
  -   * Return the alias namespace uri for a given namespace uri if one is found.
  -   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
  -   *
  -   * NEEDSDOC @param uri
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public String getNamespaceAliasComposed(String uri)
  -  {
  -    return (String) m_namespaceAliasComposed.get(uri);
  +*****************************************/
     }
   }
  
  
  
  1.25      +532 -143  xml-xalan/java/src/org/apache/xalan/templates/StylesheetRoot.java
  
  Index: StylesheetRoot.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/StylesheetRoot.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- StylesheetRoot.java	2000/11/28 17:25:51	1.24
  +++ StylesheetRoot.java	2000/11/30 09:57:33	1.25
  @@ -62,6 +62,9 @@
   
   import java.net.MalformedURLException;
   
  +import java.text.DecimalFormat;
  +import java.text.DecimalFormatSymbols;
  +
   import java.io.*;
   
   import org.xml.sax.*;
  @@ -228,7 +231,7 @@
     public OutputFormat getOutputFormat()
     {
   
  -    OutputFormatExtended cloned = new OutputFormatExtended();
  +    OutputFormatExtended cloned = new OutputFormatExtended(0);
   
       if (m_outputFormatComposed instanceof OutputFormatExtended)
       {
  @@ -247,53 +250,88 @@
     /**
      * Recompose the values of all "composed" properties, meaning
      * properties that need to be combined or calculated from
  -   * the combination of imported and included stylesheets.
  +   * the combination of imported and included stylesheets.  This
  +   * method determines the proper import precedence of all imported
  +   * stylesheets.  It then iterates through all of the elements and 
  +   * properties in the proper order and triggers the individual recompose
  +   * methods.
      *
      * @throws TransformerException
      */
     public void recompose() throws TransformerException
     {
  +
  +    // First, we build the global import tree.
  +
  +    if (null == m_globalImportList)
  +    {
  +
  +      Vector importList = new Vector();
  +
  +      addImports(this, true, importList);
  +
  +      // Now we create an array and reverse the order of the importList vector.
  +      // We built the importList vector backwards so that we could use addElement
  +      // to append to the end of the vector instead of constantly pushing new
  +      // stylesheets onto the front of the vector and having to shift the rest
  +      // of the vector each time.
  +
  +      m_globalImportList = new StylesheetComposed[importList.size()];
  +
  +      for (int i = importList.size() - 1, j= 0; i >= 0; i--)
  +        m_globalImportList[j++] = (StylesheetComposed) importList.elementAt(i);
  +    }
   
  -    recomposeImports();
  -    recomposeOutput();
  +    // Now we make a Vector that is going to hold all of the recomposable elements
   
  +    Vector recomposableElements = new Vector();
  +
  +    // Next, we walk the import tree and add all of the recomposable elements to the vector.
  +
       int n = getGlobalImportCount();
   
       for (int i = 0; i < n; i++)
       {
  -      StylesheetComposed sheet = getGlobalImport(i);
  -
  -      if (sheet != this)  // already done
  -      {
  -        sheet.recomposeImports();
  -        sheet.recomposeIncludes(sheet);
  -        sheet.recomposeAttributeSets();
  -        sheet.recomposeDecimalFormats();
  -        sheet.recomposeKeys();
  -        sheet.recomposeNamespaceAliases();
  -        sheet.recomposeTemplates();
  -        sheet.recomposeVariables();
  -        sheet.recomposeWhiteSpaceInfo();
  -      }
  +      StylesheetComposed imported = getGlobalImport(i);
  +      imported.recompose(recomposableElements);
       }
  +
  +    // We sort the elements into ascending order.
  +
  +    QuickSort2(recomposableElements, 0, recomposableElements.size() - 1);
  +
  +    // We set up the global variables that will hold the recomposed information.
  +
  +    m_outputFormatComposed = new OutputFormatExtended(0);
  +    m_attrSets = new Hashtable();
  +    m_decimalFormatSymbols = new Hashtable();
  +    m_keyDecls = new Vector();
  +    m_namespaceAliasComposed = new Hashtable();
  +    m_templateList = new TemplateList();
  +    m_variables = new Vector();
  +
  +    // Now we sequence through the sorted elements, 
  +    // calling the recompose() function on each one.  This will call back into the
  +    // appropriate routine here to actually do the recomposition.
  +    // Note that we're going backwards, encountering the highest precedence items first.
   
  -    recomposeIncludes(this);
  -    recomposeAttributeSets();
  -    recomposeDecimalFormats();
  -    recomposeKeys();
  -    recomposeNamespaceAliases();
  -    recomposeTemplates();
  -    recomposeVariables();
  -    recomposeWhiteSpaceInfo();
  +    for (int i = recomposableElements.size() - 1; i >= 0; i--)
  +      ((Recomposable) recomposableElements.elementAt(i)).recompose(this);
   
  -    // Now call the compose() method on every element.
  +    // Need final composition of TemplateList.  This adds the wild cards onto the chains.
   
  +    m_templateList.compose();
  +
  +    // Now call the compose() method on every element to give it a chance to adjust
  +    // based on composed values.
  +
  +    n = getGlobalImportCount();
  +
       for (int i = 0; i < n; i++)
       {
         StylesheetComposed imported = this.getGlobalImport(i);
  -      composeTemplates(imported);
         int includedCount = imported.getIncludeCountComposed();
  -      for (int j = 0; j < includedCount; j++)
  +      for (int j = -1; j < includedCount; j++)
         {
           Stylesheet included = imported.getIncludeComposed(j);
           composeTemplates(included);
  @@ -319,52 +357,36 @@
     }
   
     /**
  -   * This will be set up with the default values, and then the values
  -   * will be set as stylesheets are encountered.
  -   */
  -  private OutputFormat m_outputFormatComposed;
  +   * The combined list of imports.  The stylesheet with the highest
  +   * import precedence will be at element 0.  The one with the lowest
  +   * import precedence will be at element length - 1.
  +   */
  +  private transient StylesheetComposed[] m_globalImportList;
   
     /**
  -   * Get the combined "xsl:output" property with the properties
  -   * combined from the included stylesheets.  If a xsl:output
  -   * is not declared in this stylesheet or an included stylesheet,
  -   * look in the imports.
  -   * Please note that this returns a reference to the OutputFormat
  -   * object, not a cloned object, like getOutputFormat does.
  -   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
  -   *
  -   * NEEDSDOC ($objectName$) @return
  -   */
  -  public OutputFormat getOutputComposed()
  -  {
  -
  -    // System.out.println("getOutputComposed.getIndent: "+m_outputFormatComposed.getIndent());
  -    // System.out.println("getOutputComposed.getIndenting: "+m_outputFormatComposed.getIndenting());
  -    return m_outputFormatComposed;
  -  }
  -
  -  /**
  -   * Recompose the output format object from the included elements.
  -   */
  -  public void recomposeOutput()
  -  {
  -
  -    // System.out.println("Recomposing output...");
  -    m_outputFormatComposed = new OutputFormatExtended();
  -
  -    m_outputFormatComposed.setPreserveSpace(true);
  -    recomposeOutput(this);
  -  }
  -
  -  /**
  -   * Recompose the output format object from the included elements.
  +   * Add the imports in the given sheet to the working importList vector.
  +   * The will be added from highest import precedence to
  +   * least import precedence.  This is a post-order traversal of the
  +   * import tree as described in <a href="http://www.w3.org/TR/xslt.html#import">the
  +   * XSLT Recommendation</a>.
  +   * <p>For example, suppose</p>
  +   * <p>stylesheet A imports stylesheets B and C in that order;</p>
  +   * <p>stylesheet B imports stylesheet D;</p>
  +   * <p>stylesheet C imports stylesheet E.</p>
  +   * <p>Then the order of import precedence (highest first) is
  +   * A, C, E, B, D.</p>
      *
  -   * NEEDSDOC @param stylesheet
  +   * @param stylesheet Stylesheet to examine for imports.
  +   * @param addToList  <code>true</code> if this template should be added to the import list
  +   * @param importList The working import list.  Templates are added here in the reverse
  +   *        order of priority.  When we're all done, we'll reverse this to the correct
  +   *        priority in an array.
      */
  -  private void recomposeOutput(Stylesheet stylesheet)
  +  protected void addImports(Stylesheet stylesheet, boolean addToList, Vector importList)
     {
   
       // Get the direct imports of this sheet.
  +
       int n = stylesheet.getImportCount();
   
       if (n > 0)
  @@ -373,7 +395,7 @@
         {
           Stylesheet imported = stylesheet.getImport(i);
   
  -        recomposeOutput(imported);
  +        addImports(imported, true, importList);
         }
       }
   
  @@ -385,16 +407,100 @@
         {
           Stylesheet included = stylesheet.getInclude(i);
   
  -        recomposeOutput(included);
  +        addImports(included, false, importList);
         }
       }
  +
  +    if (addToList)
  +      importList.addElement(stylesheet);
  +
  +  }
   
  -    OutputFormatExtended of = stylesheet.getOutput();
  +  /**
  +   * Get a stylesheet from the global import list. 
  +   * TODO: JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH COUNT.
  +   * 
  +   * NEEDSDOC @param i 
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public StylesheetComposed getGlobalImport(int i)
  +  {
  +    return m_globalImportList[i];
  +  }
   
  -    if (null != of)
  +  /**
  +   * Get the total number of imports in the global import list.
  +   * @return The total number of imported stylesheets, including
  +   * the root stylesheet, thus the number will always be 1 or
  +   * greater.
  +   * TODO: JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH DESCRIPTION.
  +   */
  +  public int getGlobalImportCount()
  +  {
  +	  return (m_globalImportList!=null)
  +			? m_globalImportList.length 
  +			  : 1;
  +  }
  +
  +  /**
  +   * Given a stylesheet, return the number of the stylesheet
  +   * in the global import list.
  +   * @param sheet The stylesheet which will be located in the
  +   * global import list.
  +   * @return The index into the global import list of the given stylesheet,
  +   * or -1 if it is not found (which should never happen).
  +   */
  +  public int getImportNumber(StylesheetComposed sheet)
  +  {
  +
  +    if (this == sheet)
  +      return 0;
  +
  +    int n = getGlobalImportCount();
  +
  +    for (int i = 0; i < n; i++)
       {
  -      ((OutputFormatExtended) m_outputFormatComposed).copyFrom(of);
  +      if (sheet == getGlobalImport(i))
  +        return i;
       }
  +
  +    return -1;
  +  }
  +
  +  /**
  +   * This will be set up with the default values, and then the values
  +   * will be set as stylesheets are encountered.
  +   */
  +  private OutputFormatExtended m_outputFormatComposed;
  +
  +  /**
  +   * Recompose the output format object from the included elements.
  +   *
  +   * NEEDSDOC @param stylesheet
  +   */
  +  void recomposeOutput(OutputFormatExtended of)
  +  {
  +    m_outputFormatComposed.copyFrom(of);
  +  }
  +
  +  /**
  +   * Get the combined "xsl:output" property with the properties
  +   * combined from the included stylesheets.  If a xsl:output
  +   * is not declared in this stylesheet or an included stylesheet,
  +   * look in the imports.
  +   * Please note that this returns a reference to the OutputFormat
  +   * object, not a cloned object, like getOutputFormat does.
  +   * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT Specification</a>
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public OutputFormat getOutputComposed()
  +  {
  +
  +    // System.out.println("getOutputComposed.getIndent: "+m_outputFormatComposed.getIndent());
  +    // System.out.println("getOutputComposed.getIndenting: "+m_outputFormatComposed.getIndenting());
  +    return m_outputFormatComposed;
     }
   
     /** NEEDSDOC Field m_outputMethodSet          */
  @@ -412,128 +518,334 @@
     }
   
     /**
  -   * The combined list of imports.
  +   * Composed set of all included and imported attribute set properties.
  +   * Each entry is a vector of ElemAttributeSet objects.
      */
  -  private transient Vector m_globalImportList;
  +  private transient Hashtable m_attrSets;
   
     /**
  -   * Add the imports in the given sheet to the m_globalImportList
  -   * list.  The will be added from highest import precedence to
  -   * least import precidence.
  +   * Recompose the attribute-set declarations.
      *
  -   * @param stylesheet Stylesheet to examine for imports.
  +   * @param attrSet An attribute-set to add to the hashtable of attribute sets.
      */
  -  protected void addImports(Stylesheet stylesheet, boolean addToList)
  +  void recomposeAttributeSets(ElemAttributeSet attrSet)
     {
  +    Vector attrSetList = (Vector) m_attrSets.get(attrSet.getName());
   
  -    // Get the direct imports of this sheet.
  -    int n = stylesheet.getImportCount();
  -
  -    if (n > 0)
  +    if (null == attrSetList)
       {
  -      for (int i = 0; i < n; i++)
  -      {
  -        Stylesheet imported = stylesheet.getImport(i);
  +      attrSetList = new Vector();
   
  -        addImports(imported, true);
  -      }
  +      m_attrSets.put(attrSet.getName(), attrSetList);
       }
   
  -    n = stylesheet.getIncludeCount();
  +    attrSetList.addElement(attrSet);
  +  }
   
  -    if (n > 0)
  +  /**
  +   * Get a list "xsl:attribute-set" properties that match the qname.
  +   * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in XSLT Specification</a>
  +   *
  +   * NEEDSDOC @param name
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   *
  +   * @throws ArrayIndexOutOfBoundsException
  +   */
  +  public Vector getAttributeSetComposed(QName name)
  +          throws ArrayIndexOutOfBoundsException
  +  {
  +    return (Vector) m_attrSets.get(name);
  +  }
  +
  +  /**
  +   * Table of DecimalFormatSymbols, keyed by QName.
  +   */
  +  private transient Hashtable m_decimalFormatSymbols;
  +
  +  /**
  +   * Recompose the decimal-format declarations.
  +   *
  +   * @param dfp A DecimalFormatProperties to add to the hashtable of decimal formats.
  +   */
  +  void recomposeDecimalFormats(DecimalFormatProperties dfp)
  +  {
  +    DecimalFormatSymbols oldDfs =
  +                  (DecimalFormatSymbols) m_decimalFormatSymbols.get(dfp.getName());
  +    if (null == oldDfs)
       {
  -      for (int i = 0; i < n; i++)
  +      m_decimalFormatSymbols.put(dfp.getName(), dfp.getDecimalFormatSymbols());
  +    }
  +    else if (!dfp.getDecimalFormatSymbols().equals(oldDfs))
  +    {
  +      String themsg;
  +      if (dfp.getName().equals(new QName("")))
         {
  -        Stylesheet included = stylesheet.getInclude(i);
  -
  -        addImports(included, false);
  +        // "Only one default xsl:decimal-format declaration is allowed."
  +        themsg = XSLMessages.createWarning(
  +                          XSLTErrorResources.WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED,
  +                          new Object[0]);
         }
  +      else
  +      {
  +        // "xsl:decimal-format names must be unique. Name {0} has been duplicated."
  +        themsg = XSLMessages.createWarning(
  +                          XSLTErrorResources.WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE,
  +                          new Object[] {dfp.getName()});
  +      }
  +
  +      throw new RuntimeException(themsg);   // Should we throw TransformerException instead?
       }
   
  -    if (addToList)
  -      m_globalImportList.insertElementAt(stylesheet, 0);
  +  }
   
  +  /**
  +   * Given a valid element decimal-format name, return the
  +   * decimalFormatSymbols with that name.
  +   * <p>It is an error to declare either the default decimal-format or
  +   * a decimal-format with a given name more than once (even with
  +   * different import precedence), unless it is declared every
  +   * time with the same value for all attributes (taking into
  +   * account any default values).</p>
  +   * <p>Which means, as far as I can tell, the decimal-format
  +   * properties are not additive.</p>
  +   *
  +   * NEEDSDOC @param name
  +   * @return null if name is not found.
  +   */
  +  public DecimalFormatSymbols getDecimalFormatComposed(QName name)
  +  {
  +    return (DecimalFormatSymbols) m_decimalFormatSymbols.get(name);
     }
   
     /**
  -   * Recompose the value of the composed import list. This
  -   * means any stylesheets of lesser import precidence.
  -   * <p>For example, suppose</p>
  -   * <p>stylesheet A imports stylesheets B and C in that order;</p>
  -   * <p>stylesheet B imports stylesheet D;</p>
  -   * <p>stylesheet C imports stylesheet E.</p>
  -   * <p>Then the order of import precedence (highest first) is
  -   * A, C, E, B, D.</p>
  +   * A list of all key declarations visible from this stylesheet and all
  +   * lesser stylesheets.
  +   */
  +  private transient Vector m_keyDecls;
  +
  +  /**
  +   * Recompose the key declarations.
  +   *
  +   * @param keyDecl A KeyDeclaration to be added to the vector of key declarations.
      */
  -  protected void recomposeImports()
  +  void recomposeKeys(KeyDeclaration keyDecl)
     {
  +    m_keyDecls.addElement(keyDecl);
  +  }
   
  -    if (null == m_globalImportList)
  -    {
  -      m_globalImportList = new Vector();
  +  /**
  +   * Get the composed "xsl:key" properties.
  +   * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public Vector getKeysComposed()
  +  {
  +    return m_keyDecls;
  +  }
   
  -      addImports(this, true);
  -    }
  +  /**
  +   * Composed set of all namespace aliases.
  +   */
  +  private transient Hashtable m_namespaceAliasComposed;
   
  -    super.recomposeImports();
  +  /**
  +   * Recompose the namespace-alias declarations.
  +   *
  +   * @param nsAlias A NamespaceAlias object to add to the hashtable of namespace aliases.
  +   */
  +  void recomposeNamespaceAliases(NamespaceAlias nsAlias)
  +  {
  +    m_namespaceAliasComposed.put(nsAlias.getStylesheetPrefix(),
  +                                 nsAlias.getResultPrefix());
     }
   
     /**
  -   * Get a stylesheet from the global import list. 
  -   * TODO: JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH COUNT.
  -   * 
  -   * NEEDSDOC @param i 
  +   * Get the "xsl:namespace-alias" property.
  +   * Return the alias namespace uri for a given namespace uri if one is found.
  +   * @see <a href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element in XSLT Specification</a>
  +   *
  +   * NEEDSDOC @param uri
      *
      * NEEDSDOC ($objectName$) @return
      */
  -  public StylesheetComposed getGlobalImport(int i)
  +  public String getNamespaceAliasComposed(String uri)
     {
  -    return (i==0)
  -		? this
  -		  : (StylesheetComposed) m_globalImportList.elementAt(i);
  +    return (String) m_namespaceAliasComposed.get(uri);
     }
   
     /**
  -   * Get the total number of imports in the global import list.
  -   * @return The total number of imported stylesheets, including
  -   * the root stylesheet, thus the number will always be 1 or
  -   * greater.
  -   * TODO: JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH DESCRIPTION.
  +   * The "xsl:template" properties.
      */
  -  public int getGlobalImportCount()
  +  private transient TemplateList m_templateList;
  +
  +  /**
  +   * Recompose the template declarations.
  +   *
  +   * @param template An ElemTemplate object to add to the template list.
  +   */
  +  void recomposeTemplates(ElemTemplate template)
     {
  -	  return (m_globalImportList!=null)
  -			? m_globalImportList.size() 
  -			  : 1;
  +    m_templateList.setTemplate(template);
     }
   
     /**
  -   * Given a stylesheet, return the number of the stylesheet
  -   * in the global import list.
  -   * @param sheet The stylesheet which will be located in the
  -   * global import list.
  -   * @return The index into the global import list of the given stylesheet,
  -   * or -1 if it is not found (which should never happen).
  +   * NEEDSDOC Method getTemplateListComposed 
  +   *
  +   *
  +   * NEEDSDOC (getTemplateListComposed) @return
      */
  -  public int getImportNumber(StylesheetComposed sheet)
  +  public final TemplateList getTemplateListComposed()
     {
  +    return m_templateList;
  +  }
   
  -    if (this == sheet)
  -      return 0;
  +  /**
  +   * Get an "xsl:template" property by node match. This looks in the imports as
  +   * well as this stylesheet.
  +   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  +   *
  +   * NEEDSDOC @param support
  +   * NEEDSDOC @param targetNode
  +   * NEEDSDOC @param mode
  +   * NEEDSDOC @param quietConflictWarnings
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   *
  +   * @throws TransformerException
  +   */
  +  public ElemTemplate getTemplateComposed(XPathContext support,
  +                                          Node targetNode,
  +                                          QName mode,
  +                                          int maxImportLevel,
  +                                          boolean quietConflictWarnings)
  +            throws TransformerException
  +  {
  +    return m_templateList.getTemplate(support, targetNode, mode, maxImportLevel,
  +                                                                quietConflictWarnings);
  +  }
   
  -    int n = getGlobalImportCount();
  +  /**
  +   * Get an "xsl:template" property. This looks in the imports as
  +   * well as this stylesheet.
  +   * @see <a href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules in XSLT Specification</a>
  +   *
  +   * NEEDSDOC @param qname
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public ElemTemplate getTemplateComposed(QName qname)
  +  {
  +    return m_templateList.getTemplate(qname);
  +  }
  +  
  +  /**
  +   * Composed set of all variables and params.
  +   */
  +  private transient Vector m_variables;
   
  -    for (int i = 0; i < n; i++)
  +  /**
  +   * Recompose the top level variable and parameter declarations.
  +   *
  +   * @param elemVar A top level variable or parameter to be added to the Vector.
  +   */
  +  void recomposeVariables(ElemVariable elemVar)
  +  {
  +    // Don't overide higher priority variable        
  +    if (getVariableOrParamComposed(elemVar.getName()) == null)
  +      m_variables.addElement(elemVar);
  +  }
  +
  +  /**
  +   * Get an "xsl:variable" property.
  +   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
  +   *
  +   * NEEDSDOC @param qname
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public ElemVariable getVariableOrParamComposed(QName qname)
  +  {
  +    if (null != m_variables)
       {
  -      if (sheet == getGlobalImport(i))
  -        return i;
  +      int n = m_variables.size();
  +
  +      for (int i = 0; i < n; i++)
  +      {
  +        ElemVariable var = (ElemVariable)m_variables.elementAt(i);
  +        if(var.getName().equals(qname))
  +          return var;
  +      }
       }
   
  -    return -1;
  +    return null;
  +  }
  +
  +  /**
  +   * Get all global "xsl:variable" properties in scope for this stylesheet.
  +   * @see <a href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables in XSLT Specification</a>
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public Vector getVariablesAndParamsComposed()
  +  {
  +    return m_variables;
  +  }
  +
  +  /**
  +   * A list of properties that specify how to do space
  +   * stripping. This uses the same exact mechanism as Templates.
  +   */
  +  private TemplateList m_whiteSpaceInfoList;
  +
  +  /**
  +   * Recompose the strip-space and preserve-space declarations.
  +   *
  +   * @param wsi A WhiteSpaceInfo element to add to the list of WhiteSpaceInfo elements.
  +   */
  +  void recomposeWhiteSpaceInfo(WhiteSpaceInfo wsi)
  +  {
  +    if (null == m_whiteSpaceInfoList)
  +      m_whiteSpaceInfoList = new TemplateList();
  +
  +    m_whiteSpaceInfoList.setTemplate(wsi);
     }
   
     /**
  +   * Check to see if the caller should bother with check for
  +   * whitespace nodes.
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   */
  +  public boolean shouldCheckWhitespace()
  +  {
  +    return null != m_whiteSpaceInfoList;
  +  }
  +
  +  /**
  +   * Get information about whether or not an element should strip whitespace.
  +   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
  +   *
  +   * NEEDSDOC @param support
  +   * NEEDSDOC @param targetElement
  +   *
  +   * NEEDSDOC ($objectName$) @return
  +   *
  +   * @throws TransformerException
  +   */
  +  public WhiteSpaceInfo getWhiteSpaceInfo(
  +          XPathContext support, Element targetElement) throws TransformerException
  +  {
  +
  +    if (null != m_whiteSpaceInfoList)
  +      return (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support,
  +              targetElement, null, -1, false);
  +    else
  +      return null;
  +  }
  +
  +  /**
      * <meta name="usage" content="advanced"/>
      * The default template to use for text nodes if we don't find
      * anything else.  This is initialized in initDefaultRule().
  @@ -653,4 +965,81 @@
       childrenElement.setIsDefaultTemplate(true);
       m_defaultRootRule.appendChild(childrenElement);
     }
  +
  +  /**
  +   * This is a generic version of C.A.R Hoare's Quick Sort
  +   * algorithm.  This will handle arrays that are already
  +   * sorted, and arrays with duplicate keys.  It was lifted from
  +   * the NodeSorter class but should probably be eliminated and replaced
  +   * with a call to Collections.sort when we migrate to Java2.<BR>
  +   *
  +   * If you think of a one dimensional array as going from
  +   * the lowest index on the left to the highest index on the right
  +   * then the parameters to this function are lowest index or
  +   * left and highest index or right.  The first time you call
  +   * this function it will be with the parameters 0, a.length - 1.
  +   *
  +   * @param a       an integer array
  +   * @param lo0     left boundary of array partition
  +   * @param hi0     right boundary of array partition
  +   *
  +   * NEEDSDOC @param v
  +   * NEEDSDOC @param i
  +   * NEEDSDOC @param j
  +   */
  +
  +  private void QuickSort2(Vector v, int lo0, int hi0)
  +    {
  +      int lo = lo0;
  +      int hi = hi0;
  +
  +      if ( hi0 > lo0)
  +      {
  +        // Arbitrarily establishing partition element as the midpoint of
  +        // the array.
  +        Recomposable midNode = (Recomposable) v.elementAt( ( lo0 + hi0 ) / 2 );
  +
  +        // loop through the array until indices cross
  +        while( lo <= hi )
  +        {
  +          // find the first element that is greater than or equal to
  +          // the partition element starting from the left Index.
  +          while( (lo < hi0) && (((Recomposable) v.elementAt(lo)).compareTo(midNode) < 0) )
  +          {
  +            ++lo;
  +          } // end while
  +
  +          // find an element that is smaller than or equal to
  +          // the partition element starting from the right Index.
  +          while( (hi > lo0) && (((Recomposable) v.elementAt(hi)).compareTo(midNode) > 0) )          {
  +            --hi;
  +          }
  +
  +          // if the indexes have not crossed, swap
  +          if( lo <= hi )
  +          {
  +            Recomposable node = (Recomposable) v.elementAt(lo);
  +            v.setElementAt(v.elementAt(hi), lo);
  +            v.setElementAt(node, hi);
  +
  +            ++lo;
  +            --hi;
  +          }
  +        }
  +
  +        // If the right index has not reached the left side of array
  +        // must now sort the left partition.
  +        if( lo0 < hi )
  +        {
  +          QuickSort2( v, lo0, hi );
  +        }
  +
  +        // If the left index has not reached the right side of array
  +        // must now sort the right partition.
  +        if( lo < hi0 )
  +        {
  +          QuickSort2( v, lo, hi0 );
  +        }
  +      }
  +    } // end QuickSort2  */
   }
  
  
  
  1.23      +42 -119   xml-xalan/java/src/org/apache/xalan/templates/TemplateList.java
  
  Index: TemplateList.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/TemplateList.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- TemplateList.java	2000/11/23 04:57:57	1.22
  +++ TemplateList.java	2000/11/30 09:57:33	1.23
  @@ -85,17 +85,15 @@
   
     /**
      * Construct a TemplateList object.
  -   *
  -   * @param stylesheet -- The stylesheet owner, must be valid (non-null).
      */
  -  TemplateList(Stylesheet stylesheet)
  +  TemplateList()
     {
  -    m_stylesheet = stylesheet;
  -    m_stylesheetComposed = m_stylesheet.getStylesheetComposed();
  +    super();
     }
   
     /**
  -   * Add a template to the template list.
  +   * Add a template to the table of named templates.  This routine should
  +   * be called in decreasing order of precedence but it checks nonetheless.
      *
      * @param template
      */
  @@ -103,13 +101,23 @@
     {
       if (null != template.getName())
       {
  -      if (m_namedTemplates.get(template.getName()) == null)
  +      ElemTemplate existingTemplate = (ElemTemplate) m_namedTemplates.get(template.getName());
  +      if (null == existingTemplate)
         {
           m_namedTemplates.put(template.getName(), template);
         }
         else
         {
  -        template.error(XSLTErrorResources.ER_DUPLICATE_NAMED_TEMPLATE,
  +        int existingPrecedence =
  +                        existingTemplate.getStylesheetComposed().getImportCountComposed();
  +        int newPrecedence = template.getStylesheetComposed().getImportCountComposed();
  +        if (newPrecedence > existingPrecedence)
  +        {
  +          // This should never happen
  +          m_namedTemplates.put(template.getName(), template);
  +        }
  +        else if (newPrecedence == existingPrecedence)
  +          template.error(XSLTErrorResources.ER_DUPLICATE_NAMED_TEMPLATE,
                          new Object[]{ template.getName() });
         }
       }
  @@ -232,7 +240,7 @@
   
     /**
      * Insert the given TemplateSubPatternAssociation into the the linked
  -   * list.  Sort by priority first, then by document order.
  +   * list.  Sort by import precedence, then priority, then by document order.
      *
      * @param head The first TemplateSubPatternAssociation in the linked list.
      * @param item The item that we want to insert into the proper place.
  @@ -246,8 +254,8 @@
                                            boolean isWildCardInsert)
     {
   
  -    // Sort first by decreasing priority (highest priority is at front),
  -    // then by import level (higher level is at front),
  +    // Sort first by import level (higher level is at front),
  +    // then by priority (highest priority is at front),
       // then by document order (later in document is at front).
   
       double priority = getPriorityOrScore(item);
  @@ -262,7 +270,7 @@
   
       // Spin down so that insertPoint points to:
       // (a) the template immediately _before_ the first template on the chain with
  -    // a priority that is either (i) less than ours or (ii) the same as ours but
  +    // a precedence that is either (i) less than ours or (ii) the same as ours but
       // the template document position is less than ours
       // -or-
       // (b) the last template on the chain if no such template described in (a) exists.
  @@ -278,13 +286,13 @@
         else
         {
           workPriority = getPriorityOrScore(next);
  -        if (priority > workPriority)
  +        if (importLevel > next.getImportLevel())
             break;
  -        else if (priority < workPriority)
  +        else if (importLevel < next.getImportLevel())
             insertPoint = next;
  -        else if (importLevel > next.getImportLevel())   // priorities are equal
  +        else if (priority > workPriority)               // import precedence is equal
             break;
  -        else if (importLevel < next.getImportLevel())
  +        else if (priority < workPriority)
             insertPoint = next;
           else if (docOrder >= next.getDocOrderPos())     // priorities, import are equal
             break;
  @@ -296,13 +304,13 @@
       if ( (null == next) || (insertPoint == head) )      // insert point is first or last
       {
         workPriority = getPriorityOrScore(insertPoint);
  -      if (priority > workPriority)
  +      if (importLevel > insertPoint.getImportLevel())
           insertBefore = true;
  -      else if (priority < workPriority)
  +      else if (importLevel < insertPoint.getImportLevel())
           insertBefore = false;
  -      else if (importLevel > insertPoint.getImportLevel())
  +      else if (priority > workPriority)
           insertBefore = true;
  -      else if (importLevel < insertPoint.getImportLevel())
  +      else if (priority < workPriority)
           insertBefore = false;
         else if (docOrder >= insertPoint.getDocOrderPos())
           insertBefore = true;
  @@ -430,28 +438,7 @@
      */
     public ElemTemplate getTemplate(QName qname)
     {
  -
  -    ElemTemplate namedTemplate = (ElemTemplate) m_namedTemplates.get(qname);
  -
  -    if (null == namedTemplate)
  -    {
  -      StylesheetComposed stylesheet = m_stylesheetComposed;
  -      int n = stylesheet.getImportCountComposed();
  -
  -      for (int i = 0; i < n; i++)
  -      {
  -        StylesheetComposed imported = stylesheet.getImportComposed(i);
  -
  -        namedTemplate = imported.getTemplateComposed(qname);
  -
  -        if (null != namedTemplate)
  -        {
  -          break;
  -        }
  -      }
  -    }
  -
  -    return namedTemplate;
  +    return (ElemTemplate) m_namedTemplates.get(qname);
     }
   
     /**
  @@ -508,13 +495,13 @@
      * Given a target element, find the template that best
      * matches in the given XSL document, according
      * to the rules specified in the xsl draft.
  -   * @param stylesheetTree Where the XSL rules are to be found.
  -   * @param targetElem The element that needs a rule.
      *
      * @param xctxt
      * @param targetNode
      * @param mode A string indicating the display mode.
  -   * @param useImports means that this is an xsl:apply-imports commend.
  +   * @param maxImportLevel The maximum importCountComposed that we should consider or -1
  +   *        if we should consider all import levels.  This is used by apply-imports to
  +   *        access templates that have been overridden.
      * @param quietConflictWarnings
      * @return Rule that best matches targetElem.
      * @exception XSLProcessorException thrown if the active ProblemListener and XPathContext decide
  @@ -522,8 +509,11 @@
      *
      * @throws TransformerException
      */
  -  public ElemTemplate getTemplate(
  -          XPathContext xctxt, Node targetNode, QName mode, boolean quietConflictWarnings)
  +  public ElemTemplate getTemplate(XPathContext xctxt,
  +                                Node targetNode,
  +                                QName mode,
  +                                int maxImportLevel,
  +                                boolean quietConflictWarnings)
               throws TransformerException
     {
   
  @@ -537,6 +527,11 @@
   
           do
           {
  +          if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel) )
  +          {
  +            continue;
  +          }
  +
             if ((head.m_stepPattern.execute(xctxt) != NodeTest.SCORE_NONE)
                     && head.matchMode(mode))
             {
  @@ -554,22 +549,6 @@
         }
       }
   
  -    int n = m_stylesheetComposed.getImportCountComposed();
  -
  -    if (0 != n)
  -    {
  -      for (int i = 0; i < n; i++)
  -      {
  -        StylesheetComposed imported =
  -          m_stylesheetComposed.getImportComposed(i);
  -        ElemTemplate t = getTemplate(imported, xctxt, targetNode, mode,
  -                                     quietConflictWarnings);
  -
  -        if (null != t)
  -          return t;
  -      }
  -    }
  -
       return null;
     }  // end findTemplate
   
  @@ -589,28 +568,6 @@
     }
   
     /**
  -   * For derived classes to override which method gets accesed to
  -   * get the imported template.
  -   *
  -   * @param imported
  -   * @param support
  -   * @param targetNode
  -   * @param mode
  -   * @param quietConflictWarnings
  -   *
  -   * @return
  -   *
  -   * @throws TransformerException
  -   */
  -  protected ElemTemplate getTemplate(
  -          StylesheetComposed imported, XPathContext support, Node targetNode, QName mode, boolean quietConflictWarnings)
  -            throws TransformerException
  -  {
  -    return imported.getTemplateComposed(support, targetNode, mode,
  -                                        quietConflictWarnings);
  -  }
  -
  -  /**
      * Add object to vector if not already there.
      *
      * @param obj
  @@ -636,40 +593,6 @@
       {
         v.addElement(obj);
       }
  -  }
  -
  -  /**
  -   * The stylesheet owner of the list.
  -   */
  -  private Stylesheet m_stylesheet;
  -
  -  /** NEEDSDOC Field m_stylesheetComposed          */
  -  private StylesheetComposed m_stylesheetComposed;
  -
  -  /**
  -   * Get the stylesheet owner of the list.
  -   *
  -   * @return
  -   */
  -  private Stylesheet getStylesheet()
  -  {
  -    return m_stylesheet;
  -  }
  -
  -  /**
  -   * The first template of the template children.
  -   * @serial
  -   */
  -  private ElemTemplateElement m_firstTemplate = null;
  -
  -  /**
  -   * Get the first template of the template children.
  -   *
  -   * @return
  -   */
  -  private ElemTemplateElement getFirstTemplate()
  -  {
  -    return m_firstTemplate;
     }
   
     /**
  
  
  
  1.5       +9 -0      xml-xalan/java/src/org/apache/xalan/templates/WhiteSpaceInfo.java
  
  Index: WhiteSpaceInfo.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/WhiteSpaceInfo.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- WhiteSpaceInfo.java	2000/11/17 20:37:11	1.4
  +++ WhiteSpaceInfo.java	2000/11/30 09:57:33	1.5
  @@ -97,4 +97,13 @@
   
       setStylesheet(thisSheet);
     }
  +
  +  /**
  +   * This function is called to recompose() all of the WhiteSpaceInfo elements.
  +   */
  +  public void recompose(StylesheetRoot root)
  +  {
  +    root.recomposeWhiteSpaceInfo(this);
  +  }
  +
   }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/templates/Recomposable.java
  
  Index: Recomposable.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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;
  
  /**
   * This interface defines a recomposable stylesheet element.  The interface requires
   * the compareTo() method.
   * When we migrate to Java2, ththe compareTo method should be removed this interface
   * should also extend java.lang.Comparable.
   */
  
  interface Recomposable extends RecomposableBase
  {
  
    /**
     *  Returns the composed stylesheet to which this recomposable element belongs.
     */ 
    public StylesheetComposed getStylesheetComposed();
  
    /**
     *  Returns the relative document order for this recomposable element.
     */ 
    public int getUid();
  
    /**
     * Compares this object with the specified object for precedence order.
     * The order is determined by the getImportCountComposed() of the containing
     * composed stylesheet and the getUid() of this element.
     * Returns a negative integer, zero, or a positive integer as this
     * object is less than, equal to, or greater than the specified object.
     * @param o The object to be compared to this object
     * @returns a negative integer, zero, or a positive integer as this object is
     *          less than, equal to, or greater than the specified object.
     * @throws ClassCastException if the specified object's
     *         type prevents it from being compared to this Object.
     */
    public int compareTo(Object o) throws ClassCastException;
  }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/templates/RecomposableBase.java
  
  Index: RecomposableBase.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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;
  
  /**
   * This interface defines a recomposable stylesheet element that does not
   * necessarily implement the compareTo() method.
   */
  interface RecomposableBase
  {
  
    /**
     * Recomposes this object with others of its type.
     */
    public void recompose(StylesheetRoot root);
  }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/templates/RecomposableImpl.java
  
  Index: RecomposableImpl.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999 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;
  
  /**
   * This class creates a recomposable object when the underlying object does
   * not implement Recomposable itself.
   */
  class RecomposableImpl implements Recomposable
  {
  
    /**
     * The precedence level stylesheet with which this object is associated.
     */
    private StylesheetComposed m_owningStylesheet;
  
    /**
     * The document order in which which object was encountered.
     */
    private int m_docOrderNumber;
  
    /**
     * The underlying object for the recomposition.
     */
    private RecomposableBase m_obj;
  
    RecomposableImpl(StylesheetComposed owningStylesheet, int uid, RecomposableBase o)
    {
      m_owningStylesheet = owningStylesheet;
      m_docOrderNumber = uid;
      m_obj = o;
    }
  
    /**
     *  Returns the composed stylesheet to which this recomposable element belongs.
     */ 
    public StylesheetComposed getStylesheetComposed()
    {
      return m_owningStylesheet;
    }
  
    /**
     *  Returns the relative document order for this recomposable element.
     */ 
    public int getUid()
    {
      return m_docOrderNumber;
    }
  
    /**
     * Compares this object with the specified object for precedence order.
     * The order is determined by the getImportCountComposed() of the containing
     * composed stylesheet and the getUid() of this element.
     * Returns a negative integer, zero, or a positive integer as this
     * object is less than, equal to, or greater than the specified object.
     * @param o The object to be compared to this object
     * @returns a negative integer, zero, or a positive integer as this object is
     *          less than, equal to, or greater than the specified object.
     * @throws ClassCastException if the specified object's
     *         type prevents it from being compared to this Object.
     */
    public int compareTo(Object o) throws ClassCastException {
      
      Recomposable ro = (Recomposable) o;
      int roPrecedence = ro.getStylesheetComposed().getImportCountComposed();
      int myPrecedence = m_owningStylesheet.getImportCountComposed();
  
      if (myPrecedence < roPrecedence)
        return -1;
      else if (myPrecedence > roPrecedence)
        return 1;
      else
        return m_docOrderNumber - ro.getUid();
    }
  
    /**
     * Recomposes this object with others of its type.
     */
    public void recompose(StylesheetRoot root)
    {
      m_obj.recompose(root);
    }
  
  }
  
  
  
  1.8       +2 -2      xml-xalan/java/src/org/apache/xalan/transformer/KeyManager.java
  
  Index: KeyManager.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/KeyManager.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- KeyManager.java	2000/11/23 04:58:16	1.7
  +++ KeyManager.java	2000/11/30 09:57:38	1.8
  @@ -101,7 +101,7 @@
       ElemTemplateElement template = (ElemTemplateElement) nscontext;  // yuck -sb
   
       if ((null != template)
  -            && null != template.getStylesheetComposed().getKeysComposed())
  +            && null != template.getStylesheetRoot().getKeysComposed())
       {
         boolean foundDoc = false;
   
  @@ -135,7 +135,7 @@
         {
           KeyTable kt =
             new KeyTable(doc, nscontext, name,
  -                       template.getStylesheetComposed().getKeysComposed(),
  +                       template.getStylesheetRoot().getKeysComposed(),
                          xctxt);
   
           m_key_tables.addElement(kt);
  
  
  
  1.55      +23 -49    xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
  
  Index: TransformerImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- TransformerImpl.java	2000/11/23 04:58:21	1.54
  +++ TransformerImpl.java	2000/11/30 09:57:38	1.55
  @@ -1209,17 +1209,9 @@
         {
           StylesheetComposed imported = stylesheet.getGlobalImport(i);
   
  -        imported.runtimeInit(this);
  -
  -        for (ElemTemplateElement child = imported.getFirstChildElem();
  -                child != null; child = child.getNextSiblingElem())
  -        {
  -          child.runtimeInit(this);
  -        }
  -
           int includedCount = imported.getIncludeCountComposed();
   
  -        for (int j = 0; j < includedCount; j++)
  +        for (int j = -1; j < includedCount; j++)
           {
             Stylesheet included = imported.getIncludeComposed(j);
   
  @@ -1901,10 +1893,8 @@
      * Given an element and mode, find the corresponding
      * template and process the contents.
      *
  -   * @param stylesheetTree The current Stylesheet object.
      * @param xslInstruction The calling element.
      * @param template The template to use if xsl:for-each, or null.
  -   * @param selectContext The selection context.
      * @param child The source context node.
      * @param mode The current mode, may be null.
      * @exception TransformerException
  @@ -1917,52 +1907,34 @@
     {
   
       short nodeType = child.getNodeType();
  -    boolean isApplyImports = ((xslInstruction == null)
  -                              ? false
  -                              : xslInstruction.getXSLToken()
  -                                == Constants.ELEMNAME_APPLY_IMPORTS);
  -
  -    // To find templates, use the the root of the import tree if 
  -    // this element is not an xsl:apply-imports or starting from the root, 
  -    // otherwise use the root of the stylesheet tree.
  -    // TODO: Not sure apply-import handling is correct right now.  -sb
  -    StylesheetComposed stylesheetTree;
  -
  -    if (isApplyImports)
  -    {
  -      StylesheetComposed stylesheet = xslInstruction.getStylesheetComposed();
  -      StylesheetRoot sroot = stylesheet.getStylesheetRoot();
  -      int importNumber = sroot.getImportNumber(stylesheet);
  -      int nImports = sroot.getGlobalImportCount();
  -
  -      if (importNumber < (nImports - 1))
  -        stylesheetTree = sroot.getGlobalImport(importNumber + 1);
  -      else
  -        return false;
  -    }
  -    else
  -    {
  -      stylesheetTree = (null == template)
  -                       ? getStylesheet() : template.getStylesheetComposed();
  -    }
  -
  -    XPathContext xctxt = getXPathContext();
       boolean isDefaultTextRule = false;
   
       if (null == template)
       {
  +      int maxImportLevel;
  +      boolean isApplyImports = ((xslInstruction == null)
  +                                ? false
  +                                : xslInstruction.getXSLToken()
  +                                  == Constants.ELEMNAME_APPLY_IMPORTS);
  +
  +      if (isApplyImports)
  +      {
  +        maxImportLevel = xslInstruction.getStylesheetComposed().getImportCountComposed() - 1;
  +      }
  +      else
  +      {
  +        maxImportLevel = -1;
  +      }
   
         // Find the XSL template that is the best match for the 
         // element.        
  +      XPathContext xctxt = getXPathContext();
         PrefixResolver savedPrefixResolver = xctxt.getNamespaceContext();
   
         try
         {
           xctxt.setNamespaceContext(xslInstruction);
  -
  -        TemplateList tl = stylesheetTree.getTemplateListComposed();
  -
  -        template = tl.getTemplate(xctxt, child, mode,
  +        template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode, maxImportLevel,
                                     m_quietConflictWarnings);
         }
         finally
  @@ -2024,6 +1996,12 @@
         else
         {
   
  +        // Fire a trace event for the template.
  +
  +        if (TransformerImpl.S_DEBUG)
  +          getTraceManager().fireTraceEvent(child, mode, template);
  +
  +        // And execute the child templates.
           // 9/11/00: If template has been compiled, hand off to it
           // since much (most? all?) of the processing has been inlined.
           // (It would be nice if there was a single entry point that
  @@ -2032,11 +2010,7 @@
           // compiled obviously has to run its own code. It's
           // also unclear that "execute" is really the right name for
           // that entry point.)
  -        // Fire a trace event for the template.
  -        if (TransformerImpl.S_DEBUG)
  -          getTraceManager().fireTraceEvent(child, mode, template);
   
  -        // And execute the child templates.
           if (template.isCompiledTemplate())
             template.execute(this, child, mode);
           else