| /** |
| * <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 |