⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 walkerfactory.java

📁 java1.6众多例子参考
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: WalkerFactory.java,v 1.2.4.1 2005/09/10 03:42:19 jeffsuttor Exp $ */package com.sun.org.apache.xpath.internal.axes;import com.sun.org.apache.xalan.internal.res.XSLMessages;import com.sun.org.apache.xml.internal.dtm.Axis;import com.sun.org.apache.xml.internal.dtm.DTMFilter;import com.sun.org.apache.xml.internal.dtm.DTMIterator;import com.sun.org.apache.xpath.internal.Expression;import com.sun.org.apache.xpath.internal.compiler.Compiler;import com.sun.org.apache.xpath.internal.compiler.FunctionTable;import com.sun.org.apache.xpath.internal.compiler.OpCodes;import com.sun.org.apache.xpath.internal.objects.XNumber;import com.sun.org.apache.xpath.internal.patterns.ContextMatchStepPattern;import com.sun.org.apache.xpath.internal.patterns.FunctionPattern;import com.sun.org.apache.xpath.internal.patterns.NodeTest;import com.sun.org.apache.xpath.internal.patterns.StepPattern;import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;/** * This class is both a factory for XPath location path expressions, * which are built from the opcode map output, and an analysis engine * for the location path expressions in order to provide optimization hints. */public class WalkerFactory{  /**   * This method is for building an array of possible levels   * where the target element(s) could be found for a match.   * @param lpi The owning location path iterator.   * @param compiler non-null reference to compiler object that has processed   *                 the XPath operations into an opcode map.   * @param stepOpCodePos The opcode position for the step.   *   * @return non-null AxesWalker derivative.   *   * @throws javax.xml.transform.TransformerException   * @xsl.usage advanced   */  static AxesWalker loadOneWalker(          WalkingIterator lpi, Compiler compiler, int stepOpCodePos)            throws javax.xml.transform.TransformerException  {    AxesWalker firstWalker = null;    int stepType = compiler.getOp(stepOpCodePos);    if (stepType != OpCodes.ENDOP)    {      // m_axesWalkers = new AxesWalker[1];      // As we unwind from the recursion, create the iterators.      firstWalker = createDefaultWalker(compiler, stepType, lpi, 0);      firstWalker.init(compiler, stepOpCodePos, stepType);    }    return firstWalker;  }  /**   * This method is for building an array of possible levels   * where the target element(s) could be found for a match.   * @param lpi The owning location path iterator object.   * @param compiler non-null reference to compiler object that has processed   *                 the XPath operations into an opcode map.   * @param stepOpCodePos The opcode position for the step.   * @param stepIndex The top-level step index withing the iterator.   *   * @return non-null AxesWalker derivative.   *   * @throws javax.xml.transform.TransformerException   * @xsl.usage advanced   */  static AxesWalker loadWalkers(          WalkingIterator lpi, Compiler compiler, int stepOpCodePos, int stepIndex)            throws javax.xml.transform.TransformerException  {    int stepType;    AxesWalker firstWalker = null;    AxesWalker walker, prevWalker = null;    int analysis = analyze(compiler, stepOpCodePos, stepIndex);    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))    {      walker = createDefaultWalker(compiler, stepOpCodePos, lpi, analysis);      walker.init(compiler, stepOpCodePos, stepType);      walker.exprSetParent(lpi);      // walker.setAnalysis(analysis);      if (null == firstWalker)      {        firstWalker = walker;      }      else      {        prevWalker.setNextWalker(walker);        walker.setPrevWalker(prevWalker);      }      prevWalker = walker;      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);      if (stepOpCodePos < 0)        break;    }    return firstWalker;  }    public static boolean isSet(int analysis, int bits)  {    return (0 != (analysis & bits));  }    public static void diagnoseIterator(String name, int analysis, Compiler compiler)  {    System.out.println(compiler.toString()+", "+name+", "                             + Integer.toBinaryString(analysis) + ", "                             + getAnalysisString(analysis));  }  /**   * Create a new LocPathIterator iterator.  The exact type of iterator   * returned is based on an analysis of the XPath operations.   *   * @param compiler non-null reference to compiler object that has processed   *                 the XPath operations into an opcode map.   * @param opPos The position of the operation code for this itterator.   *   * @return non-null reference to a LocPathIterator or derivative.   *   * @throws javax.xml.transform.TransformerException   */  public static DTMIterator newDTMIterator(          Compiler compiler, int opPos,          boolean isTopLevel)            throws javax.xml.transform.TransformerException  {    int firstStepPos = compiler.getFirstChildPos(opPos);    int analysis = analyze(compiler, firstStepPos, 0);    boolean isOneStep = isOneStep(analysis);    DTMIterator iter;    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?    if (isOneStep && walksSelfOnly(analysis) &&         isWild(analysis) && !hasPredicate(analysis))    {      if (DEBUG_ITERATOR_CREATION)        diagnoseIterator("SelfIteratorNoPredicate", analysis, compiler);      // Then use a simple iteration of the attributes, with node test       // and predicate testing.      iter = new SelfIteratorNoPredicate(compiler, opPos, analysis);    }    // Is the iteration exactly one child step?    else if (walksChildrenOnly(analysis) && isOneStep)    {      // Does the pattern specify *any* child with no predicate? (i.e. select="child::node()".      if (isWild(analysis) && !hasPredicate(analysis))      {        if (DEBUG_ITERATOR_CREATION)          diagnoseIterator("ChildIterator", analysis, compiler);        // Use simple child iteration without any test.        iter = new ChildIterator(compiler, opPos, analysis);      }      else      {        if (DEBUG_ITERATOR_CREATION)          diagnoseIterator("ChildTestIterator", analysis, compiler);        // Else use simple node test iteration with predicate test.        iter = new ChildTestIterator(compiler, opPos, analysis);      }    }    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?    else if (isOneStep && walksAttributes(analysis))    {      if (DEBUG_ITERATOR_CREATION)        diagnoseIterator("AttributeIterator", analysis, compiler);      // Then use a simple iteration of the attributes, with node test       // and predicate testing.      iter = new AttributeIterator(compiler, opPos, analysis);    }    else if(isOneStep && !walksFilteredList(analysis))    {      if( !walksNamespaces(analysis)       && (walksInDocOrder(analysis) || isSet(analysis, BIT_PARENT)))      {        if (false || DEBUG_ITERATOR_CREATION)          diagnoseIterator("OneStepIteratorForward", analysis, compiler);          // Then use a simple iteration of the attributes, with node test         // and predicate testing.        iter = new OneStepIteratorForward(compiler, opPos, analysis);      }      else      {        if (false || DEBUG_ITERATOR_CREATION)          diagnoseIterator("OneStepIterator", analysis, compiler);          // Then use a simple iteration of the attributes, with node test         // and predicate testing.        iter = new OneStepIterator(compiler, opPos, analysis);      }    }    // Analysis of "//center":    // bits: 1001000000001010000000000000011    // count: 3    // root    // child:node()    // BIT_DESCENDANT_OR_SELF    // It's highly possible that we should have a seperate bit set for     // "//foo" patterns.    // For at least the time being, we can't optimize patterns like     // "//table[3]", because this has to be analyzed as     // "/descendant-or-self::node()/table[3]" in order for the indexes     // to work right.    else if (isOptimizableForDescendantIterator(compiler, firstStepPos, 0)              // && getStepCount(analysis) <= 3               // && walksDescendants(analysis)               // && walksSubtreeOnlyFromRootOrContext(analysis)             )    {      if (DEBUG_ITERATOR_CREATION)        diagnoseIterator("DescendantIterator", analysis, compiler);      iter = new DescendantIterator(compiler, opPos, analysis);    }    else    {       if(isNaturalDocOrder(compiler, firstStepPos, 0, analysis))      {        if (false || DEBUG_ITERATOR_CREATION)        {          diagnoseIterator("WalkingIterator", analysis, compiler);        }          iter = new WalkingIterator(compiler, opPos, analysis, true);      }      else      {//        if (DEBUG_ITERATOR_CREATION)//          diagnoseIterator("MatchPatternIterator", analysis, compiler);////        return new MatchPatternIterator(compiler, opPos, analysis);        if (DEBUG_ITERATOR_CREATION)          diagnoseIterator("WalkingIteratorSorted", analysis, compiler);        iter = new WalkingIteratorSorted(compiler, opPos, analysis, true);      }    }    if(iter instanceof LocPathIterator)      ((LocPathIterator)iter).setIsTopLevel(isTopLevel);          return iter;  }    /**   * Special purpose function to see if we can optimize the pattern for    * a DescendantIterator.   *   * @param compiler non-null reference to compiler object that has processed   *                 the XPath operations into an opcode map.   * @param stepOpCodePos The opcode position for the step.   *   * @return 32 bits as an integer that give information about the location   * path as a whole.   *   * @throws javax.xml.transform.TransformerException   */  public static int getAxisFromStep(          Compiler compiler, int stepOpCodePos)            throws javax.xml.transform.TransformerException  {    int stepType = compiler.getOp(stepOpCodePos);    switch (stepType)    {    case OpCodes.FROM_FOLLOWING :      return Axis.FOLLOWING;    case OpCodes.FROM_FOLLOWING_SIBLINGS :      return Axis.FOLLOWINGSIBLING;    case OpCodes.FROM_PRECEDING :      return Axis.PRECEDING;    case OpCodes.FROM_PRECEDING_SIBLINGS :      return Axis.PRECEDINGSIBLING;    case OpCodes.FROM_PARENT :      return Axis.PARENT;    case OpCodes.FROM_NAMESPACE :      return Axis.NAMESPACE;    case OpCodes.FROM_ANCESTORS :      return Axis.ANCESTOR;    case OpCodes.FROM_ANCESTORS_OR_SELF :      return Axis.ANCESTORORSELF;    case OpCodes.FROM_ATTRIBUTES :      return Axis.ATTRIBUTE;    case OpCodes.FROM_ROOT :      return Axis.ROOT;    case OpCodes.FROM_CHILDREN :      return Axis.CHILD;    case OpCodes.FROM_DESCENDANTS_OR_SELF :      return Axis.DESCENDANTORSELF;    case OpCodes.FROM_DESCENDANTS :      return Axis.DESCENDANT;    case OpCodes.FROM_SELF :      return Axis.SELF;    case OpCodes.OP_EXTFUNCTION :    case OpCodes.OP_FUNCTION :    case OpCodes.OP_GROUP :    case OpCodes.OP_VARIABLE :      return Axis.FILTEREDLIST;    }    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "                               //+ stepType);   }        /**     * Get a corresponding BIT_XXX from an axis.     * @param axis One of Axis.ANCESTOR, etc.     * @return One of BIT_ANCESTOR, etc.     */    static public int getAnalysisBitFromAxes(int axis)    {      switch (axis) // Generate new traverser        {        case Axis.ANCESTOR :          return BIT_ANCESTOR;        case Axis.ANCESTORORSELF :          return BIT_ANCESTOR_OR_SELF;        case Axis.ATTRIBUTE :          return BIT_ATTRIBUTE;        case Axis.CHILD :          return BIT_CHILD;        case Axis.DESCENDANT :          return BIT_DESCENDANT;        case Axis.DESCENDANTORSELF :          return BIT_DESCENDANT_OR_SELF;        case Axis.FOLLOWING :          return BIT_FOLLOWING;        case Axis.FOLLOWINGSIBLING :          return BIT_FOLLOWING_SIBLING;        case Axis.NAMESPACE :        case Axis.NAMESPACEDECLS :          return BIT_NAMESPACE;        case Axis.PARENT :          return BIT_PARENT;        case Axis.PRECEDING :          return BIT_PRECEDING;        case Axis.PRECEDINGSIBLING :          return BIT_PRECEDING_SIBLING;        case Axis.SELF :          return BIT_SELF;        case Axis.ALLFROMNODE :          return BIT_DESCENDANT_OR_SELF;          // case Axis.PRECEDINGANDANCESTOR :        case Axis.DESCENDANTSFROMROOT :        case Axis.ALL :        case Axis.DESCENDANTSORSELFFROMROOT :          return BIT_ANY_DESCENDANT_FROM_ROOT;        case Axis.ROOT :          return BIT_ROOT;        case Axis.FILTEREDLIST :          return BIT_FILTER;        default :          return BIT_FILTER;      }    }    static boolean functionProximateOrContainsProximate(Compiler compiler,                                                       int opPos)  {    int endFunc = opPos + compiler.getOp(opPos + 1) - 1;    opPos = compiler.getFirstChildPos(opPos);    int funcID = compiler.getOp(opPos);    //  System.out.println("funcID: "+funcID);    //  System.out.println("opPos: "+opPos);    //  System.out.println("endFunc: "+endFunc);    switch(funcID)    {      case FunctionTable.FUNC_LAST:      case FunctionTable.FUNC_POSITION:        return true;      default:        opPos++;        int i = 0;        for (int p = opPos; p < endFunc; p = compiler.getNextOpPos(p), i++)        {          int innerExprOpPos = p+2;          int argOp = compiler.getOp(innerExprOpPos);          boolean prox = isProximateInnerExpr(compiler, innerExprOpPos);          if(prox)            return true;        }    }    return false;  }    static boolean isProximateInnerExpr(Compiler compiler, int opPos)  {    int op = compiler.getOp(opPos);    int innerExprOpPos = opPos+2;    switch(op)    {      case OpCodes.OP_ARGUMENT:        if(isProximateInnerExpr(compiler, innerExprOpPos))          return true;        break;      case OpCodes.OP_VARIABLE:      case OpCodes.OP_NUMBERLIT:      case OpCodes.OP_LITERAL:      case OpCodes.OP_LOCATIONPATH:        break; // OK      case OpCodes.OP_FUNCTION:        boolean isProx = functionProximateOrContainsProximate(compiler, opPos);        if(isProx)          return true;        break;      case OpCodes.OP_GT:      case OpCodes.OP_GTE:      case OpCodes.OP_LT:      case OpCodes.OP_LTE:      case OpCodes.OP_EQUALS:        int leftPos = compiler.getFirstChildPos(op);        int rightPos = compiler.getNextOpPos(leftPos);        isProx = isProximateInnerExpr(compiler, leftPos);        if(isProx)          return true;        isProx = isProximateInnerExpr(compiler, rightPos);

⌨️ 快捷键说明

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