/******************************************************************************* * Copyright (c) 2006 Oracle Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cameron Bateman/Oracle - initial API and implementation * ********************************************************************************/ package org.eclipse.jst.jsf.context.symbol.internal.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; 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.TypeInfoCache; import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector; import org.eclipse.jst.jsf.common.util.JDTBeanProperty; import org.eclipse.jst.jsf.common.util.TypeUtil; import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol; import org.eclipse.jst.jsf.context.symbol.IBeanPropertySymbol; import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2; import org.eclipse.jst.jsf.context.symbol.IObjectSymbol; import org.eclipse.jst.jsf.context.symbol.IPropertySymbol; 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>IJava Type Descriptor2</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * <ul> * <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getType <em>Type</em>}</li> * <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getBeanProperties <em>Bean Properties</em>}</li> * <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getBeanMethods <em>Bean Methods</em>}</li> * <li>{@link org.eclipse.jst.jsf.context.symbol.internal.impl.IJavaTypeDescriptor2Impl#getArrayCount <em>Array Count</em>}</li> * </ul> * </p> * * @generated */ public class IJavaTypeDescriptor2Impl extends ITypeDescriptorImpl implements IJavaTypeDescriptor2 { /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @SuppressWarnings("hiding") public static final String copyright = "Copyright 2006 Oracle"; //$NON-NLS-1$ /** * The default value of the '{@link #getType() <em>Type</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getType() * @generated * @ordered */ protected static final IType TYPE_EDEFAULT = null; /** * The cached value of the '{@link #getType() <em>Type</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getType() * @generated * @ordered */ protected IType type = TYPE_EDEFAULT; /** * The default value of the '{@link #getArrayCount() <em>Array Count</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getArrayCount() * @generated * @ordered */ protected static final int ARRAY_COUNT_EDEFAULT = 0; /** * The cached value of the '{@link #getArrayCount() <em>Array Count</em>}' attribute. * <!-- begin-user-doc --> * records the array nesting of the type. IType doesn't encapsulate * array types. So if this type is an array then type will represent * the base element and this value will be > 0. If not an array, then * _arrayCount is always 0. * <!-- end-user-doc --> * @see #getArrayCount() * @generated * @ordered */ protected int arrayCount = ARRAY_COUNT_EDEFAULT; /** * The default value of the '{@link #getJdtContext() <em>Jdt Context</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getJdtContext() * @generated * @ordered */ @SuppressWarnings("hiding") protected static final IJavaElement JDT_CONTEXT_EDEFAULT = null; /** * The cached value of the '{@link #getJdtContext() <em>Jdt Context</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getJdtContext() * @generated * @ordered */ @SuppressWarnings("hiding") protected IJavaElement jdtContext = JDT_CONTEXT_EDEFAULT; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ protected IJavaTypeDescriptor2Impl() { super(); } /** * <!-- begin-user-doc --> * @return the static class * <!-- end-user-doc --> * @generated */ protected EClass eStaticClass() { return SymbolPackage.Literals.IJAVA_TYPE_DESCRIPTOR2; } /** * <!-- begin-user-doc --> * @return the JDT type descriptor; if type is an array then this type * represent's the array base type only * <!-- end-user-doc --> * @generated */ public IType getType() { return type; } /** * <!-- begin-user-doc --> * @param newType * <!-- end-user-doc --> * @generated */ public void setType(IType newType) { IType oldType = type; type = newType; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE, oldType, type)); } /** * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getInterfaceTypeSignatures() * @generated NOT */ public EList getInterfaceTypeSignatures() { EList interfaces = new BasicEList(); IType type_ = getType(); if (type_ != null) { final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance(); IType[] interfaceTypes = typeInfoCache.getCachedInterfaceTypes(type_); if (interfaceTypes == null) { interfaceTypes = typeInfoCache.cacheInterfaceTypesFor(type_); } copySignatures(interfaces, interfaceTypes); } return interfaces; } /** * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getSuperTypeSignatures() * @generated NOT */ public EList getSuperTypeSignatures() { EList interfaces = new BasicEList(); IType type_ = getType(); if (type_ != null) { final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance(); IType[] interfaceTypes = typeInfoCache.getCachedSupertypes(type_); if (interfaceTypes == null) { interfaceTypes = typeInfoCache.cacheSupertypesFor(type_); } copySignatures(interfaces, interfaceTypes); } return interfaces; } private void copySignatures(List list, IType[] types) { if (types != null) { for (int i = 0; i < types.length; i++) { final IType type_ = types[i]; final String signature = TypeUtil.getSignature(type_); if (signature != null) { list.add(signature); } } } } public EList getProperties() { return getBeanProperties(); } public EList getMethods() { return getBeanMethods(); } /** * <!-- begin-user-doc --> * @return the bean props for this java type * <!-- end-user-doc --> * @generated NOT */ public EList getBeanProperties() { TypeInfoCache typeInfoCache = TypeInfoCache.getInstance(); IBeanPropertySymbol[] properties = typeInfoCache.getCachedPropertySymbols(type); Collection propertyColl; if (properties == null) { propertyColl = getPropertiesInternal(); properties = (IBeanPropertySymbol[]) propertyColl.toArray(new IBeanPropertySymbol[propertyColl.size()]); typeInfoCache.cachePropertySymbols(type, properties); } else { propertyColl = new ArrayList(properties.length); Collections.addAll(propertyColl, (Object[])properties); } BasicEList list = new BasicEList(propertyColl); return list; } /** * <!-- begin-user-doc --> * @return the bean methods for this type * <!-- end-user-doc --> * @generated NOT */ public EList getBeanMethods() { TypeInfoCache typeInfoCache = TypeInfoCache.getInstance(); IBeanMethodSymbol[] methods = typeInfoCache.getCachedMethodSymbols(type); Collection methodColl; if (methods == null) { methodColl = getMethodsInternal(); methods = (IBeanMethodSymbol[]) methodColl.toArray(new IBeanMethodSymbol[methodColl.size()]); typeInfoCache.cacheMethodSymbols(type, methods); } else { methodColl = new ArrayList(methods.length); Collections.addAll(methodColl, (Object[])methods); } BasicEList list = new BasicEList(methodColl); return list; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public int getArrayCount() { return arrayCount; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setArrayCount(int newArrayCount) { int oldArrayCount = arrayCount; arrayCount = newArrayCount; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT, oldArrayCount, arrayCount)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public IJavaElement getJdtContext() { return jdtContext; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setJdtContext(IJavaElement newJdtContext) { IJavaElement oldJdtContext = jdtContext; jdtContext = newJdtContext; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__JDT_CONTEXT, oldJdtContext, jdtContext)); } /** * <!-- begin-user-doc --> * * Tries to load an IType for a fully resolved (i.e. starts with L not Q) * type signature using the current jdtContext. * * @return the resolved IType or null if none could be resolved. * * <!-- end-user-doc --> * @generated NOT */ public IType resolveType(String resolvedTypeSignature) { IType resolvedType = null; // we need to obtain an IJavaProject within which to resolve // the type. IJavaProject project = null; // first, see if we have an IType if (getType() != null) { // optimize: if the type sig is my type sig, then return getType() if (resolvedTypeSignature.equals(getTypeSignature())) { resolvedType = getType(); } else { project = getType().getJavaProject(); if (project != null) { resolvedType = TypeUtil.resolveType(project, resolvedTypeSignature); } } } // if not, see if a jdtContext hint has been set if (resolvedType == null && getJdtContext() != null) { resolvedType = super.resolveType(resolvedTypeSignature); } return resolvedType; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE: return getType(); case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES: return getBeanProperties(); case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS: return getBeanMethods(); case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT: return Integer.valueOf(getArrayCount()); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void eSet(int featureID, Object newValue) { switch (featureID) { case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE: setType((IType)newValue); return; case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES: getBeanProperties().clear(); getBeanProperties().addAll((Collection)newValue); return; case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS: getBeanMethods().clear(); getBeanMethods().addAll((Collection)newValue); return; case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT: setArrayCount(((Integer)newValue).intValue()); return; } super.eSet(featureID, newValue); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void eUnset(int featureID) { switch (featureID) { case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE: setType(TYPE_EDEFAULT); return; case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES: getBeanProperties().clear(); return; case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS: getBeanMethods().clear(); return; case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT: setArrayCount(ARRAY_COUNT_EDEFAULT); return; } super.eUnset(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public boolean eIsSet(int featureID) { switch (featureID) { case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE: return TYPE_EDEFAULT == null ? type != null : !TYPE_EDEFAULT.equals(type); case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_PROPERTIES: return !getBeanProperties().isEmpty(); case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__BEAN_METHODS: return !getBeanMethods().isEmpty(); case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT: return arrayCount != ARRAY_COUNT_EDEFAULT; } return super.eIsSet(featureID); } public boolean isArray() { return getArrayCount() > 0; } /** * @generated NOT */ public IObjectSymbol getArrayElement() { if (isArray()) { final String typeSignature = getTypeSignature(); final int arrayCount_ = Signature.getArrayCount(typeSignature); final String baseType = Signature.getElementType(typeSignature); final String elementTypeSignature = Signature.createArraySignature(baseType, arrayCount_-1); final IJavaTypeDescriptor2 elementTypeDesc = SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2(); final String fullyQualifiedElementType = TypeUtil.getFullyQualifiedName(baseType); IType elementType = null; try { IType myType = getType(); if (myType != null) { elementType = getType().getJavaProject() .findType(fullyQualifiedElementType); } } catch (JavaModelException e) { // suppress } if (elementType != null) { elementTypeDesc.setType(elementType); } else { elementTypeDesc.setTypeSignatureDelegate(elementTypeSignature); } elementTypeDesc.setArrayCount(Signature.getArrayCount(elementTypeSignature)); IPropertySymbol newPropertySymbol = SymbolFactory.eINSTANCE.createIPropertySymbol(); newPropertySymbol.setTypeDescriptor(elementTypeDesc); newPropertySymbol.setWritable(true); newPropertySymbol.setReadable(true); newPropertySymbol.setName(fullyQualifiedElementType); return newPropertySymbol; } return null; } /* (non-Javadoc) * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getTypeSignature() * @generated NOT */ public String getTypeSignature() { if (getType() == null) { if (eIsSet(SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE_SIGNATURE_DELEGATE)) { return getTypeSignatureDelegate(); } return null; } // make sure to array type nesting if using IType return Signature.createArraySignature( TypeUtil.getSignature(getType()), getArrayCount()); } private Collection getPropertiesInternal() { // if I'm an array then I have no bean properties if (isArray()) { return Collections.EMPTY_LIST; } final JDTBeanIntrospector introspector = new JDTBeanIntrospector(getType()); final Map<String, JDTBeanProperty> properties = introspector.getProperties(); final Collection calculatedProps = new ArrayList(properties.size()); for (final Iterator<Map.Entry<String, JDTBeanProperty>> it = properties.entrySet().iterator(); it.hasNext();) { Map.Entry<String, JDTBeanProperty> entry = it.next(); final String propertyName = entry.getKey(); final JDTBeanProperty property = entry.getValue(); final IBeanPropertySymbol workingCopy = SymbolFactory.eINSTANCE.createIBeanPropertySymbol(); workingCopy.setName(propertyName); workingCopy.setOwner(this); final IJavaTypeDescriptor2 workingCopyDesc = SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2(); workingCopy.setTypeDescriptor(workingCopyDesc); workingCopy.setReadable(property.isReadable()); workingCopy.setWritable(property.isWritable()); workingCopyDesc.setArrayCount(property.getArrayCount()); workingCopyDesc.getTypeParameterSignatures().addAll(property.getTypeParameterSignatures()); workingCopyDesc.setEnumType(property.isEnumType()); final IType newType = property.getType(); final String signature = property.getTypeSignature(); if (newType != null) { workingCopyDesc.setType(newType); } else { workingCopyDesc.setTypeSignatureDelegate(signature); } calculatedProps.add(workingCopy); } return calculatedProps; } private Collection getMethodsInternal() { JDTBeanIntrospector introspector = new JDTBeanIntrospector(getType()); IMethod[] methods = introspector.getAllMethods(); List methodSymbols = new ArrayList(); for (int i = 0; i < methods.length; i++) { IMethod method = methods[i]; try { // to be a bean method, it must not a constructor, must be public // and must not be static if (!method.isConstructor() && Flags.isPublic(method.getFlags()) && !Flags.isStatic(method.getFlags())) { String methodName = method.getElementName(); IBeanMethodSymbol workingCopy = SymbolFactory.eINSTANCE.createIBeanMethodSymbol(); workingCopy.setName(methodName); workingCopy.setOwner(this); workingCopy.setSignature(TypeUtil. resolveMethodSignature (getType(), method.getSignature())); methodSymbols.add(workingCopy); } } catch (JavaModelException jme) { // error reading meta-data. Skip to next one JSFCommonPlugin.log(jme); } } return methodSymbols; } /** * <!-- begin-user-doc --> * @return the default string rep * <!-- end-user-doc --> * @generated */ public String toString() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (type: "); //$NON-NLS-1$ result.append(type); result.append(", arrayCount: "); //$NON-NLS-1$ result.append(arrayCount); result.append(')'); return result.toString(); } } //IJavaTypeDescriptor2Impl