001/*
002 * Copyright 2002-2014 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;
025
026/**
027 * Common superclass for nodes representing literals (boolean, string, number, etc).
028 *
029 * @author Andy Clement
030 * @author Juergen Hoeller
031 */
032public abstract class Literal extends SpelNodeImpl {
033
034        private final String originalValue;
035
036
037        public Literal(String originalValue, int pos) {
038                super(pos);
039                this.originalValue = originalValue;
040        }
041
042
043        public final String getOriginalValue() {
044                return this.originalValue;
045        }
046
047        @Override
048        public final TypedValue getValueInternal(ExpressionState state) throws SpelEvaluationException {
049                return getLiteralValue();
050        }
051
052        @Override
053        public String toString() {
054                return getLiteralValue().getValue().toString();
055        }
056
057        @Override
058        public String toStringAST() {
059                return toString();
060        }
061
062
063        public abstract TypedValue getLiteralValue();
064
065
066        /**
067         * Process the string form of a number, using the specified base if supplied
068         * and return an appropriate literal to hold it. Any suffix to indicate a
069         * long will be taken into account (either 'l' or 'L' is supported).
070         * @param numberToken the token holding the number as its payload (eg. 1234 or 0xCAFE)
071         * @param radix the base of number
072         * @return a subtype of Literal that can represent it
073         */
074        public static Literal getIntLiteral(String numberToken, int pos, int radix) {
075                try {
076                        int value = Integer.parseInt(numberToken, radix);
077                        return new IntLiteral(numberToken, pos, value);
078                }
079                catch (NumberFormatException ex) {
080                        throw new InternalParseException(new SpelParseException(pos>>16, ex, SpelMessage.NOT_AN_INTEGER, numberToken));
081                }
082        }
083
084        public static Literal getLongLiteral(String numberToken, int pos, int radix) {
085                try {
086                        long value = Long.parseLong(numberToken, radix);
087                        return new LongLiteral(numberToken, pos, value);
088                }
089                catch (NumberFormatException ex) {
090                        throw new InternalParseException(new SpelParseException(pos>>16, ex, SpelMessage.NOT_A_LONG, numberToken));
091                }
092        }
093
094        public static Literal getRealLiteral(String numberToken, int pos, boolean isFloat) {
095                try {
096                        if (isFloat) {
097                                float value = Float.parseFloat(numberToken);
098                                return new FloatLiteral(numberToken, pos, value);
099                        }
100                        else {
101                                double value = Double.parseDouble(numberToken);
102                                return new RealLiteral(numberToken, pos, value);
103                        }
104                }
105                catch (NumberFormatException ex) {
106                        throw new InternalParseException(new SpelParseException(pos>>16, ex, SpelMessage.NOT_A_REAL, numberToken));
107                }
108        }
109
110}