1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jxpath.ri.compiler;
17
18 import org.apache.commons.jxpath.ri.EvalContext;
19
20 /***
21 * The common subclass for tree elements representing core operations like "+",
22 * "- ", "*" etc.
23 *
24 * @author Dmitri Plotnikov
25 * @version $Revision: 1.14 $ $Date: 2004/02/29 14:17:39 $
26 */
27 public abstract class CoreOperation extends Operation {
28
29 public CoreOperation(Expression args[]) {
30 super(args);
31 }
32
33 public Object compute(EvalContext context) {
34 return computeValue(context);
35 }
36
37 public abstract Object computeValue(EvalContext context);
38
39 /***
40 * Returns the XPath symbol for this operation, e.g. "+", "div", etc.
41 */
42 public abstract String getSymbol();
43
44 /***
45 * Returns true if the operation is not sensitive to the order of arguments,
46 * e.g. "=", "and" etc, and false if it is, e.g. "<=", "div".
47 */
48 protected abstract boolean isSymmetric();
49
50 /***
51 * Computes the precedence of the operation.
52 */
53 protected abstract int getPrecedence();
54
55 public String toString() {
56 if (args.length == 1) {
57 return getSymbol() + parenthesize(args[0], false);
58 }
59 else {
60 StringBuffer buffer = new StringBuffer();
61 for (int i = 0; i < args.length; i++) {
62 if (i > 0) {
63 buffer.append(' ');
64 buffer.append(getSymbol());
65 buffer.append(' ');
66 }
67 buffer.append(parenthesize(args[i], i == 0));
68 }
69 return buffer.toString();
70 }
71 }
72
73 private String parenthesize(Expression expression, boolean left) {
74 if (!(expression instanceof CoreOperation)) {
75 return expression.toString();
76 }
77 CoreOperation op = (CoreOperation) expression;
78 int myPrecedence = getPrecedence();
79 int thePrecedence = op.getPrecedence();
80
81 boolean needParens = true;
82 if (myPrecedence < thePrecedence) {
83 needParens = false;
84 }
85 else if (myPrecedence == thePrecedence) {
86 if (isSymmetric()) {
87 needParens = false;
88 }
89 else {
90 needParens = !left;
91 }
92 }
93
94 if (needParens) {
95 return "(" + expression.toString() + ")";
96 }
97 else {
98 return expression.toString();
99 }
100 }
101 }