/*
* 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 Neeraj Joshi <jneeraj@us.ibm.com>
*
*/
package org.apache.imperius.spl.parser.compiler;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.apache.imperius.spl.core.Argument;
import org.apache.imperius.spl.core.DataCollector;
import org.apache.imperius.spl.core.Expression;
import org.apache.imperius.spl.core.InstanceInfo;
import org.apache.imperius.spl.core.TypeInfo;
import org.apache.imperius.spl.parser.compiler.symboltable.MethodSymbol;
import org.apache.imperius.spl.parser.compiler.symboltable.SPLSymbolTable;
import org.apache.imperius.spl.parser.compiler.symboltable.Symbol;
import org.apache.imperius.spl.parser.exceptions.SPLException;
import org.apache.imperius.spl.parser.statements.actions.impl.AnchorMethodInvokeAction;
import org.apache.imperius.spl.parser.util.DataCollectorFactory;
import org.apache.imperius.spl.parser.util.TypeInfoImpl;
import org.apache.imperius.spl.parser.util.TypeResolver;
import org.apache.imperius.util.Messages;
public class IdentPrimaryTuple
{
private Expression _arrExp = null;
private List _paramList ;
private String _identifier = "";
private boolean _isMethod = false;
private SPLSymbolTable _symbolTable;
private String _classType = null;
public IdentPrimaryTuple(Expression arrExp,
List paramList, String id, boolean isMethod,
SPLSymbolTable sTab)
{
_arrExp = arrExp;
_paramList = paramList;
_identifier = id;
_isMethod = isMethod;
_symbolTable = sTab;
}
public String getPropertyName()
{
return _identifier;
}
public void setSymbolTable(SPLSymbolTable spt)
{
_symbolTable = spt;
}
// // no input object means that the symbol table already has anchor object
// // populated
// public Object evaluate() throws SPLException
// {
// Object returnValue = null;
//
// if(_isMethod)
// {
// Object instance = _symbolTable.getInstance(_classType);
// String qualifier = _symbolTable.getQualifierForClass(_classType);
// returnValue = AnchorMethodInvokeAction.invokeClassMethod(_symbolTable,
// _classType, qualifier, _identifier, _paramList,instance);
// }
// else
// {
// // xiping's addition to support Java overloading, 06/19/09
// // start
// Symbol sym = null;
// Object obj = _symbolTable.getSymbol(_classType + "." + _identifier);
// if (obj instanceof Vector) { //MethodSysbol
// Collection c = (Collection) obj;
// for (Iterator it = c.iterator(); it.hasNext();) {
// sym = (Symbol) it.next();
// List aList = ((MethodSymbol)sym).getArgumentList();
//
// if (aList.size() != _paramList.size()) {
// continue;
// }
//
// boolean typeNotEqual = false;
// for (int i = 0; i < aList.size(); i++) {
// Expression exp = (Expression)_paramList.get(i);
// Argument arg = (Argument)aList.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;
// }
// } else { //PropertySymbol
// sym = (Symbol) obj;
// }
//
// for (Iterator it = c.iterator(); it.hasNext();) {
// sym = (Symbol) it.next();
// List aList = ((MethodSymbol)sym).getArgumentList();
//
// if (aList.size() != _paramList.size()) {
// continue;
// }
//
// boolean notEqual = false;
// for (int i = 0; i < aList.size(); i++) {
// Expression exp = (Expression)_paramList.get(i);
// Argument arg = (Argument)aList.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 (sym == null) {
// throw new SPLException("evaluate() failed: " + _identifier + "does not exit");
// }
// // end
//
// returnValue = sym.getValue();
// }
//
//
// return returnValue;
//
// }
// public Object evaluate(Object parentObject) throws SPLException
// {
// Object returnValue = null;
//
// DataCollector dc = DataCollectorFactory.getDataCollector();
// String qualifier = _symbolTable.getQualifierForClass(_classType);
// Map symbolsofInstance = dc.getSymbolsForInstance(_classType,
// qualifier,
// parentObject);
// Map instanceMap = new HashMap();
// instanceMap.put(_classType, parentObject);
// _symbolTable.populateInstanceValuesForInstance(_classType,
// _classType,
// parentObject,
// symbolsofInstance);
//
// //_symbolTable.setAnchors(mapOfAnchorClassToInstance);
// if(_isMethod)
// {
// returnValue = AnchorMethodInvokeAction.invokeClassMethod(_symbolTable,
// _classType, qualifier, _identifier, _paramList, parentObject);
// }
// else
// {
// // xiping's addition to support Java overloading, 06/19/09
// // start
// Symbol sym = null;
// Collection c = _symbolTable.getSymbol(_classType + "." + _identifier);
// for (Iterator it = c.iterator(); it.hasNext();) {
// sym = (Symbol) it.next();
// List aList = ((MethodSymbol)sym).getArgumentList();
//
// if (aList.size() != _paramList.size()) {
// continue;
// }
//
// boolean notEqual = false;
// for (int i = 0; i < aList.size(); i++) {
// Expression exp = (Expression)_paramList.get(i);
// Argument arg = (Argument)aList.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 (sym == null) {
// throw new SPLException("evaluate(Object) failed: " + _identifier + "does not exit");
// }
// // end
//
// returnValue = sym.getValue();
//
// }
//
// return returnValue;
// }
// no input object means that the symbol table already has anchor object
// populated
public Object evaluate() throws SPLException
{
Object returnValue = null;
Object instance = _symbolTable.getInstance(_classType);
String qualifier = _symbolTable.getQualifierForClass(_classType);
if(_isMethod) // MethodSymbol
{
returnValue = AnchorMethodInvokeAction.invokeClassMethod(_symbolTable,
_classType, qualifier, _identifier, _paramList, instance);
}
else // PropertySymbol
{
Symbol sym = null;
try
{
sym = (Symbol)_symbolTable.getSymbol(_classType + "." + _identifier);
returnValue = sym.getValue();
}
catch(SPLException splex)
{
String accessorMethodName = getAccessorMethodName(_identifier, "get");
try
{
// xiping 09/22/2009
// not sure what this line of code is doing
// sym is not referenced
// sym = (Symbol)_symbolTable.getSymbol(_classType + "." + accessorMethodName);
Object obj = _symbolTable.getSymbol(_classType + "." + accessorMethodName);
}
catch(SPLException splex1)
{
accessorMethodName = getAccessorMethodName(_identifier, "is");
try
{
// xiping 09/22/2009
// not sure what this line of code is doing
// sym is not referenced
// sym = (Symbol)_symbolTable.getSymbol(_classType + "." + accessorMethodName);
Object obj = _symbolTable.getSymbol(_classType + "." + accessorMethodName);
}
catch(SPLException splex2)
{
throw new SPLException(
Messages
.getString(
"SPL_SYMBOL_DOES_NOT_EXIST_EXCEPTION_MSG",
new Object[] { _classType + "."
+ _identifier }));
}
}
returnValue = AnchorMethodInvokeAction.invokeClassMethod(_symbolTable, _classType, qualifier,
accessorMethodName, _paramList, instance);
}
}
return returnValue;
}
public Object evaluate(Object parentObject) throws SPLException
{
Object returnValue = null;
DataCollector dc = DataCollectorFactory.getDataCollector();
String qualifier = _symbolTable.getQualifierForClass(_classType);
Map symbolsofInstance = dc.getSymbolsForInstance(_classType,
qualifier,
parentObject);
Map instanceMap = new HashMap();
instanceMap.put(_classType, parentObject);
_symbolTable.populateInstanceValuesForInstance(_classType,
_classType, parentObject, symbolsofInstance);
// Symbol sym = _symbolTable.getSymbol(_classType + "." + _identifier);
//_symbolTable.setAnchors(mapOfAnchorClassToInstance);
if(_isMethod) //MethodSymbol
{
returnValue = AnchorMethodInvokeAction.invokeClassMethod(_symbolTable,
_classType, qualifier, _identifier, _paramList, parentObject);
}
else // PropertySymbol
{
Symbol sym = null;
try
{
sym = (Symbol)_symbolTable.getSymbol(_classType + "." + _identifier);
returnValue = sym.getValue();
}
catch(SPLException splex)
{
String accessorMethodName = getAccessorMethodName(_identifier, "get");
try
{
sym = (Symbol)_symbolTable.getSymbol(_classType + "."
+ accessorMethodName);
}
catch(SPLException splex1)
{
accessorMethodName = getAccessorMethodName(_identifier, "is");
try
{
sym = (Symbol)_symbolTable.getSymbol(_classType + "."
+ accessorMethodName);
}
catch(SPLException splex2)
{
throw new SPLException(
Messages
.getString(
"SPL_SYMBOL_DOES_NOT_EXIST_EXCEPTION_MSG",
new Object[] { _classType + "."
+ _identifier }));
}
}
returnValue = AnchorMethodInvokeAction.invokeClassMethod(
_symbolTable, _classType, qualifier,
accessorMethodName, _paramList, parentObject);
}
}
return returnValue;
}
public TypeInfo validate(String classTypeOrVariableName) throws SPLException
{
TypeInfo typeInfo = new TypeInfoImpl();
_classType = classTypeOrVariableName;
// ensure symbol table is populated
_populateSymbolTable(_classType);
// xiping's addition to support Java overloading, 06/19/09
// start
Object obj = null;
try {
obj = _symbolTable.getSymbol(classTypeOrVariableName + "." + _identifier);
} catch(SPLException splex) {
try
{
obj = _symbolTable.getSymbol(classTypeOrVariableName + "." + getAccessorMethodName(_identifier, "get"));
}
catch(SPLException splex1)
{
try
{
obj = _symbolTable.getSymbol(classTypeOrVariableName + "." + getAccessorMethodName(_identifier, "is"));
}
catch(SPLException splex2)
{
throw new SPLException(
Messages
.getString(
"SPL_SYMBOL_DOES_NOT_EXIST_EXCEPTION_MSG",
new Object[] { classTypeOrVariableName + "."
+ _identifier }));
}
}
}
Symbol sym = null;
if (obj instanceof Vector) { // MethodSymbol
Collection c = (Collection) obj;
for (Iterator it = c.iterator(); it.hasNext();) {
sym = (Symbol) it.next();
List aList = ((MethodSymbol)sym).getArgumentList();
if (aList.size() != _paramList.size()) {
continue;
}
boolean typeNotEqual = false;
for (int i = 0; i < aList.size(); i++) {
Expression exp = (Expression)_paramList.get(i);
Argument arg = (Argument)aList.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;
}
} else { // PropertySymbol
sym = (Symbol) obj;
}
if(_isMethod)
{
if(sym instanceof MethodSymbol)
{
typeInfo = _validateActualParameters(sym,classTypeOrVariableName);
}
else
{
throw new SPLException("Symbol " + _identifier + "is not a method");
}
}
else
{
TypeInfo tp = sym.getType();
boolean isArray = sym.isArray();
if(_arrExp != null) // expression is like A.b[2] which means
{ // the result is not an array
isArray = false;
}
String resultClass = null;
if(TypeResolver.isReference(tp))
{
resultClass = sym.getReferenceTypeName();
typeInfo.setReferenceTypeName(resultClass);
typeInfo.setType(tp.getType());
typeInfo.setIsArray(isArray);
}
else
{
typeInfo.setType(tp.getType());
typeInfo.setIsArray(isArray);
}
}
return typeInfo;
}
private String getAccessorMethodName(String identifier, String setOrGetOrIs)
{
if(Character.isLetter(identifier.charAt(0)))
{
identifier = Character.toUpperCase(identifier.charAt(0)) + identifier.substring(1);
}
identifier = setOrGetOrIs+identifier;
return identifier;
}
private TypeInfo _validateActualParameters(Symbol sym,
String classType) throws SPLException
{
TypeInfo returnTypeInfo = new TypeInfoImpl();
String returnClassName = null;
AnchorMethodInvokeAction.validateActualParameters(_symbolTable,
classType, _identifier, _paramList);
TypeInfo returnType = sym.getType();
boolean isArray = sym.isArray();
if(TypeResolver.isReference(returnType))
{
returnClassName = sym.getReferenceTypeName();
returnTypeInfo.setIsArray(isArray);
returnTypeInfo.setReferenceTypeName(returnClassName);
returnTypeInfo.setType(returnType.getType());
}
else
{
returnTypeInfo.setIsArray(isArray);
returnTypeInfo.setType(returnType.getType());
}
return returnTypeInfo;
}
private void _populateSymbolTable(String classType) throws SPLException
{
String qualifierName = null;
if(_symbolTable.getAnchorData() == null)
{
List instanceInfoList = new ArrayList(1);
instanceInfoList.add(new InstanceInfo(classType, new Object()));
_symbolTable.addAnchor(classType,qualifierName,instanceInfoList);
}
}
//Xiping 05/25/08
public List getParamList() {
return _paramList;
}
public String getIdentifier() {
return _identifier;
}
public boolean isMethod() {
return _isMethod;
}
//
}