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: FilterExprIterator.java 468655 2006-10-28 07:12:06Z minchau $
     20  */
     21 package org.apache.xpath.axes;
     22 
     23 import org.apache.xml.dtm.DTM;
     24 import org.apache.xpath.Expression;
     25 import org.apache.xpath.ExpressionOwner;
     26 import org.apache.xpath.XPathVisitor;
     27 import org.apache.xpath.objects.XNodeSet;
     28 
     29 public class FilterExprIterator extends BasicTestIterator
     30 {
     31     static final long serialVersionUID = 2552176105165737614L;
     32   /** The contained expression. Should be non-null.
     33    *  @serial   */
     34   private Expression m_expr;
     35 
     36   /** The result of executing m_expr.  Needs to be deep cloned on clone op.  */
     37   transient private XNodeSet m_exprObj;
     38 
     39   private boolean m_mustHardReset = false;
     40   private boolean m_canDetachNodeset = true;
     41 
     42   /**
     43    * Create a FilterExprIterator object.
     44    *
     45    */
     46   public FilterExprIterator()
     47   {
     48     super(null);
     49   }
     50 
     51   /**
     52    * Create a FilterExprIterator object.
     53    *
     54    */
     55   public FilterExprIterator(Expression expr)
     56   {
     57     super(null);
     58     m_expr = expr;
     59   }
     60 
     61   /**
     62    * Initialize the context values for this expression
     63    * after it is cloned.
     64    *
     65    * @param context The XPath runtime context for this
     66    * transformation.
     67    */
     68   public void setRoot(int context, Object environment)
     69   {
     70   	super.setRoot(context, environment);
     71 
     72   	m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context,
     73   	                  m_execContext, getPrefixResolver(),
     74   	                  getIsTopLevel(), m_stackFrame, m_expr);
     75    }
     76 
     77 
     78   /**
     79    * Get the next node via getNextXXX.  Bottlenecked for derived class override.
     80    * @return The next node on the axis, or DTM.NULL.
     81    */
     82   protected int getNextNode()
     83   {
     84     if (null != m_exprObj)
     85     {
     86       m_lastFetched = m_exprObj.nextNode();
     87     }
     88     else
     89       m_lastFetched = DTM.NULL;
     90 
     91     return m_lastFetched;
     92   }
     93 
     94   /**
     95    * Detaches the walker from the set which it iterated over, releasing
     96    * any computational resources and placing the iterator in the INVALID
     97    * state.
     98    */
     99   public void detach()
    100   {
    101   	super.detach();
    102   	m_exprObj.detach();
    103   	m_exprObj = null;
    104   }
    105 
    106   /**
    107    * This function is used to fixup variables from QNames to stack frame
    108    * indexes at stylesheet build time.
    109    * @param vars List of QNames that correspond to variables.  This list
    110    * should be searched backwards for the first qualified name that
    111    * corresponds to the variable reference qname.  The position of the
    112    * QName in the vector from the start of the vector will be its position
    113    * in the stack frame (but variables above the globalsTop value will need
    114    * to be offset to the current stack frame).
    115    */
    116   public void fixupVariables(java.util.Vector vars, int globalsSize)
    117   {
    118     super.fixupVariables(vars, globalsSize);
    119     m_expr.fixupVariables(vars, globalsSize);
    120   }
    121 
    122   /**
    123    * Get the inner contained expression of this filter.
    124    */
    125   public Expression getInnerExpression()
    126   {
    127     return m_expr;
    128   }
    129 
    130   /**
    131    * Set the inner contained expression of this filter.
    132    */
    133   public void setInnerExpression(Expression expr)
    134   {
    135     expr.exprSetParent(this);
    136     m_expr = expr;
    137   }
    138 
    139   /**
    140    * Get the analysis bits for this walker, as defined in the WalkerFactory.
    141    * @return One of WalkerFactory#BIT_DESCENDANT, etc.
    142    */
    143   public int getAnalysisBits()
    144   {
    145     if (null != m_expr && m_expr instanceof PathComponent)
    146     {
    147       return ((PathComponent) m_expr).getAnalysisBits();
    148     }
    149     return WalkerFactory.BIT_FILTER;
    150   }
    151 
    152   /**
    153    * Returns true if all the nodes in the iteration well be returned in document
    154    * order.
    155    * Warning: This can only be called after setRoot has been called!
    156    *
    157    * @return true as a default.
    158    */
    159   public boolean isDocOrdered()
    160   {
    161     return m_exprObj.isDocOrdered();
    162   }
    163 
    164   class filterExprOwner implements ExpressionOwner
    165   {
    166     /**
    167     * @see ExpressionOwner#getExpression()
    168     */
    169     public Expression getExpression()
    170     {
    171       return m_expr;
    172     }
    173 
    174     /**
    175      * @see ExpressionOwner#setExpression(Expression)
    176      */
    177     public void setExpression(Expression exp)
    178     {
    179       exp.exprSetParent(FilterExprIterator.this);
    180       m_expr = exp;
    181     }
    182 
    183   }
    184 
    185   /**
    186    * This will traverse the heararchy, calling the visitor for
    187    * each member.  If the called visitor method returns
    188    * false, the subtree should not be called.
    189    *
    190    * @param visitor The visitor whose appropriate method will be called.
    191    */
    192   public void callPredicateVisitors(XPathVisitor visitor)
    193   {
    194     m_expr.callVisitors(new filterExprOwner(), visitor);
    195 
    196     super.callPredicateVisitors(visitor);
    197   }
    198 
    199   /**
    200    * @see Expression#deepEquals(Expression)
    201    */
    202   public boolean deepEquals(Expression expr)
    203   {
    204     if (!super.deepEquals(expr))
    205       return false;
    206 
    207     FilterExprIterator fet = (FilterExprIterator) expr;
    208     if (!m_expr.deepEquals(fet.m_expr))
    209       return false;
    210 
    211     return true;
    212   }
    213 
    214 }
    215