1. package org.apache.xpath.axes;
  2. import org.apache.xpath.Expression;
  3. import org.apache.xpath.ExpressionOwner;
  4. import org.apache.xpath.XPathVisitor;
  5. import org.apache.xpath.functions.FuncLast;
  6. import org.apache.xpath.functions.FuncPosition;
  7. import org.apache.xpath.functions.Function;
  8. import org.apache.xpath.objects.XNumber;
  9. import org.apache.xpath.operations.Div;
  10. import org.apache.xpath.operations.Minus;
  11. import org.apache.xpath.operations.Mod;
  12. import org.apache.xpath.operations.Mult;
  13. import org.apache.xpath.operations.Plus;
  14. import org.apache.xpath.operations.Quo;
  15. import org.apache.xpath.operations.Variable;
  16. public class HasPositionalPredChecker extends XPathVisitor
  17. {
  18. private boolean m_hasPositionalPred = false;
  19. private int m_predDepth = 0;
  20. /**
  21. * Process the LocPathIterator to see if it contains variables
  22. * or functions that may make it context dependent.
  23. * @param path LocPathIterator that is assumed to be absolute, but needs checking.
  24. * @return true if the path is confirmed to be absolute, false if it
  25. * may contain context dependencies.
  26. */
  27. public static boolean check(LocPathIterator path)
  28. {
  29. HasPositionalPredChecker hppc = new HasPositionalPredChecker();
  30. path.callVisitors(null, hppc);
  31. return hppc.m_hasPositionalPred;
  32. }
  33. /**
  34. * Visit a function.
  35. * @param owner The owner of the expression, to which the expression can
  36. * be reset if rewriting takes place.
  37. * @param func The function reference object.
  38. * @return true if the sub expressions should be traversed.
  39. */
  40. public boolean visitFunction(ExpressionOwner owner, Function func)
  41. {
  42. if((func instanceof FuncPosition) ||
  43. (func instanceof FuncLast))
  44. m_hasPositionalPred = true;
  45. return true;
  46. }
  47. // /**
  48. // * Visit a variable reference.
  49. // * @param owner The owner of the expression, to which the expression can
  50. // * be reset if rewriting takes place.
  51. // * @param var The variable reference object.
  52. // * @return true if the sub expressions should be traversed.
  53. // */
  54. // public boolean visitVariableRef(ExpressionOwner owner, Variable var)
  55. // {
  56. // m_hasPositionalPred = true;
  57. // return true;
  58. // }
  59. /**
  60. * Visit a predicate within a location path. Note that there isn't a
  61. * proper unique component for predicates, and that the expression will
  62. * be called also for whatever type Expression is.
  63. *
  64. * @param owner The owner of the expression, to which the expression can
  65. * be reset if rewriting takes place.
  66. * @param pred The predicate object.
  67. * @return true if the sub expressions should be traversed.
  68. */
  69. public boolean visitPredicate(ExpressionOwner owner, Expression pred)
  70. {
  71. m_predDepth++;
  72. if(m_predDepth == 1)
  73. {
  74. if((pred instanceof Variable) ||
  75. (pred instanceof XNumber) ||
  76. (pred instanceof Div) ||
  77. (pred instanceof Plus) ||
  78. (pred instanceof Minus) ||
  79. (pred instanceof Mod) ||
  80. (pred instanceof Quo) ||
  81. (pred instanceof Mult) ||
  82. (pred instanceof org.apache.xpath.operations.Number) ||
  83. (pred instanceof Function))
  84. m_hasPositionalPred = true;
  85. else
  86. pred.callVisitors(owner, this);
  87. }
  88. m_predDepth--;
  89. // Don't go have the caller go any further down the subtree.
  90. return false;
  91. }
  92. }