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 }