| /******************************************************************************* |
| * 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.core.runtime.NullProgressMonitor; |
| 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.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.ITypeHierarchy; |
| 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.provisional.util.JDTBeanIntrospector; |
| import org.eclipse.jst.jsf.common.internal.provisional.util.JDTBeanProperty; |
| import org.eclipse.jst.jsf.common.internal.provisional.util.TypeUtil; |
| import org.eclipse.jst.jsf.context.symbol.SymbolFactory; |
| import org.eclipse.jst.jsf.context.symbol.SymbolPackage; |
| import org.eclipse.jst.jsf.context.symbol.internal.provisional.IBeanMethodSymbol; |
| import org.eclipse.jst.jsf.context.symbol.internal.provisional.IBeanPropertySymbol; |
| import org.eclipse.jst.jsf.context.symbol.internal.provisional.IJavaTypeDescriptor2; |
| import org.eclipse.jst.jsf.context.symbol.internal.provisional.IObjectSymbol; |
| import org.eclipse.jst.jsf.context.symbol.internal.provisional.IPropertySymbol; |
| |
| |
| /** |
| * <!-- 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 |
| */ |
| public static final String copyright = "Copyright 2006 Oracle"; |
| |
| /** |
| * 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; |
| |
| /** |
| * <!-- 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)); |
| } |
| |
| public EList getInterfaceTypeSignatures() |
| { |
| EList interfaces = new BasicEList(); |
| |
| IType type_ = getType(); |
| |
| if (type_ != null) |
| { |
| // TODO: type hierarchy is potentially expensive, should |
| // cache once and listen for changes |
| try { |
| final ITypeHierarchy hierarchy = |
| type_.newSupertypeHierarchy(new NullProgressMonitor()); |
| final IType[] interfaceTypes = hierarchy.getAllInterfaces(); |
| copySignatures(interfaces, interfaceTypes); |
| } catch (JavaModelException e) { |
| JSFCommonPlugin.log(e); |
| } |
| |
| } |
| |
| return interfaces; |
| } |
| |
| public EList getSuperTypeSignatures() |
| { |
| EList interfaces = new BasicEList(); |
| |
| IType type_ = getType(); |
| |
| if (type_ != null) |
| { |
| // TODO: type hierarchy is potentially expensive, should |
| // cache once and listen for changes |
| try { |
| final ITypeHierarchy hierarchy = |
| type_.newSupertypeHierarchy(new NullProgressMonitor()); |
| final IType[] interfaceTypes = hierarchy.getAllSuperclasses(type_); |
| copySignatures(interfaces, interfaceTypes); |
| } catch (JavaModelException e) { |
| JSFCommonPlugin.log(e); |
| } |
| } |
| |
| return interfaces; |
| } |
| |
| |
| private void copySignatures(List list, IType[] types) |
| { |
| 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() { |
| BasicEList list = new BasicEList(); |
| list.addAll(getPropertiesInternal()); |
| return list; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * @return the bean methods for this type |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public EList getBeanMethods() { |
| BasicEList list = new BasicEList(); |
| list.addAll(getMethodsInternal()); |
| 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)); |
| } |
| |
| public boolean isArray() |
| { |
| return getArrayCount() > 0; |
| } |
| |
| /** |
| * |
| */ |
| 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 properties = introspector.getProperties(); |
| final Collection calculatedProps = new ArrayList(properties.size()); |
| |
| for (final Iterator it = properties.keySet().iterator(); it.hasNext();) |
| { |
| final String propertyName = (String) it.next(); |
| final JDTBeanProperty property = |
| (JDTBeanProperty) properties.get(propertyName); |
| |
| 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()); |
| |
| 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() |
| && (method.getFlags() & Flags.AccPublic) != 0 |
| && (method.getFlags() & Flags.AccStatic) == 0) |
| { |
| 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 --> |
| * @param featureID |
| * @param resolve |
| * @param coreType |
| * @return the value of featureID |
| * <!-- 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 new Integer(getArrayCount()); |
| } |
| return super.eGet(featureID, resolve, coreType); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * @param featureID |
| * @param newValue |
| * <!-- 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 --> |
| * @param featureID |
| * <!-- 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 --> |
| * @param featureID |
| * @return true if the feature is set |
| * <!-- 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); |
| } |
| |
| /** |
| * <!-- 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: "); |
| result.append(type); |
| result.append(", arrayCount: "); |
| result.append(arrayCount); |
| result.append(')'); |
| return result.toString(); |
| } |
| |
| } //IJavaTypeDescriptor2Impl |