001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /*
017: * $Id: HasPositionalPredChecker.java,v 1.4 2004/02/17 04:32:08 minchau Exp $
018: */
019: package org.apache.xpath.axes;
020:
021: import org.apache.xpath.Expression;
022: import org.apache.xpath.ExpressionOwner;
023: import org.apache.xpath.XPathVisitor;
024: import org.apache.xpath.functions.FuncLast;
025: import org.apache.xpath.functions.FuncPosition;
026: import org.apache.xpath.functions.Function;
027: import org.apache.xpath.objects.XNumber;
028: import org.apache.xpath.operations.Div;
029: import org.apache.xpath.operations.Minus;
030: import org.apache.xpath.operations.Mod;
031: import org.apache.xpath.operations.Mult;
032: import org.apache.xpath.operations.Plus;
033: import org.apache.xpath.operations.Quo;
034: import org.apache.xpath.operations.Variable;
035:
036: public class HasPositionalPredChecker extends XPathVisitor {
037: private boolean m_hasPositionalPred = false;
038: private int m_predDepth = 0;
039:
040: /**
041: * Process the LocPathIterator to see if it contains variables
042: * or functions that may make it context dependent.
043: * @param path LocPathIterator that is assumed to be absolute, but needs checking.
044: * @return true if the path is confirmed to be absolute, false if it
045: * may contain context dependencies.
046: */
047: public static boolean check(LocPathIterator path) {
048: HasPositionalPredChecker hppc = new HasPositionalPredChecker();
049: path.callVisitors(null, hppc);
050: return hppc.m_hasPositionalPred;
051: }
052:
053: /**
054: * Visit a function.
055: * @param owner The owner of the expression, to which the expression can
056: * be reset if rewriting takes place.
057: * @param func The function reference object.
058: * @return true if the sub expressions should be traversed.
059: */
060: public boolean visitFunction(ExpressionOwner owner, Function func) {
061: if ((func instanceof FuncPosition)
062: || (func instanceof FuncLast))
063: m_hasPositionalPred = true;
064: return true;
065: }
066:
067: // /**
068: // * Visit a variable reference.
069: // * @param owner The owner of the expression, to which the expression can
070: // * be reset if rewriting takes place.
071: // * @param var The variable reference object.
072: // * @return true if the sub expressions should be traversed.
073: // */
074: // public boolean visitVariableRef(ExpressionOwner owner, Variable var)
075: // {
076: // m_hasPositionalPred = true;
077: // return true;
078: // }
079:
080: /**
081: * Visit a predicate within a location path. Note that there isn't a
082: * proper unique component for predicates, and that the expression will
083: * be called also for whatever type Expression is.
084: *
085: * @param owner The owner of the expression, to which the expression can
086: * be reset if rewriting takes place.
087: * @param pred The predicate object.
088: * @return true if the sub expressions should be traversed.
089: */
090: public boolean visitPredicate(ExpressionOwner owner, Expression pred) {
091: m_predDepth++;
092:
093: if (m_predDepth == 1) {
094: if ((pred instanceof Variable)
095: || (pred instanceof XNumber)
096: || (pred instanceof Div)
097: || (pred instanceof Plus)
098: || (pred instanceof Minus)
099: || (pred instanceof Mod)
100: || (pred instanceof Quo)
101: || (pred instanceof Mult)
102: || (pred instanceof org.apache.xpath.operations.Number)
103: || (pred instanceof Function))
104: m_hasPositionalPred = true;
105: else
106: pred.callVisitors(owner, this );
107: }
108:
109: m_predDepth--;
110:
111: // Don't go have the caller go any further down the subtree.
112: return false;
113: }
114:
115: }
|