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: HasPositionalPredChecker.java 468655 2006-10-28 07:12:06Z minchau $
20  */
21 package org.apache.xpath.axes;
22 
23 import org.apache.xpath.Expression;
24 import org.apache.xpath.ExpressionOwner;
25 import org.apache.xpath.XPathVisitor;
26 import org.apache.xpath.functions.FuncLast;
27 import org.apache.xpath.functions.FuncPosition;
28 import org.apache.xpath.functions.Function;
29 import org.apache.xpath.objects.XNumber;
30 import org.apache.xpath.operations.Div;
31 import org.apache.xpath.operations.Minus;
32 import org.apache.xpath.operations.Mod;
33 import org.apache.xpath.operations.Mult;
34 import org.apache.xpath.operations.Plus;
35 import org.apache.xpath.operations.Quo;
36 import org.apache.xpath.operations.Variable;
37 
38 public class HasPositionalPredChecker extends XPathVisitor
39 {
40 	private boolean m_hasPositionalPred = false;
41 	private int m_predDepth = 0;
42 
43 	/**
44 	 * Process the LocPathIterator to see if it contains variables
45 	 * or functions that may make it context dependent.
46 	 * @param path LocPathIterator that is assumed to be absolute, but needs checking.
47 	 * @return true if the path is confirmed to be absolute, false if it
48 	 * may contain context dependencies.
49 	 */
check(LocPathIterator path)50 	public static boolean check(LocPathIterator path)
51 	{
52 		HasPositionalPredChecker hppc = new HasPositionalPredChecker();
53 		path.callVisitors(null, hppc);
54 		return hppc.m_hasPositionalPred;
55 	}
56 
57 	/**
58 	 * Visit a function.
59 	 * @param owner The owner of the expression, to which the expression can
60 	 *              be reset if rewriting takes place.
61 	 * @param func The function reference object.
62 	 * @return true if the sub expressions should be traversed.
63 	 */
visitFunction(ExpressionOwner owner, Function func)64 	public boolean visitFunction(ExpressionOwner owner, Function func)
65 	{
66 		if((func instanceof FuncPosition) ||
67 		   (func instanceof FuncLast))
68 			m_hasPositionalPred = true;
69 		return true;
70 	}
71 
72 //	/**
73 //	 * Visit a variable reference.
74 //	 * @param owner The owner of the expression, to which the expression can
75 //	 *              be reset if rewriting takes place.
76 //	 * @param var The variable reference object.
77 //	 * @return true if the sub expressions should be traversed.
78 //	 */
79 //	public boolean visitVariableRef(ExpressionOwner owner, Variable var)
80 //	{
81 //		m_hasPositionalPred = true;
82 //		return true;
83 //	}
84 
85   /**
86    * Visit a predicate within a location path.  Note that there isn't a
87    * proper unique component for predicates, and that the expression will
88    * be called also for whatever type Expression is.
89    *
90    * @param owner The owner of the expression, to which the expression can
91    *              be reset if rewriting takes place.
92    * @param pred The predicate object.
93    * @return true if the sub expressions should be traversed.
94    */
visitPredicate(ExpressionOwner owner, Expression pred)95   public boolean visitPredicate(ExpressionOwner owner, Expression pred)
96   {
97     m_predDepth++;
98 
99     if(m_predDepth == 1)
100     {
101       if((pred instanceof Variable) ||
102          (pred instanceof XNumber) ||
103          (pred instanceof Div) ||
104          (pred instanceof Plus) ||
105          (pred instanceof Minus) ||
106          (pred instanceof Mod) ||
107          (pred instanceof Quo) ||
108          (pred instanceof Mult) ||
109          (pred instanceof org.apache.xpath.operations.Number) ||
110          (pred instanceof Function))
111           m_hasPositionalPred = true;
112       else
113       	pred.callVisitors(owner, this);
114     }
115 
116     m_predDepth--;
117 
118     // Don't go have the caller go any further down the subtree.
119     return false;
120   }
121 
122 
123 }
124 
125