19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: TemplateList.java 468643 2006-10-28 06:56:03Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xalan.templates;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Enumeration;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Hashtable;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Vector;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.QName;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.Expression;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPath;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathContext;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.PsuedoNames;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.NodeTest;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.StepPattern;
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.UnionPattern;
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Encapsulates a template list, and helps locate individual templates.
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage advanced
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class TemplateList implements java.io.Serializable
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = 5803675288911728791L;
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Construct a TemplateList object. Needs to be public so it can
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be invoked from the CompilingStylesheetHandler.
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public TemplateList()
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super();
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Add a template to the table of named templates and/or the table of templates
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * with match patterns.  This routine should
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be called in decreasing order of precedence but it checks nonetheless.
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param template
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setTemplate(ElemTemplate template)
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XPath matchXPath = template.getMatch();
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null == template.getName() && null == matchXPath)
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      template.error(XSLTErrorResources.ER_NEED_NAME_OR_MATCH_ATTRIB,
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          new Object[]{ "xsl:template" });
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != template.getName())
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ElemTemplate existingTemplate = (ElemTemplate) m_namedTemplates.get(template.getName());
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == existingTemplate)
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_namedTemplates.put(template.getName(), template);
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int existingPrecedence =
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        existingTemplate.getStylesheetComposed().getImportCountComposed();
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int newPrecedence = template.getStylesheetComposed().getImportCountComposed();
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (newPrecedence > existingPrecedence)
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // This should never happen
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_namedTemplates.put(template.getName(), template);
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (newPrecedence == existingPrecedence)
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          template.error(XSLTErrorResources.ER_DUPLICATE_NAMED_TEMPLATE,
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       new Object[]{ template.getName() });
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != matchXPath)
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Expression matchExpr = matchXPath.getExpression();
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (matchExpr instanceof StepPattern)
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertPatternInTable((StepPattern) matchExpr, template);
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (matchExpr instanceof UnionPattern)
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        UnionPattern upat = (UnionPattern) matchExpr;
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        StepPattern[] pats = upat.getPatterns();
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int n = pats.length;
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int i = 0; i < n; i++)
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          insertPatternInTable(pats[i], template);
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // TODO: assert error
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Flag to indicate whether in DEBUG mode          */
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  final static boolean DEBUG = false;
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Dump all patterns and elements that match those patterns
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  void dumpAssociationTables()
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Enumeration associations = m_patternTable.elements();
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (associations.hasMoreElements())
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      TemplateSubPatternAssociation head =
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        (TemplateSubPatternAssociation) associations.nextElement();
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (null != head)
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        System.out.print("(" + head.getTargetString() + ", "
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         + head.getPattern() + ")");
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        head = head.getNext();
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("\n.....");
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation head = m_wildCardPatterns;
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.print("wild card list: ");
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (null != head)
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print("(" + head.getTargetString() + ", "
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       + head.getPattern() + ")");
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = head.getNext();
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("\n.....");
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * After all templates have been added, this function
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * should be called.
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void compose(StylesheetRoot sroot)
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DEBUG)
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("Before wildcard insert...");
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      dumpAssociationTables();
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_wildCardPatterns)
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Enumeration associations = m_patternTable.elements();
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (associations.hasMoreElements())
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        TemplateSubPatternAssociation head =
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          (TemplateSubPatternAssociation) associations.nextElement();
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        TemplateSubPatternAssociation wild = m_wildCardPatterns;
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (null != wild)
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          try
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            head = insertAssociationIntoList(
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              head, (TemplateSubPatternAssociation) wild.clone(), true);
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          catch (CloneNotSupportedException cnse){}
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          wild = wild.getNext();
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DEBUG)
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("After wildcard insert...");
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      dumpAssociationTables();
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Insert the given TemplateSubPatternAssociation into the the linked
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * list.  Sort by import precedence, then priority, then by document order.
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param head The first TemplateSubPatternAssociation in the linked list.
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param item The item that we want to insert into the proper place.
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param isWildCardInsert <code>true</code> if we are inserting a wild card
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             template onto this list.
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the new head of the list.
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private TemplateSubPatternAssociation
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              insertAssociationIntoList(TemplateSubPatternAssociation head,
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         TemplateSubPatternAssociation item,
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         boolean isWildCardInsert)
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Sort first by import level (higher level is at front),
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // then by priority (highest priority is at front),
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // then by document order (later in document is at front).
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    double priority = getPriorityOrScore(item);
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    double workPriority;
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int importLevel = item.getImportLevel();
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int docOrder = item.getDocOrderPos();
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation insertPoint = head;
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation next;
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean insertBefore;         // true means insert before insertPoint; otherwise after
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  // This can only be true if insertPoint is pointing to
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  // the first or last template.
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Spin down so that insertPoint points to:
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // (a) the template immediately _before_ the first template on the chain with
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // a precedence that is either (i) less than ours or (ii) the same as ours but
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // the template document position is less than ours
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // -or-
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // (b) the last template on the chain if no such template described in (a) exists.
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // If we are pointing to the first template or the last template (that is, case b),
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // we need to determine whether to insert before or after the template.  Otherwise,
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // we always insert after the insertPoint.
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (true)
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      next = insertPoint.getNext();
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == next)
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        workPriority = getPriorityOrScore(next);
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (importLevel > next.getImportLevel())
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (importLevel < next.getImportLevel())
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          insertPoint = next;
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (priority > workPriority)               // import precedence is equal
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (priority < workPriority)
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          insertPoint = next;
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (docOrder >= next.getDocOrderPos())     // priorities, import are equal
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          insertPoint = next;
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if ( (null == next) || (insertPoint == head) )      // insert point is first or last
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      workPriority = getPriorityOrScore(insertPoint);
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (importLevel > insertPoint.getImportLevel())
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertBefore = true;
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (importLevel < insertPoint.getImportLevel())
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertBefore = false;
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (priority > workPriority)
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertBefore = true;
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (priority < workPriority)
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertBefore = false;
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (docOrder >= insertPoint.getDocOrderPos())
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertBefore = true;
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertBefore = false;
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      insertBefore = false;
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // System.out.println("appending: "+target+" to "+matchPat.getPattern());
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (isWildCardInsert)
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (insertBefore)
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        item.setNext(insertPoint);
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String key = insertPoint.getTargetString();
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        item.setTargetString(key);
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        putHead(key, item);
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return item;
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        item.setNext(next);
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertPoint.setNext(item);
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return head;
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (insertBefore)
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        item.setNext(insertPoint);
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (insertPoint.isWild() || item.isWild())
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_wildCardPatterns = item;
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          putHead(item.getTargetString(), item);
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return item;
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        item.setNext(next);
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertPoint.setNext(item);
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return head;
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Add a template to the template list.
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pattern
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param template
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void insertPatternInTable(StepPattern pattern, ElemTemplate template)
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String target = pattern.getTargetString();
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != target)
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String pstring = template.getMatch().getPatternString();
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      TemplateSubPatternAssociation association =
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        new TemplateSubPatternAssociation(template, pattern, pstring);
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // See if there's already one there
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean isWildCard = association.isWild();
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      TemplateSubPatternAssociation head = isWildCard
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                           ? m_wildCardPatterns
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                           : getHead(target);
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == head)
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (isWildCard)
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_wildCardPatterns = association;
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          putHead(target, association);
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        insertAssociationIntoList(head, association, false);
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a match pattern and template association, return the
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * score of that match.  This score or priority can always be
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * statically calculated.
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param matchPat The match pattern to template association.
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}, or
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         the value defined by the priority attribute of the template.
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private double getPriorityOrScore(TemplateSubPatternAssociation matchPat)
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    double priority = matchPat.getTemplate().getPriority();
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (priority == XPath.MATCH_SCORE_NONE)
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Expression ex = matchPat.getStepPattern();
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (ex instanceof NodeTest)
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return ((NodeTest) ex).getDefaultScore();
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return priority;
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Locate a named template.
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param qname  Qualified name of the template.
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Template argument with the requested name, or null if not found.
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ElemTemplate getTemplate(QName qname)
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (ElemTemplate) m_namedTemplates.get(qname);
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the head of the most likely list of associations to check, based on
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the name and type of the targetNode argument.
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The XPath runtime context.
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param targetNode The target node that will be checked for a match.
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param dtm The dtm owner for the target node.
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The head of a linked list that contains all possible match pattern to
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * template associations.
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public TemplateSubPatternAssociation getHead(XPathContext xctxt,
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                               int targetNode, DTM dtm)
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    short targetNodeType = dtm.getNodeType(targetNode);
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation head;
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (targetNodeType)
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ELEMENT_NODE :
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ATTRIBUTE_NODE :
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getLocalName(targetNode));
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.TEXT_NODE :
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.CDATA_SECTION_NODE :
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_textPatterns;
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ENTITY_REFERENCE_NODE :
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ENTITY_NODE :
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.PROCESSING_INSTRUCTION_NODE :
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getLocalName(targetNode));
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.COMMENT_NODE :
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_commentPatterns;
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.DOCUMENT_NODE :
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.DOCUMENT_FRAGMENT_NODE :
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_docPatterns;
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.NOTATION_NODE :
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (null == head) ? m_wildCardPatterns : head;
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a target element, find the template that best
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * matches in the given XSL document, according
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to the rules specified in the xsl draft.  This variation of getTemplate
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * assumes the current node and current expression node have already been
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * pushed.
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param targetNode
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mode A string indicating the display mode.
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param maxImportLevel The maximum importCountComposed that we should consider or -1
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        if we should consider all import levels.  This is used by apply-imports to
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        access templates that have been overridden.
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param quietConflictWarnings
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Rule that best matches targetElem.
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the error condition is severe enough to halt processing.
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ElemTemplate getTemplateFast(XPathContext xctxt,
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                int targetNode,
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                int expTypeID,
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                QName mode,
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                int maxImportLevel,
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                boolean quietConflictWarnings,
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DTM dtm)
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation head;
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (dtm.getNodeType(targetNode))
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ELEMENT_NODE :
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ATTRIBUTE_NODE :
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getLocalNameFromExpandedNameID(expTypeID));
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.TEXT_NODE :
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.CDATA_SECTION_NODE :
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_textPatterns;
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ENTITY_REFERENCE_NODE :
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.ENTITY_NODE :
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.PROCESSING_INSTRUCTION_NODE :
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getLocalName(targetNode));
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.COMMENT_NODE :
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_commentPatterns;
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.DOCUMENT_NODE :
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.DOCUMENT_FRAGMENT_NODE :
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_docPatterns;
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case DTM.NOTATION_NODE :
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = (TemplateSubPatternAssociation) m_patternTable.get(
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        dtm.getNodeName(targetNode)); // %REVIEW% I think this is right
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null == head)
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      head = m_wildCardPatterns;
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(null == head)
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return null;
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // XSLT functions, such as xsl:key, need to be able to get to
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // current ElemTemplateElement via a cast to the prefix resolver.
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Setting this fixes bug idkey03.
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    xctxt.pushNamespaceContextNull();
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel) )
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          continue;
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ElemTemplate template = head.getTemplate();
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        xctxt.setNamespaceContext(template);
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((head.m_stepPattern.execute(xctxt, targetNode, dtm, expTypeID) != NodeTest.SCORE_NONE)
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && head.matchMode(mode))
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (quietConflictWarnings)
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            checkConflicts(head, xctxt, targetNode, mode);
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return template;
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (null != (head = head.getNext()));
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    finally
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      xctxt.popNamespaceContext();
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return null;
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end findTemplate
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a target element, find the template that best
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * matches in the given XSL document, according
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to the rules specified in the xsl draft.
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param targetNode
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mode A string indicating the display mode.
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param quietConflictWarnings
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Rule that best matches targetElem.
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the error condition is severe enough to halt processing.
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ElemTemplate getTemplate(XPathContext xctxt,
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                int targetNode,
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                QName mode,
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                boolean quietConflictWarnings,
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DTM dtm)
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation head = getHead(xctxt, targetNode, dtm);
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != head)
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // XSLT functions, such as xsl:key, need to be able to get to
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // current ElemTemplateElement via a cast to the prefix resolver.
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Setting this fixes bug idkey03.
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      xctxt.pushNamespaceContextNull();
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      xctxt.pushCurrentNodeAndExpression(targetNode, targetNode);
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          ElemTemplate template = head.getTemplate();
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          xctxt.setNamespaceContext(template);
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if ((head.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE)
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  && head.matchMode(mode))
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (quietConflictWarnings)
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              checkConflicts(head, xctxt, targetNode, mode);
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return template;
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (null != (head = head.getNext()));
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      finally
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        xctxt.popCurrentNodeAndExpression();
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        xctxt.popNamespaceContext();
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return null;
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end findTemplate
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a target element, find the template that best
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * matches in the given XSL document, according
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to the rules specified in the xsl draft.
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param targetNode
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mode A string indicating the display mode.
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param maxImportLevel The maximum importCountComposed that we should consider or -1
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        if we should consider all import levels.  This is used by apply-imports to
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        access templates that have been overridden.
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param endImportLevel The count of composed imports
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param quietConflictWarnings
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Rule that best matches targetElem.
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the error condition is severe enough to halt processing.
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ElemTemplate getTemplate(XPathContext xctxt,
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                int targetNode,
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                QName mode,
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                int maxImportLevel, int endImportLevel,
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                boolean quietConflictWarnings,
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DTM dtm)
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    TemplateSubPatternAssociation head = getHead(xctxt, targetNode, dtm);
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != head)
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // XSLT functions, such as xsl:key, need to be able to get to
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // current ElemTemplateElement via a cast to the prefix resolver.
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Setting this fixes bug idkey03.
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      xctxt.pushNamespaceContextNull();
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      xctxt.pushCurrentNodeAndExpression(targetNode, targetNode);
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        do
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if ( (maxImportLevel > -1) && (head.getImportLevel() > maxImportLevel))
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            continue;
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (head.getImportLevel()<= maxImportLevel - endImportLevel)
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return null;
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          ElemTemplate template = head.getTemplate();
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          xctxt.setNamespaceContext(template);
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if ((head.m_stepPattern.execute(xctxt, targetNode) != NodeTest.SCORE_NONE)
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  && head.matchMode(mode))
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (quietConflictWarnings)
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              checkConflicts(head, xctxt, targetNode, mode);
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return template;
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (null != (head = head.getNext()));
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      finally
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        xctxt.popCurrentNodeAndExpression();
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        xctxt.popNamespaceContext();
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return null;
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end findTemplate
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a TemplateWalker for use by a compiler.  See the documentation for
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the TreeWalker inner class for further details.
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public TemplateWalker getWalker()
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return new TemplateWalker();
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Check for match conflicts, and warn the stylesheet author.
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param head Template pattern
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt Current XPath context
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param targetNode Node matching the pattern
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void checkConflicts(TemplateSubPatternAssociation head,
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                              XPathContext xctxt, int targetNode, QName mode)
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // TODO: Check for conflicts.
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Add object to vector if not already there.
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param obj
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void addObjectIfNotFound(Object obj, Vector v)
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int n = v.size();
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean addIt = true;
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = 0; i < n; i++)
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (v.elementAt(i) == obj)
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        addIt = false;
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (addIt)
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      v.addElement(obj);
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Keyed on string macro names, and holding values
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that are macro elements in the XSL DOM tree.
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Initialized in initMacroLookupTable, and used in
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * findNamedTemplate.
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Hashtable m_namedTemplates = new Hashtable(89);
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This table is keyed on the target elements
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of patterns, and contains linked lists of
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the actual patterns that match the target element
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to some degree of specifity.
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Hashtable m_patternTable = new Hashtable(89);
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Wildcard patterns.
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial          */
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private TemplateSubPatternAssociation m_wildCardPatterns = null;
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Text Patterns.
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial          */
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private TemplateSubPatternAssociation m_textPatterns = null;
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Root document Patterns.
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial          */
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private TemplateSubPatternAssociation m_docPatterns = null;
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Comment Patterns.
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial          */
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private TemplateSubPatternAssociation m_commentPatterns = null;
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get table of named Templates.
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * These are keyed on template names, and holding values
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that are template elements.
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A Hashtable dictionary that contains {@link java.lang.String}s
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as the keys, and {@link org.apache.xalan.templates.ElemTemplate}s as the
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * values.
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Hashtable getNamedTemplates()
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_namedTemplates;
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set table of named Templates.
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * These are keyed on string macro names, and holding values
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that are template elements in the XSL DOM tree.
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Hashtable dictionary that contains {@link java.lang.String}s
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as the keys, and {@link org.apache.xalan.templates.ElemTemplate}s as the
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * values.
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void setNamedTemplates(Hashtable v)
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_namedTemplates = v;
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the head of the assocation list that is keyed by target.
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param key The name of a node.
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The head of a linked list that contains all possible match pattern to
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * template associations for the given key.
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private TemplateSubPatternAssociation getHead(String key)
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (TemplateSubPatternAssociation) m_patternTable.get(key);
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the head of the assocation list that is keyed by target.
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param key
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param assoc
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void putHead(String key, TemplateSubPatternAssociation assoc)
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (key.equals(PsuedoNames.PSEUDONAME_TEXT))
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_textPatterns = assoc;
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (key.equals(PsuedoNames.PSEUDONAME_ROOT))
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_docPatterns = assoc;
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (key.equals(PsuedoNames.PSEUDONAME_COMMENT))
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_commentPatterns = assoc;
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_patternTable.put(key, assoc);
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * An inner class used by a compiler to iterate over all of the ElemTemplates
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * stored in this TemplateList.  The compiler can replace returned templates
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * with their compiled equivalent.
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class TemplateWalker
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private Enumeration hashIterator;
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private boolean inPatterns;
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private TemplateSubPatternAssociation curPattern;
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private Hashtable m_compilerCache = new Hashtable();
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private TemplateWalker()
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      hashIterator = m_patternTable.elements();
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      inPatterns = true;
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      curPattern = null;
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public ElemTemplate next()
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ElemTemplate retValue = null;
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ElemTemplate ct;
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (true)
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (inPatterns)
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (null != curPattern)
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            curPattern = curPattern.getNext();
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (null != curPattern)
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            retValue = curPattern.getTemplate();
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (hashIterator.hasMoreElements())
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              curPattern = (TemplateSubPatternAssociation) hashIterator.nextElement();
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              retValue =  curPattern.getTemplate();
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              inPatterns = false;
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              hashIterator = m_namedTemplates.elements();
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!inPatterns)
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (hashIterator.hasMoreElements())
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            retValue = (ElemTemplate) hashIterator.nextElement();
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return null;
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ct = (ElemTemplate) m_compilerCache.get(new Integer(retValue.getUid()));
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null == ct)
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_compilerCache.put(new Integer(retValue.getUid()), retValue);
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return retValue;
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
924