blob: e6cb34b8a57061bbc48c4d6bffb2f896aa9bd49a [file] [log] [blame]
/**
* <copyright>
* </copyright>
*
* $Id: IBoundedListTypeDescriptorImpl.java,v 1.6 2007/10/01 04:29:44 cbateman Exp $
*/
package org.eclipse.jst.jsf.context.symbol.internal.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.common.util.TypeUtil;
import org.eclipse.jst.jsf.context.symbol.IBoundedListTypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.ITypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.context.symbol.SymbolPackage;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>IBounded List Type Descriptor</b></em>'.
* <!-- end-user-doc -->
* <p>
* </p>
*
* @generated
*/
public class IBoundedListTypeDescriptorImpl extends IListTypeDescriptorImpl implements IBoundedListTypeDescriptor {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@SuppressWarnings("hiding")
public static final String copyright = "Copyright 2006 Oracle"; //$NON-NLS-1$
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected IBoundedListTypeDescriptorImpl() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected EClass eStaticClass() {
return SymbolPackage.Literals.IBOUNDED_LIST_TYPE_DESCRIPTOR;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public boolean isUnboundedForType(String typeSignature)
{
// type signature must be a boxed integer
// TODO: at this level, do we need to deal with coercion to
// other integer types? list.get() takes an integer...
return typeSignature != null && TypeConstants.TYPE_BOXED_INTEGER.equals(typeSignature);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public ISymbol getUnboundedProperty(Object name, String typeSignature) {
ISymbol retValue = null;
if (isUnboundedForType(typeSignature)
&& name instanceof Number)
{
// get integer value
int offset = ((Number)name).intValue();
// first see if we have it in our map source
// TODO: retValue = getFromMap(name.toString());
if (retValue == null)
{
IPropertySymbol propSymbol = SymbolFactory.eINSTANCE.createIPropertySymbol();
// TODO: there is a possible problem here for non-string keyed maps
propSymbol.setName(name.toString());
propSymbol.setReadable(true);
propSymbol.setTypeDescriptor(getBoundsTypeDescriptor(offset));
retValue = propSymbol;
}
}
return retValue;
}
/**
* <!-- begin-user-doc -->
* @param methodName
* @param methodArguments
* @param symbolName
* @return a symbol representing the return value of the method
* <!-- end-user-doc -->
* @generated NOT
*/
public ISymbol call(String methodName, EList methodArguments, String symbolName)
{
ISymbol result = null;
final IType type = resolveType(getTypeSignature());
if (type != null)
{
final JDTBeanIntrospector introspector =
new JDTBeanIntrospector(type);
final IMethod callMethod =
matchMethod(methodName, methodArguments, introspector.getAllMethods());
if (callMethod != null)
{
try
{
// resolve the method's return type; don't erase parameters
final String retTypeSignature =
TypeUtil.resolveTypeSignature
(type, callMethod.getReturnType(), false) ;
final IPropertySymbol propSymbol =
SymbolFactory.eINSTANCE.createIPropertySymbol();
// TODO: there is a possible problem here for non-string keyed maps
propSymbol.setName(symbolName);
propSymbol.setReadable(true);
IJavaTypeDescriptor2 typeDesc =
SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
typeDesc.setArrayCount(Signature.getArrayCount(retTypeSignature));
// may be null
typeDesc.setType(resolveType(retTypeSignature));
typeDesc.setTypeSignatureDelegate(retTypeSignature);
propSymbol.setTypeDescriptor(typeDesc);
result = propSymbol;
}
catch (JavaModelException e)
{
JSFCommonPlugin.log(e);
// fall-through and return null result
}
}
}
return result;
}
private IMethod matchMethod(String name, List methodArguments, IMethod[] allMethods)
{
final List argSigs = convertArgsToSignatures(methodArguments);
IMethod matchedMethod = null;
for (int i = 0; i < allMethods.length; i++)
{
final IMethod method = allMethods[i];
// check for names and argument count match
if (method.getParameterTypes().length == argSigs.size()
&& method.getElementName().equals(name))
{
String[] methods = method.getParameterTypes();
// need to verify argument matches
boolean isMatched = true;
CHECK_ARGUMENTS: for (int j = 0; j < methods.length; j++)
{
if (!methods[j].equals(argSigs.get(j)))
{
// not a match
isMatched = false;
break CHECK_ARGUMENTS;
}
}
if (isMatched)
{
return method;
}
}
}
return matchedMethod;
}
private List convertArgsToSignatures(List methodArgs)
{
List args = new ArrayList();
for (final Iterator it = methodArgs.iterator(); it.hasNext();)
{
Object arg = it.next();
String className = arg.getClass().getName();
String resolvedName = Signature.createTypeSignature(className, true);
args.add(resolvedName);
}
return args;
}
/**
* @return the ITypeDescriptor for this List's element type (bound type).
* Defaults to java.lang.Object if no bounds or can't resolve bounds
*
* @generated NOT
*/
private ITypeDescriptor getBoundsTypeDescriptor(int offset)
{
IJavaTypeDescriptor2 typeDesc = null;
List typeParameters = getTypeParameterSignatures();
// if no bounds at all, then default to bounded java object
if (typeParameters.size() == 0)
{
typeDesc =
SymbolFactory.eINSTANCE.createIBoundedJavaTypeDescriptor();
typeDesc.setTypeSignatureDelegate(TypeConstants.TYPE_JAVAOBJECT);
}
else
{
// TODO: there should only be exactly one on a list...
final String elementType = (String) typeParameters.get(0);
typeDesc =
SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
typeDesc.setArrayCount(Signature.getArrayCount(elementType));
// may be null
typeDesc.setType(resolveType(elementType));
typeDesc.setTypeSignatureDelegate(elementType);
}
return typeDesc;
}
} //IBoundedListTypeDescriptorImpl