001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.expression.spel.ast; 018 019import org.springframework.expression.TypedValue; 020import org.springframework.expression.spel.ExpressionState; 021import org.springframework.expression.spel.InternalParseException; 022import org.springframework.expression.spel.SpelEvaluationException; 023import org.springframework.expression.spel.SpelMessage; 024import org.springframework.expression.spel.SpelParseException; 025import org.springframework.lang.Nullable; 026 027/** 028 * Common superclass for nodes representing literals (boolean, string, number, etc). 029 * 030 * @author Andy Clement 031 * @author Juergen Hoeller 032 */ 033public abstract class Literal extends SpelNodeImpl { 034 035 @Nullable 036 private final String originalValue; 037 038 039 public Literal(@Nullable String originalValue, int startPos, int endPos) { 040 super(startPos, endPos); 041 this.originalValue = originalValue; 042 } 043 044 045 @Nullable 046 public final String getOriginalValue() { 047 return this.originalValue; 048 } 049 050 @Override 051 public final TypedValue getValueInternal(ExpressionState state) throws SpelEvaluationException { 052 return getLiteralValue(); 053 } 054 055 @Override 056 public String toString() { 057 return String.valueOf(getLiteralValue().getValue()); 058 } 059 060 @Override 061 public String toStringAST() { 062 return toString(); 063 } 064 065 066 public abstract TypedValue getLiteralValue(); 067 068 069 /** 070 * Process the string form of a number, using the specified base if supplied 071 * and return an appropriate literal to hold it. Any suffix to indicate a 072 * long will be taken into account (either 'l' or 'L' is supported). 073 * @param numberToken the token holding the number as its payload (eg. 1234 or 0xCAFE) 074 * @param radix the base of number 075 * @return a subtype of Literal that can represent it 076 */ 077 public static Literal getIntLiteral(String numberToken, int startPos, int endPos, int radix) { 078 try { 079 int value = Integer.parseInt(numberToken, radix); 080 return new IntLiteral(numberToken, startPos, endPos, value); 081 } 082 catch (NumberFormatException ex) { 083 throw new InternalParseException(new SpelParseException(startPos, ex, SpelMessage.NOT_AN_INTEGER, numberToken)); 084 } 085 } 086 087 public static Literal getLongLiteral(String numberToken, int startPos, int endPos, int radix) { 088 try { 089 long value = Long.parseLong(numberToken, radix); 090 return new LongLiteral(numberToken, startPos, endPos, value); 091 } 092 catch (NumberFormatException ex) { 093 throw new InternalParseException(new SpelParseException(startPos, ex, SpelMessage.NOT_A_LONG, numberToken)); 094 } 095 } 096 097 public static Literal getRealLiteral(String numberToken, int startPos, int endPos, boolean isFloat) { 098 try { 099 if (isFloat) { 100 float value = Float.parseFloat(numberToken); 101 return new FloatLiteral(numberToken, startPos, endPos, value); 102 } 103 else { 104 double value = Double.parseDouble(numberToken); 105 return new RealLiteral(numberToken, startPos, endPos, value); 106 } 107 } 108 catch (NumberFormatException ex) { 109 throw new InternalParseException(new SpelParseException(startPos, ex, SpelMessage.NOT_A_REAL, numberToken)); 110 } 111 } 112 113}