View Javadoc

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  
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 }