1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements.  See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package com.sun.org.apache.xpath.internal.axes;
22
23import com.sun.org.apache.xpath.internal.Expression;
24import com.sun.org.apache.xpath.internal.ExpressionOwner;
25import com.sun.org.apache.xpath.internal.XPathVisitor;
26import com.sun.org.apache.xpath.internal.functions.FuncLast;
27import com.sun.org.apache.xpath.internal.functions.FuncPosition;
28import com.sun.org.apache.xpath.internal.functions.Function;
29import com.sun.org.apache.xpath.internal.objects.XNumber;
30import com.sun.org.apache.xpath.internal.operations.Div;
31import com.sun.org.apache.xpath.internal.operations.Minus;
32import com.sun.org.apache.xpath.internal.operations.Mod;
33import com.sun.org.apache.xpath.internal.operations.Mult;
34import com.sun.org.apache.xpath.internal.operations.Plus;
35import com.sun.org.apache.xpath.internal.operations.Quo;
36import com.sun.org.apache.xpath.internal.operations.Variable;
37
38@SuppressWarnings("deprecation")
39public class HasPositionalPredChecker extends XPathVisitor
40{
41        private boolean m_hasPositionalPred = false;
42        private int m_predDepth = 0;
43
44        /**
45         * Process the LocPathIterator to see if it contains variables
46         * or functions that may make it context dependent.
47         * @param path LocPathIterator that is assumed to be absolute, but needs checking.
48         * @return true if the path is confirmed to be absolute, false if it
49         * may contain context dependencies.
50         */
51        public static boolean check(LocPathIterator path)
52        {
53                HasPositionalPredChecker hppc = new HasPositionalPredChecker();
54                path.callVisitors(null, hppc);
55                return hppc.m_hasPositionalPred;
56        }
57
58        /**
59         * Visit a function.
60         * @param owner The owner of the expression, to which the expression can
61         *              be reset if rewriting takes place.
62         * @param func The function reference object.
63         * @return true if the sub expressions should be traversed.
64         */
65        public boolean visitFunction(ExpressionOwner owner, Function func)
66        {
67                if((func instanceof FuncPosition) ||
68                   (func instanceof FuncLast))
69                        m_hasPositionalPred = true;
70                return true;
71        }
72
73//      /**
74//       * Visit a variable reference.
75//       * @param owner The owner of the expression, to which the expression can
76//       *              be reset if rewriting takes place.
77//       * @param var The variable reference object.
78//       * @return true if the sub expressions should be traversed.
79//       */
80//      public boolean visitVariableRef(ExpressionOwner owner, Variable var)
81//      {
82//              m_hasPositionalPred = true;
83//              return true;
84//      }
85
86  /**
87   * Visit a predicate within a location path.  Note that there isn't a
88   * proper unique component for predicates, and that the expression will
89   * be called also for whatever type Expression is.
90   *
91   * @param owner The owner of the expression, to which the expression can
92   *              be reset if rewriting takes place.
93   * @param pred The predicate object.
94   * @return true if the sub expressions should be traversed.
95   */
96  public boolean visitPredicate(ExpressionOwner owner, Expression pred)
97  {
98    m_predDepth++;
99
100    if(m_predDepth == 1)
101    {
102      if((pred instanceof Variable) ||
103         (pred instanceof XNumber) ||
104         (pred instanceof Div) ||
105         (pred instanceof Plus) ||
106         (pred instanceof Minus) ||
107         (pred instanceof Mod) ||
108         (pred instanceof Quo) ||
109         (pred instanceof Mult) ||
110         (pred instanceof com.sun.org.apache.xpath.internal.operations.Number) ||
111         (pred instanceof Function))
112          m_hasPositionalPred = true;
113      else
114        pred.callVisitors(owner, this);
115    }
116
117    m_predDepth--;
118
119    // Don't go have the caller go any further down the subtree.
120    return false;
121  }
122
123
124}
125