/*
* 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 Prashant Baliga <prabalig@in.ibm.com>
*
*/
package org.apache.imperius.spl.parser.statements.actions.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import org.apache.imperius.spl.core.Actuator;
import org.apache.imperius.spl.core.Argument;
import org.apache.imperius.spl.core.Expression;
import org.apache.imperius.spl.core.TypeConstants;
import org.apache.imperius.spl.core.TypeInfo;
import org.apache.imperius.spl.parser.compiler.IdentPrimaryTuple;
import org.apache.imperius.spl.parser.compiler.symboltable.MethodSymbol;
import org.apache.imperius.spl.parser.compiler.symboltable.SPLSymbolTable;
import org.apache.imperius.spl.parser.exceptions.SPLException;
import org.apache.imperius.spl.parser.expression.primary.PrimaryExpression;
import org.apache.imperius.spl.parser.expressions.impl.AssignmentExpression;
import org.apache.imperius.spl.parser.statements.BasicActionBlock;
import org.apache.imperius.spl.parser.statements.impl.ArgumentImpl;
import org.apache.imperius.spl.parser.util.ActuatorFactory;
import org.apache.imperius.spl.parser.util.ExpressionUtility;
import org.apache.imperius.spl.parser.util.TypeInfoImpl;
import org.apache.imperius.spl.parser.util.TypeResolver;
import org.apache.imperius.util.Messages;
import org.apache.imperius.util.SPLLogger;
public class AnchorMethodInvokeAction implements BasicActionBlock
{
private String _className = null;
private SPLSymbolTable _symTable = null;
private List _identTupleList = null;
private String _operatorType = null;
private Expression _constantExpression = null;
private static Logger logger = SPLLogger.getSPLLogger().getLogger();
private static final String sourceClass = "MethodInvokeAction";
public AnchorMethodInvokeAction(String className, List identTupleList,
String operatorType, Expression constExpr, SPLSymbolTable symTable) throws SPLException
{
logger.entering(sourceClass, Thread.currentThread().getName() + " "
+ "MethodInvokeAction");
_className = className;
_identTupleList = identTupleList;
_operatorType = operatorType;
_constantExpression = constExpr;
_symTable = symTable;
_validate();
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "MethodInvokeAction");
}
private void _validate() throws SPLException
{
boolean isArray = false;
if (!_identTupleList.isEmpty())
{
TypeInfo returnType = new TypeInfoImpl(TypeConstants.referenceType,
_className, isArray);
Iterator identTupleIt = _identTupleList.iterator();
int i = 0;
while (identTupleIt.hasNext())
{
if (returnType.getType() == TypeConstants.referenceType)
{
String referenceTypeName = returnType
.getReferenceTypeName();
IdentPrimaryTuple ipt = (IdentPrimaryTuple) identTupleIt
.next();
if (i++ == 0)
{
ipt.setSymbolTable(_symTable);
}
returnType = ipt.validate(referenceTypeName);
}
}
}
}
// public static void validateActualParameters(SPLSymbolTable symTab,
// String classNameOrVariableName, String methodName, List pList)
// throws SPLException
// {
//
// // xiping's addition to support Java overloading, 06/19/09
// Collection c = symTab.getSymbol(classNameOrVariableName + "." + methodName);
// MethodSymbol methodSym = null;
// for (Iterator it = c.iterator(); it.hasNext();) {
// methodSym = (MethodSymbol) it.next();
// List argTypeList = methodSym.getArgumentList();
//
// if (argTypeList.size() != pList.size()) {
// continue;
// }
//
// boolean notEqual = false;
// for (int i = 0; i < argTypeList.size(); i++) {
// Expression exp = (Expression)pList.get(i);
// Argument arg = (Argument)argTypeList.get(i);
// TypeInfoImpl expDataType = exp.getType();
// TypeInfoImpl argDataType = arg.getType();
//// if (expDataType.getIsArray() != argDataType.getIsArray() ||
//// expDataType.getType() != argDataType.getType()) {
// if (expDataType.getType() != argDataType.getType()) {
// notEqual = true;
// break;
// }
// }
//
// if (notEqual) {
// continue;
// }
//
// break;
// }
//
// if (methodSym == null) {
// throw new SPLException("actual parameter validation failed: " + methodName + "does not exit");
// }
// // end
//
// //Xiping 05/30/09 commented the original code below
// List argTypeList = methodSym.getArgumentList();
//
// Iterator formalParamTypeIt = argTypeList.iterator();
// Iterator actualParamIt = pList.iterator();
// if (argTypeList.size() == pList.size())
// {
// while (formalParamTypeIt.hasNext() && actualParamIt.hasNext())
// {
// Argument formalArg = (Argument) formalParamTypeIt.next();
// Expression actualParam = (Expression) actualParamIt.next();
// if (!TypeResolver.isTypeAssignableForEquality(formalArg
// .getType(), actualParam.getType())
// /* || formalArg.getIsArray() != actualParam.isArray() */)
//
// {
// throw new SPLException(
// Messages
// .getString("SPL_METHOD_PASSED_ARGUMENTS_EXCEPTION_MSG")
// + " " + methodName);
// }
//
// }
// }
// else
// {
// System.err
// .println("Number of Formal and passed parameters don't match for method "
// + methodName);
// // throw new SPLException("Number of Formal and passed parameters don't match for method "
// // + methodName);
// }
//
// }
public static void validateActualParameters(SPLSymbolTable symTab,
String classNameOrVariableName, String methodName, List pList)
throws SPLException
{
// xiping's addition to support Java overloading, 06/19/09
Collection c = (Collection)symTab.getSymbol(classNameOrVariableName + "." + methodName);
MethodSymbol methodSym = null;
for (Iterator it = c.iterator(); it.hasNext();) {
methodSym = (MethodSymbol) it.next();
List argTypeList = methodSym.getArgumentList();
if (argTypeList.size() != pList.size()) {
continue;
}
boolean typeNotEqual = false;
for (int i = 0; i < argTypeList.size(); i++) {
Expression exp = (Expression)pList.get(i);
Argument arg = (Argument)argTypeList.get(i);
TypeInfo expDataType = exp.getType();
TypeInfo argDataType = arg.getType();
// if (expDataType.getIsArray() != argDataType.getIsArray() ||
// expDataType.getType() != argDataType.getType()) {
if (expDataType.getType() != argDataType.getType()) {
typeNotEqual = true;
break;
}
}
if (typeNotEqual) {
continue;
}
break;
}
if (methodSym == null) {
throw new SPLException("actual parameter validation failed: " + methodName + "does not exit");
}
// end
List argTypeList = methodSym.getArgumentList();
Iterator formalParamTypeIt = argTypeList.iterator();
Iterator actualParamIt = pList.iterator();
//Xiping 05/30/09
//1) argTypeList.size() will be different from pList.size()
//if there are overloaded methods in an anchor class.
//
//2) formalArg.getIsArray() is different from actualParam.isArray()
//if an argument passed in is of array return type as SPL does not
//carry return type info correctly except for collection expressions.
if (true)
{
while (formalParamTypeIt.hasNext() && actualParamIt.hasNext())
{
Argument formalArg = (Argument) formalParamTypeIt.next();
Expression actualParam = (Expression) actualParamIt.next();
if (!TypeResolver.isTypeAssignableForEquality(formalArg
.getType(), actualParam.getType()))
{
throw new SPLException(
Messages
.getString("SPL_METHOD_PASSED_ARGUMENTS_EXCEPTION_MSG")
+ " " + methodName);
}
}
}
//Xiping 05/30/09 commented the original code below
/*
if (argTypeList.size() == pList.size())
{
while (formalParamTypeIt.hasNext() && actualParamIt.hasNext())
{
Argument formalArg = (Argument) formalParamTypeIt.next();
Expression actualParam = (Expression) actualParamIt.next();
if (!TypeResolver.isTypeAssignableForEquality(formalArg
.getType(), actualParam.getType())
|| formalArg.getIsArray() != actualParam.isArray())
{
throw new SPLException(
Messages
.getString("SPL_METHOD_PASSED_ARGUMENTS_EXCEPTION_MSG")
+ " " + methodName);
}
}
}
*/
else
{
System.err
.println("Number of Formal and passed parameters don't match for method "
+ methodName);
// throw new SPLException("Number of Formal and passed parameters don't match for method "
// + methodName);
}
}
public boolean execute(Actuator ac) throws SPLException
{
boolean postExprResult = false;
int i = 0;
Object intermediateObject = null;
// try
// {
if (!_identTupleList.isEmpty())
{
Iterator idIter = _identTupleList.iterator();
while (idIter.hasNext())
{
IdentPrimaryTuple ipt = (IdentPrimaryTuple) idIter.next();
if (i++ == 0)
{
intermediateObject = ipt.evaluate();
}
else
{
intermediateObject = ipt.evaluate(intermediateObject);
}
}
}
if (intermediateObject != null)
{
if (_constantExpression == null)
{
postExprResult = true;
}
else
{
Expression constexpr = this._constantExpression;
Object constresult;
int compareResult = 0;
try
{
constresult = constexpr.evaluate();
compareResult = ExpressionUtility.compare(
intermediateObject, constresult);
}
catch (SPLException e)
{
// e.printStackTrace();
logger.severe(Thread.currentThread().getName() + " "
+ e.getMessage());
throw e;
}
String operation = this._operatorType;
if (operation.equalsIgnoreCase("=="))
{
if (compareResult != 0)
postExprResult = false;
else
postExprResult = true;
}
else if (operation.equalsIgnoreCase("!="))
{
if (compareResult == 0)
postExprResult = false;
else
postExprResult = true;
}
else if (operation.equalsIgnoreCase(">="))
{
if (compareResult < 0)
postExprResult = false;
else
postExprResult = true;
}
else if (operation.equalsIgnoreCase(">"))
{
if (compareResult <= 0)
postExprResult = false;
else
postExprResult = true;
}
else if (operation.equalsIgnoreCase("<"))
{
if (compareResult >= 0)
postExprResult = false;
else
postExprResult = true;
}
else if (operation.equalsIgnoreCase("<="))
{
if (compareResult > 0)
postExprResult = false;
else
postExprResult = true;
}
else
{
logger
.severe(Thread.currentThread().getName()
+ " "
+ "operation did not match any of the standard expressions "
+ operation);
}
}
//System.out.println("AnchorMethodInvokeAction returning "+postExprResult);
return postExprResult;
}
// }
// catch (SPLException e)
// {
//
// }
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "execute");
return false;
}
// xiping's addition to support Java overloading, 06/19/09
public static Object invokeClassMethod(SPLSymbolTable symTab,
String className, String qualifier, String methodName,
List paramList, Object targetObject) throws SPLException
{
List parameterObjects = new ArrayList();
try
{
MethodSymbol methodSym = null;
Collection c = (Collection)symTab.getSymbol(className + "." + methodName);
for (Iterator it = c.iterator(); it.hasNext();) {
methodSym = (MethodSymbol) it.next();
List argTypeList = methodSym.getArgumentList();
if (argTypeList.size() != paramList.size()) {
continue;
}
boolean typeNotEqual = false;
for (int i = 0; i < argTypeList.size(); i++) {
Expression exp = (Expression)paramList.get(i);
ArgumentImpl arg = (ArgumentImpl)argTypeList.get(i);
TypeInfo expDataType = exp.getType();
TypeInfo argDataType = arg.getType();
// if (expDataType.getIsArray() != argDataType.getIsArray() ||
// expDataType.getType() != argDataType.getType()) {
if (expDataType.getType() != argDataType.getType()) {
typeNotEqual = true;
break;
}
}
if (typeNotEqual) {
continue;
}
break;
}
if (methodSym == null) {
throw new SPLException("invokeClassMethod failed: " + methodName + "does not exit");
}
List argTypeList = methodSym.getArgumentList();
for (int i = 0; i < paramList.size(); i++)
{
Expression exp = (Expression) paramList.get(i);
if (exp instanceof AssignmentExpression) {
//System.out.println("assignment Expression");
Expression lhsExpression = null;
Expression rhsExpression = null;
AssignmentExpression assignmentExpression = (AssignmentExpression) exp;
if (assignmentExpression.getLHSExpression() instanceof org.apache.imperius.spl.core.Expression)
{
lhsExpression = (Expression) assignmentExpression
.getLHSExpression();
}
if (assignmentExpression.getRHSExpression() instanceof org.apache.imperius.spl.core.Expression) {
rhsExpression = (Expression) assignmentExpression
.getRHSExpression();
}
if ((lhsExpression == null) || (rhsExpression == null))
{
logger
.severe("LHS or RHS or argument in method call is null : "
+ lhsExpression.toString()
+ " "
+ rhsExpression);
throw new SPLException(Messages.getString(
"SPL_ASSIGNMENT_EXP_EXCEPTION_MSG",
new Object[] { lhsExpression, rhsExpression }));
}
//System.out.println("lhsExpression class "+ lhsExpression.getClass());
//System.out.println("lhsExpression getPropertyName() "+ ((PrimaryExpression) lhsExpression).getPropertyName());
// ((PrimaryExpression)lhsExpression).getPropertyName();
String keyName = ((PrimaryExpression) lhsExpression)
.getclassNameOrInstanceVariableName();
//System.out.println("argument name= " + keyName);
Object keyValue = rhsExpression.evaluate();
//System.out.println("argument value= " + keyValue);
String referenceTypeName = "";
if (TypeResolver.isReference(rhsExpression.getType()))
{
referenceTypeName = rhsExpression.getType()
.getReferenceTypeName();
}
if (keyValue != null)
{
Argument arg = new ArgumentImpl(rhsExpression.getType()
.getType(), keyName, rhsExpression.isArray(),
referenceTypeName);
arg.setValue(keyValue);
//System.out.println("created new arg :"+keyName+" "+keyValue.toString());
/*
* Expression expression=(Expression)pList.get(i); String
* nameAndValue=(String)expression.evaluate(); Key
*/
parameterObjects.add(arg);
}
}
else
{
Object result = exp.evaluate();
boolean isArgCreated = false;
if(argTypeList != null && argTypeList.size() > 0)
{
Argument tempArg = null;
if(i < argTypeList.size())
{
tempArg = (Argument)argTypeList.get(i);
if(TypeResolver.isReference(tempArg.getType()))
{
if (TypeResolver.OBJECT_STRING.equals(tempArg
.getType().getReferenceTypeName())
&& TypeResolver.isString(exp.getType()))
{
Argument arg = new ArgumentImpl(tempArg
.getType().getType(), null, tempArg
.getType().getIsArray(),
TypeResolver.OBJECT_STRING);
arg.setValue(result);
parameterObjects.add(arg);
isArgCreated = true;
}
}
}
else
{
// throw exception
}
}
if(!isArgCreated)
{
//Xiping 05/29/09
//get isArray flag from the formal argument list if available
boolean flag = exp.isArray();
if(argTypeList != null && i < argTypeList.size()) {
flag = ((Argument)argTypeList.get(i)).getType().getIsArray();
}
//
Argument arg = new ArgumentImpl(exp.getType().getType(),
// null, exp.isArray(), null);
null, flag, null);
arg.setValue(result);
parameterObjects.add(arg);
}
}
}
Actuator ac = ActuatorFactory.getActuator();
Object result = ac.invokeMethod(className, qualifier, targetObject,
methodName, parameterObjects);
//System.out.println("method invokation complete : "+className+" "+qualifier+" "+methodName+" "+targetObject);
//System.out.println("method invokation result of invokation : "+result);
// TO DO COMPARE RESULT WITH CONSTANT
if (result == null)
result = "";
return result;
}
catch (SPLException e)
{
logger.severe(e.getMessage());
logger.exiting(sourceClass, Thread.currentThread().getName() + " "
+ "execute");
// return null;
throw e;
}
}
// public static Object invokeClassMethod(SPLSymbolTable symTab,
// String className, String qualifier, String methodName,
// List paramList, Object targetObject) throws SPLException
// {
//
// // xiping's addition to support Java overloading, 06/19/09
// // start
// MethodSymbol methodSym = null;
// Collection c = (Collection)symTab.getSymbol(className + "." + methodName);
// for (Iterator it = c.iterator(); it.hasNext();) {
// methodSym = (MethodSymbol) it.next();
// List argTypeList = methodSym.getArgumentList();
//
// if (argTypeList.size() != paramList.size()) {
// continue;
// }
// boolean typeNotEqual = false;
// for (int i = 0; i < argTypeList.size(); i++) {
// Expression exp = (Expression)paramList.get(i);
// ArgumentImpl arg = (ArgumentImpl)argTypeList.get(i);
// TypeInfoImpl expDataType = exp.getType();
// TypeInfoImpl argDataType = arg.getType();
//// if (expDataType.getIsArray() != argDataType.getIsArray() ||
//// expDataType.getType() != argDataType.getType()) {
// if (expDataType.getType() != argDataType.getType()) {
// typeNotEqual = true;
// break;
// }
// }
// if (typeNotEqual) {
// continue;
// }
//
// break;
// }
//
// if (methodSym == null) {
// throw new SPLException("invokeClassMethod failed: " + methodName + "does not exit");
// }
// // end
//
// List parameterObjects = new ArrayList();
// try
// {
// List argTypeList = methodSym.getArgumentList();
//
// for (int i = 0; i < paramList.size(); i++)
// {
// Expression exp = (Expression) paramList.get(i);
//
// if (exp instanceof AssignmentExpression) {
// //System.out.println("assignment Expression");
// Expression lhsExpression = null;
// Expression rhsExpression = null;
//
// AssignmentExpression assignmentExpression = (AssignmentExpression) exp;
// if (assignmentExpression.getLHSExpression() instanceof org.apache.imperius.spl.core.Expression)
// {
// lhsExpression = (Expression) assignmentExpression
// .getLHSExpression();
// }
// if (assignmentExpression.getRHSExpression() instanceof org.apache.imperius.spl.core.Expression) {
// rhsExpression = (Expression) assignmentExpression
// .getRHSExpression();
// }
// if ((lhsExpression == null) || (rhsExpression == null))
// {
// logger
// .severe("LHS or RHS or argument in method call is null : "
// + lhsExpression.toString()
// + " "
// + rhsExpression);
//
// throw new SPLException(Messages.getString(
// "SPL_ASSIGNMENT_EXP_EXCEPTION_MSG",
// new Object[] { lhsExpression, rhsExpression }));
// }
// //System.out.println("lhsExpression class "+ lhsExpression.getClass());
// //System.out.println("lhsExpression getPropertyName() "+ ((PrimaryExpression) lhsExpression).getPropertyName());
// // ((PrimaryExpression)lhsExpression).getPropertyName();
//
// String keyName = ((PrimaryExpression) lhsExpression)
// .getclassNameOrInstanceVariableName();
// //System.out.println("argument name= " + keyName);
//
// Object keyValue = rhsExpression.evaluate();
// //System.out.println("argument value= " + keyValue);
//
// String referenceTypeName = "";
//
// if (TypeResolver.isReference(rhsExpression.getType()))
// {
//
// referenceTypeName = rhsExpression.getType()
// .getReferenceTypeName();
//
// }
//
// if (keyValue != null)
// {
// Argument arg = new ArgumentImpl(rhsExpression.getType()
// .getType(), keyName, rhsExpression.isArray(),
// referenceTypeName);
// arg.setValue(keyValue);
//
// //System.out.println("created new arg :"+keyName+" "+keyValue.toString());
// /*
// * Expression expression=(Expression)pList.get(i); String
// * nameAndValue=(String)expression.evaluate(); Key
// */
// parameterObjects.add(arg);
// }
//
// }
// else
// {
// Object result = exp.evaluate();
// boolean isArgCreated = false;
// if(argTypeList != null && argTypeList.size() > 0)
// {
// Argument tempArg = null;
// if(i < argTypeList.size())
// {
// tempArg = (Argument)argTypeList.get(i);
// if(TypeResolver.isReference(tempArg.getType()))
// {
// if (TypeResolver.OBJECT_STRING.equals(tempArg
// .getType().getReferenceTypeName())
// && TypeResolver.isString(exp.getType()))
// {
// Argument arg = new ArgumentImpl(tempArg
// .getType().getType(), null, tempArg
// .getType().getIsArray(),
// TypeResolver.OBJECT_STRING);
// arg.setValue(result);
// parameterObjects.add(arg);
// isArgCreated = true;
// }
// }
// }
// else
// {
// // throw exception
// }
// }
// if(!isArgCreated)
// {
// //Xiping 05/29/09
// Argument arg = new ArgumentImpl(exp.getType().getType(),
// //null, exp.isArray(), null);
// null, result.getClass().isArray(), null);
// arg.setValue(result);
//
// parameterObjects.add(arg);
// }
// }
// }
//
// Actuator ac = ActuatorFactory.getActuator();
//
// Object result = ac.invokeMethod(className, qualifier, targetObject,
// methodName, parameterObjects);
//
// //System.out.println("method invokation complete : "+className+" "+qualifier+" "+methodName+" "+targetObject);
// //System.out.println("method invokation result of invokation : "+result);
//
// // TO DO COMPARE RESULT WITH CONSTANT
//
// if (result == null)
// result = "";
//
// return result;
// }
// catch (SPLException e)
// {
// logger.severe(e.getMessage());
//
// logger.exiting(sourceClass, Thread.currentThread().getName() + " "
// + "execute");
//
// // return null;
// throw e;
// }
// }
}