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 java.math.BigDecimal; 020import java.math.BigInteger; 021 022import org.springframework.expression.EvaluationException; 023import org.springframework.expression.Operation; 024import org.springframework.expression.TypedValue; 025import org.springframework.expression.spel.ExpressionState; 026import org.springframework.util.NumberUtils; 027 028/** 029 * The power operator. 030 * 031 * @author Andy Clement 032 * @author Giovanni Dall'Oglio Risso 033 * @since 3.0 034 */ 035public class OperatorPower extends Operator { 036 037 public OperatorPower(int pos, SpelNodeImpl... operands) { 038 super("^", pos, operands); 039 } 040 041 042 @Override 043 public TypedValue getValueInternal(ExpressionState state) throws EvaluationException { 044 SpelNodeImpl leftOp = getLeftOperand(); 045 SpelNodeImpl rightOp = getRightOperand(); 046 047 Object leftOperand = leftOp.getValueInternal(state).getValue(); 048 Object rightOperand = rightOp.getValueInternal(state).getValue(); 049 050 if (leftOperand instanceof Number && rightOperand instanceof Number) { 051 Number leftNumber = (Number) leftOperand; 052 Number rightNumber = (Number) rightOperand; 053 054 if (leftNumber instanceof BigDecimal) { 055 BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class); 056 return new TypedValue(leftBigDecimal.pow(rightNumber.intValue())); 057 } 058 else if (leftNumber instanceof BigInteger) { 059 BigInteger leftBigInteger = NumberUtils.convertNumberToTargetClass(leftNumber, BigInteger.class); 060 return new TypedValue(leftBigInteger.pow(rightNumber.intValue())); 061 } 062 else if (leftNumber instanceof Double || rightNumber instanceof Double) { 063 return new TypedValue(Math.pow(leftNumber.doubleValue(), rightNumber.doubleValue())); 064 } 065 else if (leftNumber instanceof Float || rightNumber instanceof Float) { 066 return new TypedValue(Math.pow(leftNumber.floatValue(), rightNumber.floatValue())); 067 } 068 069 double d = Math.pow(leftNumber.doubleValue(), rightNumber.doubleValue()); 070 if (d > Integer.MAX_VALUE || leftNumber instanceof Long || rightNumber instanceof Long) { 071 return new TypedValue((long) d); 072 } 073 else { 074 return new TypedValue((int) d); 075 } 076 } 077 078 return state.operate(Operation.POWER, leftOperand, rightOperand); 079 } 080 081}