01: /*
02: * Copyright 1999-2004 The Apache Software Foundation
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
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:
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: } else {
59: StringBuffer buffer = new StringBuffer();
60: for (int i = 0; i < args.length; i++) {
61: if (i > 0) {
62: buffer.append(' ');
63: buffer.append(getSymbol());
64: buffer.append(' ');
65: }
66: buffer.append(parenthesize(args[i], i == 0));
67: }
68: return buffer.toString();
69: }
70: }
71:
72: private String parenthesize(Expression expression, boolean left) {
73: if (!(expression instanceof CoreOperation)) {
74: return expression.toString();
75: }
76: CoreOperation op = (CoreOperation) expression;
77: int myPrecedence = getPrecedence();
78: int thePrecedence = op.getPrecedence();
79:
80: boolean needParens = true;
81: if (myPrecedence < thePrecedence) {
82: needParens = false;
83: } else if (myPrecedence == thePrecedence) {
84: if (isSymmetric()) {
85: needParens = false;
86: } else {
87: needParens = !left;
88: }
89: }
90:
91: if (needParens) {
92: return "(" + expression.toString() + ")";
93: } else {
94: return expression.toString();
95: }
96: }
97: }
|