/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
//
/**
*
* @author Xiping Change Log: 3/9/07: Neeraj Joshi: Changed signature to take a
* list of expressions and boolean This will help in reflection 3/9/07:
* Neeraj Joshi: Updated the method for determining return type to use
* binary numeric promotion
*
*/
package org.apache.imperius.spl.parser.expressions.impl;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import org.apache.imperius.spl.core.TypeConstants;
import org.apache.imperius.spl.core.TypeInfo;
import org.apache.imperius.spl.parser.exceptions.IllegalExpressionTypeException;
import org.apache.imperius.spl.parser.exceptions.SPLException;
import org.apache.imperius.spl.parser.expressions.DoubleArgumentExpression;
import org.apache.imperius.spl.parser.expressions.NumericExpression;
import org.apache.imperius.spl.parser.util.TypeResolver;
import org.apache.imperius.util.Messages;
import org.apache.imperius.util.SPLLogger;
public class Addition extends DoubleArgumentExpression implements
NumericExpression
{
public static final String className = Addition.class.getName();
private static Logger logger = SPLLogger.getSPLLogger().getLogger();
private static final String sourceClass = "Addition";
public Addition(List exprList, boolean evaluateExpression)
throws SPLException
{
super(exprList);
logger.entering(sourceClass, Thread.currentThread().getName() + " "
+ "Addition");
if (evaluateExpression)
{
if (!validate())
{
logger.severe(Thread.currentThread().getName() + " "
+ "validation error: wrong data type passed into "
+ className + ".");
throw new SPLException(Messages.getString(
"SPL_VALIDATION_ERROR_MSG", new Object[] { className }));
}
}
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "Addition");
}
public Object evaluate() throws SPLException
{
logger.entering(sourceClass, Thread.currentThread().getName() + " "
+ "evaluate");
try
{
Number lhs = (Number) _lhsExp.evaluate();
Number rhs = (Number) _rhsExp.evaluate();
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "evaluate");
return plus(lhs, rhs);
}
catch (Exception e)
{
logger.severe(Thread.currentThread().getName() + " "
+ "evaluation error: " + e.toString());
throw new SPLException(Messages.getString(
"SPL_EVALUATION_ERROR_MSG", new Object[] { e.toString() }));
}
}
public static Number plus(Vector o) throws IllegalExpressionTypeException {
Number[] operandArray = (Number[]) o.toArray(new Number[0]);
return plus(operandArray);
}
public static Number plus(Number[] o) throws IllegalExpressionTypeException
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "plus(Number[])");
Number[] o1 = new Number[2];
Number result = null;
for (int i = 0; i < o.length; i++) {
if (i == 0) {
result = o[i];
} else {
o1[0] = result;
o1[1] = o[i];
int resolvedType = TypeResolver.resolveType(o1);
if (resolvedType == TypeConstants.doubleType)
{
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "plus(Number[])");
return new Double(result.doubleValue() + o[i].doubleValue());
}
else if (resolvedType == TypeConstants.floatType)
{
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "plusplus(Number[])");
return new Float(result.floatValue() + o[i].floatValue());
}
else if (resolvedType == TypeConstants.longType)
{
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "plusplus(Number[])");
return new Long(result.longValue() + o[i].longValue());
}
else if (resolvedType == TypeConstants.shortType)
{
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "plusplus(Number[])");
return new Long(result.shortValue() + o[i].shortValue());
}
else if (resolvedType == TypeConstants.byteType)
{
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "plusplus(Number[])");
return new Long(result.byteValue() + o[i].byteValue());
}
else
{
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "plusplus(Number[])");
return new Integer(result.intValue() + o[i].intValue());
}
}
}
return result;
}
public static Number plus(Number o1, Number o2)
throws IllegalExpressionTypeException
{
logger.entering(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
Number[] o = new Number[2];
o[0] = o1;
o[1] = o2;
int resolvedType = TypeResolver.resolveType(o);
if (resolvedType == TypeConstants.doubleType)
{
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
return new Double(o1.doubleValue() + o2.doubleValue());
}
else if (resolvedType == TypeConstants.floatType)
{
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
return new Float(o1.floatValue() + o2.floatValue());
}
else if (resolvedType == TypeConstants.longType)
{
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
return new Long(o1.longValue() + o2.longValue());
}
else if (resolvedType == TypeConstants.shortType)
{
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
return new Long(o1.shortValue() + o2.shortValue());
}
else if (resolvedType == TypeConstants.byteType)
{
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
return new Long(o1.byteValue() + o2.byteValue());
}
else
{
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "plus");
return new Integer(o1.intValue() + o2.intValue());
}
}
public boolean validate() throws SPLException
{
logger.entering(sourceClass, Thread.currentThread().getName() + " "
+ "validate");
TypeInfo lType = _lhsExp.getType();
TypeInfo rType = _rhsExp.getType();
// dataType = TypeConstants.numericType;
if (TypeResolver.isNumeric(lType) && TypeResolver.isNumeric(rType)
&& !lType.getIsArray() && !rType.getIsArray())
{
_dataType = TypeResolver.binaryNumericPromotionResolver(lType,
rType);
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "validate");
return true;
}
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "validate");
return false;
}
public String toString()
{
logger.entering(sourceClass, Thread.currentThread().getName() + " "
+ "toString");
String str = this._lhsExp.toString() + " + " + this._rhsExp.toString();
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "toString");
return str;
}
}