templatelist.java

来自「java jdk 1.4的源码」· Java 代码 · 共 958 行 · 第 1/2 页

JAVA
958
字号
/* * 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;import java.util.Hashtable;import java.util.Vector;import java.util.Enumeration;import java.io.Serializable;//import org.w3c.dom.Node;import org.apache.xml.dtm.DTM;import org.apache.xml.dtm.ref.ExpandedNameTable;import javax.xml.transform.TransformerException;import org.apache.xml.utils.QName;import org.apache.xml.utils.PrefixResolver;import org.apache.xpath.XPath;import org.apache.xpath.compiler.PsuedoNames;import org.apache.xpath.patterns.NodeTest;import org.apache.xpath.Expression;import org.apache.xalan.res.XSLTErrorResources;import org.apache.xpath.XPathContext;import org.apache.xpath.patterns.StepPattern;import org.apache.xpath.patterns.UnionPattern;/** * <meta name="usage" content="advanced"/> * Encapsulates a template list, and helps locate individual templates. */public class TemplateList implements java.io.Serializable{  /**   * Construct a TemplateList object. Needs to be public so it can   * be invoked from the CompilingStylesheetHandler.   */  public TemplateList()  {    super();  }  /**   * Add a template to the table of named templates and/or the table of templates   * with match patterns.  This routine should   * be called in decreasing order of precedence but it checks nonetheless.   *   * @param template   */  public void setTemplate(ElemTemplate template)  {    if (null != template.getName())    {      ElemTemplate existingTemplate = (ElemTemplate) m_namedTemplates.get(template.getName());      if (null == existingTemplate)      {        m_namedTemplates.put(template.getName(), template);      }      else      {        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() });      }    }    XPath matchXPath = template.getMatch();    if (null != matchXPath)    {      Expression matchExpr = matchXPath.getExpression();      if (matchExpr instanceof StepPattern)      {        insertPatternInTable((StepPattern) matchExpr, template);      }      else if (matchExpr instanceof UnionPattern)      {        UnionPattern upat = (UnionPattern) matchExpr;        StepPattern[] pats = upat.getPatterns();        int n = pats.length;        for (int i = 0; i < n; i++)        {          insertPatternInTable(pats[i], template);        }      }      else      {        // TODO: assert error      }    }  }  /** Flag to indicate whether in DEBUG mode          */  static boolean DEBUG = false;  /**   * Dump all patterns and elements that match those patterns   *   */  void dumpAssociationTables()  {    Enumeration associations = m_patternTable.elements();    while (associations.hasMoreElements())    {      TemplateSubPatternAssociation head =        (TemplateSubPatternAssociation) associations.nextElement();      while (null != head)      {        System.out.print("(" + head.getTargetString() + ", "                         + head.getPattern() + ")");        head = head.getNext();      }      System.out.println("\n.....");    }    TemplateSubPatternAssociation head = m_wildCardPatterns;    System.out.print("wild card list: ");    while (null != head)    {      System.out.print("(" + head.getTargetString() + ", "                       + head.getPattern() + ")");      head = head.getNext();    }    System.out.println("\n.....");  }  /**   * After all templates have been added, this function   * should be called.   */  public void compose(StylesheetRoot sroot)  {    if (DEBUG)    {      System.out.println("Before wildcard insert...");      dumpAssociationTables();    }    if (null != m_wildCardPatterns)    {      Enumeration associations = m_patternTable.elements();      while (associations.hasMoreElements())      {        TemplateSubPatternAssociation head =          (TemplateSubPatternAssociation) associations.nextElement();        TemplateSubPatternAssociation wild = m_wildCardPatterns;        while (null != wild)        {          try          {            head = insertAssociationIntoList(              head, (TemplateSubPatternAssociation) wild.clone(), true);          }          catch (CloneNotSupportedException cnse){}          wild = wild.getNext();        }      }    }    if (DEBUG)    {      System.out.println("After wildcard insert...");      dumpAssociationTables();    }  }  /**   * Insert the given TemplateSubPatternAssociation into the the linked   * 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.   * @param isWildCardInsert <code>true</code> if we are inserting a wild card    *             template onto this list.   * @return the new head of the list.   */  private TemplateSubPatternAssociation              insertAssociationIntoList(TemplateSubPatternAssociation head,                                         TemplateSubPatternAssociation item,                                         boolean isWildCardInsert)  {    // 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);    double workPriority;    int importLevel = item.getImportLevel();    int docOrder = item.getDocOrderPos();    TemplateSubPatternAssociation insertPoint = head;    TemplateSubPatternAssociation next;    boolean insertBefore;         // true means insert before insertPoint; otherwise after                                  // This can only be true if insertPoint is pointing to                                  // the first or last template.    // Spin down so that insertPoint points to:    // (a) the template immediately _before_ the first template on the chain with    // 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.    // If we are pointing to the first template or the last template (that is, case b),    // we need to determine whether to insert before or after the template.  Otherwise,    // we always insert after the insertPoint.    while (true)    {      next = insertPoint.getNext();      if (null == next)        break;      else      {        workPriority = getPriorityOrScore(next);        if (importLevel > next.getImportLevel())          break;        else if (importLevel < next.getImportLevel())          insertPoint = next;        else if (priority > workPriority)               // import precedence is equal          break;        else if (priority < workPriority)          insertPoint = next;        else if (docOrder >= next.getDocOrderPos())     // priorities, import are equal          break;        else          insertPoint = next;      }    }    if ( (null == next) || (insertPoint == head) )      // insert point is first or last    {      workPriority = getPriorityOrScore(insertPoint);      if (importLevel > insertPoint.getImportLevel())        insertBefore = true;      else if (importLevel < insertPoint.getImportLevel())        insertBefore = false;      else if (priority > workPriority)        insertBefore = true;      else if (priority < workPriority)        insertBefore = false;      else if (docOrder >= insertPoint.getDocOrderPos())        insertBefore = true;      else        insertBefore = false;    }    else      insertBefore = false;    // System.out.println("appending: "+target+" to "+matchPat.getPattern());        if (isWildCardInsert)    {      if (insertBefore)      {        item.setNext(insertPoint);        String key = insertPoint.getTargetString();        item.setTargetString(key);        putHead(key, item);        return item;      }      else      {        item.setNext(next);        insertPoint.setNext(item);        return head;      }    }    else    {      if (insertBefore)      {        item.setNext(insertPoint);        if (insertPoint.isWild() || item.isWild())          m_wildCardPatterns = item;        else          putHead(item.getTargetString(), item);        return item;      }      else      {        item.setNext(next);        insertPoint.setNext(item);        return head;      }    }  }  /**   * Add a template to the template list.   *   * @param pattern   * @param template   */  private void insertPatternInTable(StepPattern pattern, ElemTemplate template)  {    String target = pattern.getTargetString();    if (null != target)    {      String pstring = template.getMatch().getPatternString();      TemplateSubPatternAssociation association =        new TemplateSubPatternAssociation(template, pattern, pstring);      // See if there's already one there      boolean isWildCard = association.isWild();      TemplateSubPatternAssociation head = isWildCard                                           ? m_wildCardPatterns                                           : getHead(target);      if (null == head)      {        if (isWildCard)          m_wildCardPatterns = association;        else          putHead(target, association);      }      else      {        insertAssociationIntoList(head, association, false);      }    }  }  /**   * Given a match pattern and template association, return the    * score of that match.  This score or priority can always be    * statically calculated.   *   * @param matchPat The match pattern to template association.   *   * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or   *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}, or    *         the value defined by the priority attribute of the template.   *   */  private double getPriorityOrScore(TemplateSubPatternAssociation matchPat)  {    double priority = matchPat.getTemplate().getPriority();    if (priority == XPath.MATCH_SCORE_NONE)    {      Expression ex = matchPat.getStepPattern();      if (ex instanceof NodeTest)      {        return ((NodeTest) ex).getDefaultScore();      }    }    return priority;  }  /**   * Locate a named template.   *   * @param qname  Qualified name of the template.   *   * @return Template argument with the requested name, or null if not found.   */  public ElemTemplate getTemplate(QName qname)  {    return (ElemTemplate) m_namedTemplates.get(qname);  }  /**   * Get the head of the most likely list of associations to check, based on    * the name and type of the targetNode argument.   *   * @param xctxt The XPath runtime context.   * @param targetNode The target node that will be checked for a match.   * @param dtm The dtm owner for the target node.   *   * @return The head of a linked list that contains all possible match pattern to    * template associations.   */  public TemplateSubPatternAssociation getHead(XPathContext xctxt,                                                int targetNode, DTM dtm)  {    short targetNodeType = dtm.getNodeType(targetNode);    TemplateSubPatternAssociation head;    switch (targetNodeType)    {    case DTM.ELEMENT_NODE :    case DTM.ATTRIBUTE_NODE :      head = (TemplateSubPatternAssociation) m_patternTable.get(        dtm.getLocalName(targetNode));      break;    case DTM.TEXT_NODE :    case DTM.CDATA_SECTION_NODE :      head = m_textPatterns;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?