View Javadoc

1   /*
2    * Copyright 2002-2006 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  
17  package org.apache.commons.jexl.parser;
18  
19  import org.apache.commons.jexl.JexlContext;
20  import org.apache.commons.jexl.util.Coercion;
21  
22  /***
23   *  Addition : either integer addition or string concatenation.
24   *
25   *  @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
26   *  @version $Id: ASTAddNode.java 398180 2006-04-29 15:40:35Z dion $
27   */
28  public class ASTAddNode extends SimpleNode {
29      /***
30       * Create the node given an id.
31       * 
32       * @param id node id.
33       */
34      public ASTAddNode(int id) {
35          super(id);
36      }
37  
38      /***
39       * Create a node with the given parser and id.
40       * 
41       * @param p a parser.
42       * @param id node id.
43       */
44      public ASTAddNode(Parser p, int id) {
45          super(p, id);
46      }
47  
48  
49      /*** 
50       * {@inheritDoc}
51       */
52      public Object jjtAccept(ParserVisitor visitor, Object data) {
53          return visitor.visit(this, data);
54      }
55  
56      /***
57       * {@inheritDoc} 
58       */
59      public Object value(JexlContext context) throws Exception {
60          Object left = ((SimpleNode) jjtGetChild(0)).value(context);
61          Object right = ((SimpleNode) jjtGetChild(1)).value(context);
62  
63          /*
64           *  the spec says 'and'
65           */
66          if (left == null && right == null) {
67              return new Long(0);
68          }
69  
70          /*
71           *  if anything is float, double or string with ( "." | "E" | "e")
72           *  coerce all to doubles and do it
73           */
74          if (left instanceof Float || left instanceof Double
75              || right instanceof Float || right instanceof Double
76              || (left instanceof String
77                    && (((String) left).indexOf(".") != -1 
78                            || ((String) left).indexOf("e") != -1
79                            || ((String) left).indexOf("E") != -1)
80                 )
81              || (right instanceof String
82                    && (((String) right).indexOf(".") != -1
83                            || ((String) right).indexOf("e") != -1
84                            || ((String) right).indexOf("E") != -1)
85                 )
86              ) {
87  
88              /*
89               * in the event that either is null and not both, then just make the
90               * null a 0
91               */
92  
93              try {
94                  Double l = Coercion.coerceDouble(left);
95                  Double r = Coercion.coerceDouble(right);
96                  return new Double(l.doubleValue() + r.doubleValue());
97              } catch (java.lang.NumberFormatException nfe) {
98                  /*
99                   * Well, use strings!
100                  */
101                 return left.toString().concat(right.toString());
102             }
103         }
104 
105         /*
106          * attempt to use Longs
107          */
108         try {
109             Long l = Coercion.coerceLong(left);
110             Long r = Coercion.coerceLong(right);
111             return new Long(l.longValue() + r.longValue());
112         } catch (java.lang.NumberFormatException nfe) {
113             /*
114              * Well, use strings!
115              */
116             return left.toString().concat(right.toString());
117         }
118     }
119 }