View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl2.parser;
18  
19  import java.math.BigDecimal;
20  import java.math.BigInteger;
21  
22  public class ASTNumberLiteral extends JexlNode implements JexlNode.Literal<Number> {
23      /** The type literal value. */
24      Number literal = null;
25      /** The expected class. */
26      Class<?> clazz = null;
27  
28      public ASTNumberLiteral(int id) {
29          super(id);
30      }
31  
32      public ASTNumberLiteral(Parser p, int id) {
33          super(p, id);
34      }
35  
36      /**
37       * Gets the literal value.
38       * @return the number literal
39       */
40      public Number getLiteral() {
41          return literal;
42      }
43      
44      /** {@inheritDoc} */
45      @Override
46      protected boolean isConstant(boolean literal) {
47          return true;
48      }
49  
50      /** {@inheritDoc} */
51      @Override
52      public Object jjtAccept(ParserVisitor visitor, Object data) {
53          return visitor.visit(this, data);
54      }
55  
56      public Class<?> getLiteralClass() {
57          return clazz;
58      }
59  
60      public boolean isInteger() {
61          return Integer.class.equals(clazz);
62      }
63  
64      /**
65       * Sets this node as a natural literal.
66       * Originally from OGNL.
67       * @param s the natural as string
68       */
69      public void setNatural(String s) {
70          Number result;
71          Class<?> rclass;
72          // determine the base
73          final int base;
74          if (s.charAt(0) == '0') {
75              if ((s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 'X'))) {
76                  base = 16;
77                  s = s.substring(2); // Trim the 0x off the front
78              } else {
79                  base = 8;
80              }
81          } else {
82              base = 10;
83          }
84          final int last = s.length() - 1;
85          switch (s.charAt(last)) {
86              case 'l':
87              case 'L': {
88                  rclass = Long.class;
89                  result = Long.valueOf(s.substring(0, last), base);
90                  break;
91              }
92              case 'h':
93              case 'H': {
94                  rclass = BigInteger.class;
95                  result = new BigInteger(s.substring(0, last), base);
96                  break;
97              }
98              default: {
99                  rclass = Integer.class;
100                 try {
101                     result = Integer.valueOf(s, base);
102                 } catch (NumberFormatException take2) {
103                     try {
104                         result = Long.valueOf(s, base);
105                     } catch (NumberFormatException take3) {
106                         result = new BigInteger(s, base);
107                     }
108                 }
109             }
110         }
111         literal = result;
112         clazz = rclass;
113     }
114 
115     /**
116      * Sets this node as a real literal.
117      * Originally from OGNL.
118      * @param s the real as string
119      */
120     public void setReal(String s) {
121         Number result;
122         Class<?> rclass;
123         final int last = s.length() - 1;
124         switch (s.charAt(last)) {
125             case 'b':
126             case 'B': {
127                 result = new BigDecimal(s.substring(0, last));
128                 rclass = BigDecimal.class;
129                 break;
130             }
131             case 'd':
132             case 'D': {
133                 rclass = Double.class;
134                 result = Double.valueOf(s);
135                 break;
136             }
137             case 'f':
138             case 'F':
139             default: {
140                 rclass = Float.class;
141                 try {
142                     result = Float.valueOf(s);
143                 } catch (NumberFormatException take2) {
144                     try {
145                         result = Double.valueOf(s);
146                     } catch (NumberFormatException take3) {
147                         result = new BigDecimal(s);
148                     }
149                 }
150                 break;
151             }
152         }
153         literal = result;
154         clazz = rclass;
155     }
156 }