001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.jexl2.parser;
018
019 import java.math.BigDecimal;
020 import java.math.BigInteger;
021
022 public class ASTNumberLiteral extends JexlNode implements JexlNode.Literal<Number> {
023 /** The type literal value. */
024 Number literal = null;
025 /** The expected class. */
026 Class<?> clazz = null;
027
028 public ASTNumberLiteral(int id) {
029 super(id);
030 }
031
032 public ASTNumberLiteral(Parser p, int id) {
033 super(p, id);
034 }
035
036 /**
037 * Gets the literal value.
038 * @return the number literal
039 */
040 public Number getLiteral() {
041 return literal;
042 }
043
044 /** {@inheritDoc} */
045 @Override
046 protected boolean isConstant(boolean literal) {
047 return true;
048 }
049
050 /** {@inheritDoc} */
051 @Override
052 public Object jjtAccept(ParserVisitor visitor, Object data) {
053 return visitor.visit(this, data);
054 }
055
056 public Class<?> getLiteralClass() {
057 return clazz;
058 }
059
060 public boolean isInteger() {
061 return Integer.class.equals(clazz);
062 }
063
064 /**
065 * Sets this node as a natural literal.
066 * Originally from OGNL.
067 * @param s the natural as string
068 */
069 public void setNatural(String s) {
070 Number result;
071 Class<?> rclass;
072 // determine the base
073 final int base;
074 if (s.charAt(0) == '0') {
075 if ((s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 'X'))) {
076 base = 16;
077 s = s.substring(2); // Trim the 0x off the front
078 } else {
079 base = 8;
080 }
081 } else {
082 base = 10;
083 }
084 final int last = s.length() - 1;
085 switch (s.charAt(last)) {
086 case 'l':
087 case 'L': {
088 rclass = Long.class;
089 result = Long.valueOf(s.substring(0, last), base);
090 break;
091 }
092 case 'h':
093 case 'H': {
094 rclass = BigInteger.class;
095 result = new BigInteger(s.substring(0, last), base);
096 break;
097 }
098 default: {
099 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 }