Home | History | Annotate | Download | only in axes
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: WalkingIteratorSorted.java 468655 2006-10-28 07:12:06Z minchau $
     20  */
     21 package org.apache.xpath.axes;
     22 
     23 import org.apache.xml.dtm.Axis;
     24 import org.apache.xml.utils.PrefixResolver;
     25 import org.apache.xpath.compiler.Compiler;
     26 
     27 /**
     28  * This class iterates over set of nodes that needs to be sorted.
     29  * @xsl.usage internal
     30  */
     31 public class WalkingIteratorSorted extends WalkingIterator
     32 {
     33     static final long serialVersionUID = -4512512007542368213L;
     34 
     35 //  /** True if the nodes will be found in document order */
     36 //  protected boolean m_inNaturalOrder = false;
     37 
     38   /** True if the nodes will be found in document order, and this can
     39    * be determined statically. */
     40   protected boolean m_inNaturalOrderStatic = false;
     41 
     42   /**
     43    * Create a WalkingIteratorSorted object.
     44    *
     45    * @param nscontext The namespace context for this iterator,
     46    * should be OK if null.
     47    */
     48   public WalkingIteratorSorted(PrefixResolver nscontext)
     49   {
     50     super(nscontext);
     51   }
     52 
     53   /**
     54    * Create a WalkingIterator iterator, including creation
     55    * of step walkers from the opcode list, and call back
     56    * into the Compiler to create predicate expressions.
     57    *
     58    * @param compiler The Compiler which is creating
     59    * this expression.
     60    * @param opPos The position of this iterator in the
     61    * opcode list from the compiler.
     62    * @param shouldLoadWalkers True if walkers should be
     63    * loaded, or false if this is a derived iterator and
     64    * it doesn't wish to load child walkers.
     65    *
     66    * @throws javax.xml.transform.TransformerException
     67    */
     68   WalkingIteratorSorted(
     69           Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
     70             throws javax.xml.transform.TransformerException
     71   {
     72     super(compiler, opPos, analysis, shouldLoadWalkers);
     73   }
     74 
     75   /**
     76    * Returns true if all the nodes in the iteration well be returned in document
     77    * order.
     78    *
     79    * @return true as a default.
     80    */
     81   public boolean isDocOrdered()
     82   {
     83     return m_inNaturalOrderStatic;
     84   }
     85 
     86 
     87   /**
     88    * Tell if the nodeset can be walked in doc order, via static analysis.
     89    *
     90    *
     91    * @return true if the nodeset can be walked in doc order, without sorting.
     92    */
     93   boolean canBeWalkedInNaturalDocOrderStatic()
     94   {
     95 
     96     if (null != m_firstWalker)
     97     {
     98       AxesWalker walker = m_firstWalker;
     99       int prevAxis = -1;
    100       boolean prevIsSimpleDownAxis = true;
    101 
    102       for(int i = 0; null != walker; i++)
    103       {
    104         int axis = walker.getAxis();
    105 
    106         if(walker.isDocOrdered())
    107         {
    108           boolean isSimpleDownAxis = ((axis == Axis.CHILD)
    109                                    || (axis == Axis.SELF)
    110                                    || (axis == Axis.ROOT));
    111           // Catching the filtered list here is only OK because
    112           // FilterExprWalker#isDocOrdered() did the right thing.
    113           if(isSimpleDownAxis || (axis == -1))
    114             walker = walker.getNextWalker();
    115           else
    116           {
    117             boolean isLastWalker = (null == walker.getNextWalker());
    118             if(isLastWalker)
    119             {
    120               if(walker.isDocOrdered() && (axis == Axis.DESCENDANT ||
    121                  axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
    122                  || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
    123                 return true;
    124             }
    125             return false;
    126           }
    127         }
    128         else
    129           return false;
    130       }
    131       return true;
    132     }
    133     return false;
    134   }
    135 
    136 
    137 //  /**
    138 //   * NEEDSDOC Method canBeWalkedInNaturalDocOrder
    139 //   *
    140 //   *
    141 //   * NEEDSDOC (canBeWalkedInNaturalDocOrder) @return
    142 //   */
    143 //  boolean canBeWalkedInNaturalDocOrder()
    144 //  {
    145 //
    146 //    if (null != m_firstWalker)
    147 //    {
    148 //      AxesWalker walker = m_firstWalker;
    149 //      int prevAxis = -1;
    150 //      boolean prevIsSimpleDownAxis = true;
    151 //
    152 //      for(int i = 0; null != walker; i++)
    153 //      {
    154 //        int axis = walker.getAxis();
    155 //
    156 //        if(walker.isDocOrdered())
    157 //        {
    158 //          boolean isSimpleDownAxis = ((axis == Axis.CHILD)
    159 //                                   || (axis == Axis.SELF)
    160 //                                   || (axis == Axis.ROOT));
    161 //          // Catching the filtered list here is only OK because
    162 //          // FilterExprWalker#isDocOrdered() did the right thing.
    163 //          if(isSimpleDownAxis || (axis == -1))
    164 //            walker = walker.getNextWalker();
    165 //          else
    166 //          {
    167 //            boolean isLastWalker = (null == walker.getNextWalker());
    168 //            if(isLastWalker)
    169 //            {
    170 //              if(walker.isDocOrdered() && (axis == Axis.DESCENDANT ||
    171 //                 axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
    172 //                 || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
    173 //                return true;
    174 //            }
    175 //            return false;
    176 //          }
    177 //        }
    178 //        else
    179 //          return false;
    180 //      }
    181 //      return true;
    182 //    }
    183 //    return false;
    184 //  }
    185 
    186   /**
    187    * This function is used to perform some extra analysis of the iterator.
    188    *
    189    * @param vars List of QNames that correspond to variables.  This list
    190    * should be searched backwards for the first qualified name that
    191    * corresponds to the variable reference qname.  The position of the
    192    * QName in the vector from the start of the vector will be its position
    193    * in the stack frame (but variables above the globalsTop value will need
    194    * to be offset to the current stack frame).
    195    */
    196   public void fixupVariables(java.util.Vector vars, int globalsSize)
    197   {
    198     super.fixupVariables(vars, globalsSize);
    199 
    200     int analysis = getAnalysisBits();
    201     if(WalkerFactory.isNaturalDocOrder(analysis))
    202     {
    203     	m_inNaturalOrderStatic = true;
    204     }
    205     else
    206     {
    207     	m_inNaturalOrderStatic = false;
    208     	// System.out.println("Setting natural doc order to false: "+
    209     	//    WalkerFactory.getAnalysisString(analysis));
    210     }
    211 
    212   }
    213 
    214 }
    215