    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    }