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 }