1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.jxpath.ri.compiler;
  17. import org.apache.commons.jxpath.ri.EvalContext;
  18. /**
  19. * The common subclass for tree elements representing core operations like "+",
  20. * "- ", "*" etc.
  21. *
  22. * @author Dmitri Plotnikov
  23. * @version $Revision: 1.14 $ $Date: 2004/02/29 14:17:39 $
  24. */
  25. public abstract class CoreOperation extends Operation {
  26. public CoreOperation(Expression args[]) {
  27. super(args);
  28. }
  29. public Object compute(EvalContext context) {
  30. return computeValue(context);
  31. }
  32. public abstract Object computeValue(EvalContext context);
  33. /**
  34. * Returns the XPath symbol for this operation, e.g. "+", "div", etc.
  35. */
  36. public abstract String getSymbol();
  37. /**
  38. * Returns true if the operation is not sensitive to the order of arguments,
  39. * e.g. "=", "and" etc, and false if it is, e.g. "<=", "div".
  40. */
  41. protected abstract boolean isSymmetric();
  42. /**
  43. * Computes the precedence of the operation.
  44. */
  45. protected abstract int getPrecedence();
  46. public String toString() {
  47. if (args.length == 1) {
  48. return getSymbol() + parenthesize(args[0], false);
  49. }
  50. else {
  51. StringBuffer buffer = new StringBuffer();
  52. for (int i = 0; i < args.length; i++) {
  53. if (i > 0) {
  54. buffer.append(' ');
  55. buffer.append(getSymbol());
  56. buffer.append(' ');
  57. }
  58. buffer.append(parenthesize(args[i], i == 0));
  59. }
  60. return buffer.toString();
  61. }
  62. }
  63. private String parenthesize(Expression expression, boolean left) {
  64. if (!(expression instanceof CoreOperation)) {
  65. return expression.toString();
  66. }
  67. CoreOperation op = (CoreOperation) expression;
  68. int myPrecedence = getPrecedence();
  69. int thePrecedence = op.getPrecedence();
  70. boolean needParens = true;
  71. if (myPrecedence < thePrecedence) {
  72. needParens = false;
  73. }
  74. else if (myPrecedence == thePrecedence) {
  75. if (isSymmetric()) {
  76. needParens = false;
  77. }
  78. else {
  79. needParens = !left;
  80. }
  81. }
  82. if (needParens) {
  83. return "(" + expression.toString() + ")";
  84. }
  85. else {
  86. return expression.toString();
  87. }
  88. }
  89. }