Bug 569656 Cache resolved types of JSF beans to make validation faster
- JDTTypeResolver caches each resolved type of a bean type
- JDTBeanIntrospector is using JDTTypeResolver to resolve types
- JDTBeanIntrospector is cached in TypeInfoCache
- JDTBeanIntrospector caches all methods of type so that it can be
resused for properties and methods
- JDTBeanIntrospector does no longer compute type hierarchy since this
is already cached in type info cache. Super types will be provided from
there
- Use cached JDTBeanIntrospector everywhere instead of creating new
instances of it
- AnnotationSearchRequestor uses cached JDTBeanIntrospector to resolve
annotations. It has a new white list of types that it will resolve
Change-Id: Icc29fd971dec3bc833c3bf43a35dbd268a5868ef
Signed-off-by: Reto Weiss <reto.weiss@axonivy.com>
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfo.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfo.java
index 32e4027..4e4d599 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfo.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2007 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,10 +9,12 @@
*
* Contributors:
* Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy Cache resolved types
*******************************************************************************/
package org.eclipse.jst.jsf.common.internal.types;
import org.eclipse.jdt.core.IType;
+import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanPropertySymbol;
@@ -32,6 +34,7 @@
private IType[] supertypes = null;
private IType[] interfaceTypes = null;
private String[] missingSupertypeNames = null;
+ private JDTBeanIntrospector beanIntrospector = null;
/**Creates an empty TypeInfo object
*/
@@ -109,4 +112,11 @@
this.missingSupertypeNames = missingSupertypeNames;
}
+ public JDTBeanIntrospector getBeanIntrospector() {
+ return beanIntrospector;
+ }
+
+ public void setBeanIntrospector(JDTBeanIntrospector beanIntrospector) {
+ this.beanIntrospector = beanIntrospector;
+ }
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfoCache.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfoCache.java
index d7da0fe..9bcc991 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfoCache.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeInfoCache.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2009 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Oracle Corporation - initial API and implementation
+ * Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache resolved types
*******************************************************************************/
package org.eclipse.jst.jsf.common.internal.types;
@@ -36,6 +37,7 @@
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
+import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanPropertySymbol;
@@ -84,7 +86,7 @@
public static void disposeInstance(final TypeInfoCache cache)
{
if (cache != null
- && cache != instance)
+ && cache != instance)
{
JavaCore.removeElementChangedListener(cache);
@@ -181,6 +183,24 @@
return methods;
}
+
+ /**
+ * @param beanType
+ * @return cached bean introspector or null
+ */
+ public JDTBeanIntrospector getCachedBeanIntrospector(IType beanType)
+ {
+ if (beanType != null)
+ {
+ TypeInfo typeInfo = getTypeInfo(beanType);
+ if (typeInfo != null)
+ {
+ return typeInfo.getBeanIntrospector();
+ }
+ }
+ return null;
+ }
+
/**Returns the cached supertypes for a given type. Will return null if no supertypes
* have been cached for this type or if the type/something it depends on has changed since
* then.
@@ -189,18 +209,16 @@
* @see TypeInfoCache#cacheSupertypesFor(IType)
*/
public synchronized IType[] getCachedSupertypes(IType type) {
- IType[] types = null;
-
if (type != null)
{
TypeInfo typeInfo = getTypeInfo(type);
if (typeInfo != null)
{
- types = typeInfo.getSupertypes();
+ return typeInfo.getSupertypes();
}
}
- return types;
+ return null;
}
/**Returns the cached implemented interfaces for a given type. Will return null if no interfaces
@@ -253,6 +271,22 @@
}
}
}
+
+ /**
+ * Chaches the given bean introspector for the given type
+ * @param beanType
+ * @param beanIntrospector
+ */
+ public void cacheBeanIntrospector(IType beanType, JDTBeanIntrospector beanIntrospector)
+ {
+ if (beanType != null)
+ {
+ TypeInfo typeInfo = getOrCreateTypeInfo(beanType);
+ if (typeInfo != null) {
+ typeInfo.setBeanIntrospector(beanIntrospector);
+ }
+ }
+ }
/**Caches the supertypes for the given type. The supertypes will be calculated (and also returned)
* by this method.
@@ -601,5 +635,4 @@
}
}
}
-
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanIntrospector.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanIntrospector.java
index f5411ac..47616d9 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanIntrospector.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanIntrospector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 Oracle Corporation.
+ * Copyright (c) 2007, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy Cache resolved types
*
********************************************************************************/
package org.eclipse.jst.jsf.common.util;
@@ -21,14 +22,13 @@
import java.util.Map;
import java.util.Map.Entry;
-import org.eclipse.core.runtime.NullProgressMonitor;
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.types.TypeInfoCache;
/**
* A class that does bean introspection on a JDT IType
@@ -44,176 +44,242 @@
* @author cbateman
*
*/
-public class JDTBeanIntrospector
+public class JDTBeanIntrospector
{
- private final static String GET_PREFIX = "get"; //$NON-NLS-1$
- private final static String SET_PREFIX = "set"; //$NON-NLS-1$
- private final static String IS_PREFIX = "is"; //$NON-NLS-1$
-
- private final IType _type;
- private final HashMap<String, String> _resolvedSignatures;
+ private final static IType[] EMPTY_SUPER_TYPES = new IType[0];
+ private final static String GET_PREFIX = "get"; //$NON-NLS-1$
+ private final static String SET_PREFIX = "set"; //$NON-NLS-1$
+ private final static String IS_PREFIX = "is"; //$NON-NLS-1$
+ private final static IMethod[] EMTPY_METHODS = new IMethod[0];
- /**
- * @param type
- */
- public JDTBeanIntrospector(IType type)
- {
- _type = type;
- _resolvedSignatures = new HashMap<String, String>();
- }
-
- /**
- * @return an map of all properties with the property names
- * as keys and the values being JDTBeanProperty objects representing
- * the properties.
- */
- public Map<String, JDTBeanProperty> getProperties()
- {
- _resolvedSignatures.clear();
+ private final IType type;
+ private final JDTTypeResolver typeResolver;
+ private IMethod[] methods;
+ private final IType[] superTypes;
- final Map<String, JDTBeanProperty> propertiesWorkingCopy =
- new HashMap<String, JDTBeanProperty>();
- final IMethod[] methods = getAllMethods();
-
- for (int i = 0; i < methods.length; i++)
- {
- final IMethod method = methods[i];
-
- try
- {
- processPropertyMethod(method, propertiesWorkingCopy);
- }
- catch (JavaModelException jme)
- {
- // log and then proceed to next method
- JSFCommonPlugin.log(jme, "Error processing IMethod for bean property info"); //$NON-NLS-1$
- }
- }
-
- final Map properties = new HashMap();
-
- for (Entry<String, JDTBeanProperty> entry : propertiesWorkingCopy.entrySet())
- {
- final String key = entry.getKey();
- JDTBeanPropertyWorkingCopy wcopy = (JDTBeanPropertyWorkingCopy) entry.getValue();
- properties.put(key, wcopy.toValueObject());
- }
-
- return properties;
- }
-
- private void processPropertyMethod(IMethod method, Map<String, JDTBeanProperty> properties) throws JavaModelException
- {
- // 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())
- || _type.isInterface())
- && !Flags.isStatic(method.getFlags()))
- {
- final String methodName = method.getElementName();
- final String returnType = method.getReturnType();
-
- // either starts with get or is boolean and starts with is
-
- // is access must start with 'is', have a boolean return type and no parameters
- final boolean startsWithIs = methodName.startsWith(IS_PREFIX)
- && Signature.SIG_BOOLEAN.equals(returnType)
- && method.getNumberOfParameters() == 0
- && methodName.length() > IS_PREFIX.length();
-
- // get accessor must start with 'get', have no parameters and return non-void
- final boolean startsWithGet = (methodName.startsWith(GET_PREFIX)
- && method.getNumberOfParameters() == 0)
- && !Signature.SIG_VOID.equals(returnType)
- && methodName.length() > GET_PREFIX.length();
-
- // mutator must start with 'set' and have one parameter and a void return type
- final boolean startsWithSet = methodName.startsWith(SET_PREFIX)
- && method.getNumberOfParameters() == 1
- && Signature.SIG_VOID.equals(returnType)
- && methodName.length() > SET_PREFIX.length();
-
- if (startsWithGet || startsWithSet || startsWithIs)
- {
- final String propertyName =
- Introspector.decapitalize(methodName.substring(startsWithIs ? 2 : 3));
-
- JDTBeanPropertyWorkingCopy workingCopy =
- (JDTBeanPropertyWorkingCopy) properties.get(propertyName);
-
- if (workingCopy == null)
- {
- workingCopy = new JDTBeanPropertyWorkingCopy(_type, _resolvedSignatures);
- properties.put(propertyName, workingCopy);
- }
-
- if (startsWithIs)
- {
- workingCopy.setIsGetter(method);
- }
- else if (startsWithGet)
- {
- workingCopy.setGetter(method);
- }
- else if (startsWithSet)
- {
- workingCopy.addSetter(method);
- }
- }
- }
- }
-
- /**
- * @return all methods for the type including inherited ones
- */
- public IMethod[] getAllMethods()
- {
- IMethod[] methods = new IMethod[0];
-
- try
- {
- // type not resolved so don't proceed
- if (_type != null)
- {
- // TODO: type hierarchy is potentially expensive, should
- // cache once and listen for changes
- ITypeHierarchy hierarchy = _type.newSupertypeHierarchy(new NullProgressMonitor());
-
- methods = getAllMethods(hierarchy, _type);
- }
- }
- catch(JavaModelException jme)
- {
- JSFCommonPlugin.log(jme, "Error getting type information for bean"); //$NON-NLS-1$
- }
-
- return methods;
- }
-
- /**
- * @param typeHierarchy
- * @param type
- * @return all methods of the type and it's super types
- */
- private static IMethod[] getAllMethods(final ITypeHierarchy typeHierarchy, final IType type)
+ /**
+ * @param type
+ * @return cached JDT bean introspector for the given type
+ */
+ public static JDTBeanIntrospector forType(IType type)
+ {
+ TypeInfoCache cache = TypeInfoCache.getInstance();
+ JDTBeanIntrospector beanIntrospector = cache.getCachedBeanIntrospector(type);
+ if (beanIntrospector != null)
{
- final List<IMethod> methods = new ArrayList<IMethod>();
- final IType[] superTypes = typeHierarchy.getAllSuperclasses(type);
- final IType[] closure = new IType[superTypes.length+1];
- closure[0] = type;
- System.arraycopy(superTypes, 0, closure, 1, superTypes.length);
-
- for (int i = 0; i < closure.length; i++)
- {
- try {
- final IType superType = closure[i];
- methods.addAll(Arrays.asList(superType.getMethods()));
- } catch (JavaModelException e) {
- JSFCommonPlugin.log(e, "Error getting super type information for bean"); //$NON-NLS-1$
- }
- }
-
- return methods.toArray(new IMethod[methods.size()]);
+ return beanIntrospector;
}
+ IType[] superTypes = cache.getCachedSupertypes(type);
+ if (superTypes == null)
+ {
+ superTypes = cache.cacheSupertypesFor(type);
+ }
+ beanIntrospector = new JDTBeanIntrospector(type, superTypes);
+ cache.cacheBeanIntrospector(type, beanIntrospector);
+ return beanIntrospector;
+ }
+
+ /**
+ * @param type
+ */
+ private JDTBeanIntrospector(IType type, IType[] superTypes)
+ {
+ this.type = type;
+ this.superTypes = superTypes;
+ if (superTypes == null)
+ {
+ superTypes = EMPTY_SUPER_TYPES;
+ }
+
+ this.typeResolver = new JDTTypeResolver(type, superTypes);
+ }
+
+ /**
+ * @return an map of all properties with the property names as keys and the
+ * values being JDTBeanProperty objects representing the properties.
+ */
+ public Map<String, JDTBeanProperty> getProperties()
+ {
+ final Map<String, JDTBeanPropertyWorkingCopy> propertiesWorkingCopy = new HashMap<String, JDTBeanPropertyWorkingCopy>();
+ final IMethod[] mthds = methods();
+
+ for (int i = 0; i < mthds.length; i++)
+ {
+ try
+ {
+ processPropertyMethod(mthds[i], propertiesWorkingCopy);
+ }
+ catch (JavaModelException jme)
+ {
+ // log and then proceed to next method
+ JSFCommonPlugin.log(jme, "Error processing IMethod for bean property info"); //$NON-NLS-1$
+ }
+ }
+
+ final Map<String, JDTBeanProperty> properties = new HashMap<String, JDTBeanProperty>();
+
+ for (Entry<String, JDTBeanPropertyWorkingCopy> entry : propertiesWorkingCopy.entrySet())
+ {
+ final String key = entry.getKey();
+ JDTBeanPropertyWorkingCopy wcopy = entry.getValue();
+ properties.put(key, wcopy.toValueObject());
+ }
+
+ return properties;
+ }
+
+ private void processPropertyMethod(IMethod method, Map<String, JDTBeanPropertyWorkingCopy> properties)
+ throws JavaModelException
+ {
+ // 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())
+ || type.isInterface())
+ && !Flags.isStatic(method.getFlags()))
+ {
+ final String methodName = method.getElementName();
+ final String returnType = method.getReturnType();
+
+ // either starts with get or is boolean and starts with is
+
+ // is access must start with 'is', have a boolean return type and no
+ // parameters
+ final boolean startsWithIs = methodName.startsWith(IS_PREFIX)
+ && Signature.SIG_BOOLEAN.equals(returnType)
+ && method.getNumberOfParameters() == 0
+ && methodName.length() > IS_PREFIX.length();
+
+ // get accessor must start with 'get', have no parameters and return
+ // non-void
+ final boolean startsWithGet = (methodName.startsWith(GET_PREFIX)
+ && method.getNumberOfParameters() == 0)
+ && !Signature.SIG_VOID.equals(returnType)
+ && methodName.length() > GET_PREFIX.length();
+
+ // mutator must start with 'set' and have one parameter and a void return
+ // type
+ final boolean startsWithSet = methodName.startsWith(SET_PREFIX)
+ && method.getNumberOfParameters() == 1
+ && Signature.SIG_VOID.equals(returnType)
+ && methodName.length() > SET_PREFIX.length();
+
+ if (startsWithGet || startsWithSet || startsWithIs)
+ {
+ final String propertyName = Introspector.decapitalize(methodName.substring(startsWithIs ? 2 : 3));
+
+ JDTBeanPropertyWorkingCopy workingCopy = properties.get(propertyName);
+
+ if (workingCopy == null)
+ {
+ workingCopy = new JDTBeanPropertyWorkingCopy(type, typeResolver, propertyName);
+ properties.put(propertyName, workingCopy);
+ }
+
+ if (startsWithIs)
+ {
+ workingCopy.setIsGetter(method);
+ }
+ else if (startsWithGet)
+ {
+ workingCopy.setGetter(method);
+ }
+ else if (startsWithSet)
+ {
+ workingCopy.addSetter(method);
+ }
+ }
+ }
+ }
+
+ /**
+ * @return methods
+ */
+ public JDTBeanMethod[] getMethods()
+ {
+ List<JDTBeanMethod> beanMethods = new ArrayList<JDTBeanMethod>();
+ for (IMethod method : methods())
+ {
+ JDTBeanMethod beanMethod = toBeanMethod(method);
+ if (beanMethod != null)
+ {
+ beanMethods.add(beanMethod);
+ }
+ }
+ return beanMethods.toArray(new JDTBeanMethod[beanMethods.size()]);
+ }
+
+ private JDTBeanMethod toBeanMethod(IMethod method)
+ {
+ try
+ {
+ String resMethodSigErased = typeResolver.resolveMethodEraseTypeParams(method.getSignature());
+ String resMethodSigUnerased = typeResolver.resolveMethodKeepTypeParams(method.getSignature());
+ return new JDTBeanMethod(method, resMethodSigErased, resMethodSigUnerased);
+ }
+ catch(JavaModelException jme)
+ {
+ // log and then proceed to next method
+ JSFCommonPlugin.log(jme, "Error processing IMethod for bean method info"); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ * @return all methods for the type including inherited ones
+ */
+ private IMethod[] methods()
+ {
+ // type not resolved so don't proceed
+ if (type == null)
+ {
+ return EMTPY_METHODS;
+ }
+ if (methods == null)
+ {
+ methods = allMethods();
+ }
+ return methods;
+ }
+
+ /**
+ * @param typeHierarchy
+ * @param type
+ * @return all methods of the type and it's super types
+ */
+ private IMethod[] allMethods()
+ {
+ final List<IMethod> allMethods = new ArrayList<IMethod>();
+ final IType[] closure = new IType[superTypes.length + 1];
+ closure[0] = type;
+ System.arraycopy(superTypes, 0, closure, 1, superTypes.length);
+
+ for (IType t : closure)
+ {
+ try
+ {
+ allMethods.addAll(Arrays.asList(t.getMethods()));
+ }
+ catch (JavaModelException e)
+ {
+ JSFCommonPlugin.log(e, "Error getting super type information for bean"); //$NON-NLS-1$
+ }
+ }
+
+ return allMethods.toArray(new IMethod[allMethods.size()]);
+ }
+
+ /**
+ * @param simpleName simple type name
+ * @return full qualified type name or null
+ */
+ public String resolveFullQualifiedTypeName(String simpleName)
+ {
+ IType resolvedType = typeResolver.resolveTypeName(simpleName);
+ if (resolvedType == null)
+ {
+ return null;
+ }
+ return resolvedType.getFullyQualifiedName();
+ }
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanMethod.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanMethod.java
new file mode 100644
index 0000000..9d1edbd
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanMethod.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2020, 2021 Axon Ivy.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Reto Weiss/Axon Ivy Cache resolved types
+ *
+ ********************************************************************************/
+package org.eclipse.jst.jsf.common.util;
+
+
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+
+/**
+ * Represents a single bean method backed by JDT data
+ * @author rwei
+ * @since 27.11.2020
+ */
+public class JDTBeanMethod
+{
+ private final IMethod method;
+ private final String resolvedMethodSignatureErased;
+ private final String resolvedMethodSignatureUnerased;
+
+ JDTBeanMethod(IMethod method, String resolvedMethodSignatureErased, String resolvedMethodSignatureUnerased)
+ {
+ this.method = method;
+ this.resolvedMethodSignatureErased = resolvedMethodSignatureErased;
+ this.resolvedMethodSignatureUnerased = resolvedMethodSignatureUnerased;
+ }
+
+ /**
+ * @return type that declares this method
+ */
+ public IType getDeclaringType()
+ {
+ return method.getDeclaringType();
+ }
+
+ /**
+ * @return jdt method that is behind this bean method
+ */
+ public IMethod getMethod()
+ {
+ return method;
+ }
+
+ /**
+ * @return method name
+ */
+ public String getElementName()
+ {
+ return method.getElementName();
+ }
+
+ /**
+ * @return true if method is a constructor
+ * @throws JavaModelException
+ */
+ public boolean isConstructor() throws JavaModelException
+ {
+ return method.isConstructor();
+ }
+
+ /**
+ * @return flags
+ * @throws JavaModelException
+ */
+ public int getFlags() throws JavaModelException
+ {
+ return method.getFlags();
+ }
+
+ /**
+ * @return method signature resolved (e.g. L signatures only no unresolved signatures with Q) and erased (no type parameters)
+ */
+ public String getResolvedSignatureErased()
+ {
+ return resolvedMethodSignatureErased;
+ }
+
+ /**
+ * @return parameters types unresolved (e.g. may contain Q signatures) and unerased (with type parameters)
+ */
+ public String[] getUnresolvedParameterTypesUnerased()
+ {
+ return method.getParameterTypes();
+ }
+
+ /**
+ * @return paramters types resolved (e.g. L signatures only no unresolved signatures with Q) and unerased (with type parameters)
+ */
+ public String[] getResolvedParameterTypesUnerased()
+ {
+ return Signature.getParameterTypes(resolvedMethodSignatureUnerased);
+ }
+
+ /**
+ * @return returns type resolved (e.g. L signatures only no unresolved signatures with Q) and unerased (with type parameters)
+ */
+ public String getResolvedReturnTypeUnerased()
+ {
+ return Signature.getReturnType(resolvedMethodSignatureUnerased);
+ }
+
+ /**
+ * @return return type unresolved (e.g Q signatures) and unerased (with type parameters)
+ * @throws JavaModelException
+ */
+ public String getUnresolvedReturnTypeUnerased() throws JavaModelException
+ {
+ return method.getReturnType();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "JDTBeanMethod [name="+getElementName()+ //$NON-NLS-1$
+ "erasedSignature="+resolvedMethodSignatureErased+ //$NON-NLS-1$
+ "unerasedSignature="+resolvedMethodSignatureUnerased+ //$NON-NLS-1$
+ "]"; //$NON-NLS-1$
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanProperty.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanProperty.java
index ec3d49d..3b26475 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanProperty.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanProperty.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Oracle Corporation.
+ * Copyright (c) 2007, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,18 +9,16 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy Cache resolved types
*
********************************************************************************/
package org.eclipse.jst.jsf.common.util;
-import java.util.ArrayList;
import java.util.List;
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;
/**
* Represents a single bean property backed by JDT data
@@ -30,226 +28,125 @@
* @author cbateman
*
*/
-public class JDTBeanProperty
+public class JDTBeanProperty
{
- /**
- * the IMethod for the accessor (either is or get)
- */
- private IMethod _getter;
-
- /**
- * the IMethod for a "set" accessor method
- */
- private IMethod _setter;
+ private final IType type;
+ private final String typeSignature;
+ private final List<String> typeParameterSignatures;
+ private final IMethod getter;
+ private final IMethod setter;
+ private final String propertyName;
- /**
- * The IType that this property belongs to
- */
- protected final IType _type;
-
- /**
- * @param type
- */
- protected JDTBeanProperty(IType type)
- {
- _type = type;
- }
+ JDTBeanProperty(String propertyName, IType type, String typeSignature, List<String> typeParameterSignatures, IMethod getter, IMethod setter)
+ {
+ this.propertyName = propertyName;
+ this.type = type;
+ this.typeSignature = typeSignature;
+ this.typeParameterSignatures = typeParameterSignatures;
+ this.getter = getter;
+ this.setter = setter;
+ }
- /**
- * @return true if this property is readable
- */
- public boolean isReadable()
- {
- return _getter != null;
- }
-
- /**
- * @return true if this property is writable
- */
- public boolean isWritable()
- {
- return _setter != null;
- }
-
-
- /**
- * @return the get accessor IMethod or null if none
- */
- public IMethod getGetter() {
- return _getter;
- }
+ /**
+ * @return true if property can be read
+ */
+ public boolean isReadable()
+ {
+ return getter != null;
+ }
-
-
- /**
- * Set the get accessor IMethod
- * @param getter -- may be null to indicate none
- */
- void setGetter(IMethod getter) {
- _getter = getter;
- }
+ /**
+ * @return true if property can be written
+ */
+ public boolean isWritable()
+ {
+ return setter != null;
+ }
+ /**
+ * @return JDT getter method
+ */
+ public IMethod getGetter()
+ {
+ return getter;
+ }
- /**
- * @return the set mutator IMethod or null if none
- */
- public IMethod getSetter() {
- return _setter;
- }
+ /**
+ * @return JDT setter metod
+ */
+ public IMethod getSetter()
+ {
+ return setter;
+ }
- /**
- * @param setter
- */
- void setSetter(IMethod setter) {
- _setter = setter;
- }
-
- /**
- * @return the IType for this property's type or null if it
- * cannot determined. Note that null does not necessarily indicate an error
- * since some types like arrays of things do not have corresponding JDT IType's
- * If typeSignature represents an array, the base element IType is returned
- * if possible
- */
- public IType getType()
- {
- final String typeSignature = Signature.getElementType(getTypeSignature());
- return TypeUtil.resolveType(_type, typeSignature);
- }
-
- /**
- * @return the number of array nesting levels in typeSignature.
- * Returns 0 if not an array.
- */
- public int getArrayCount()
- {
- final String sig = getTypeSignature();
- if (sig == null)
- return 0;
- return Signature.getArrayCount(sig);
- }
-
- /**
- * @return true if property is an enum type, false otherwise or if cannot be resolved
- */
- public boolean isEnumType()
- {
- return TypeUtil.isEnumType(getType());
- }
-
- /**
- * Fully equivalent to:
- *
- * getTypeSignature(true)
- *
- * @return the fully resolved (if possible) type signature for
- * the property or null if unable to determine.
- *
- * NOTE: this is the "type erasure" signature, so any type parameters
- * will be removed and only the raw type signature will be returned.
- */
- public String getTypeSignature()
- {
- return getTypeSignature(true);
- }
-
-
- /**
- * @param eraseTypeParameters if true, the returned type has type parameters
- * erased. If false, template types are resolved.
- *
- * @see org.eclipse.jst.jsf.common.util.TypeUtil#resolveTypeSignature(IType, String, boolean)
- * for more information on how specific kinds of unresolved generics are resolved
- *
- * @return the fully resolved (if possible) type signature for
- * the property or null if unable to determine.
- */
- public String getTypeSignature(boolean eraseTypeParameters)
- {
- try
- {
- String unResolvedSig = getUnresolvedType();
- return TypeUtil.resolveTypeSignature(_type, unResolvedSig, eraseTypeParameters);
- }
- catch (JavaModelException jme)
- {
- JSFCommonPlugin.log(jme, "Error resolving bean property type signature"); //$NON-NLS-1$
- return null;
- }
- }
-
- /**
- * For example, if this property was formed from: List<String> getListOfStrings()
- * then the list would consist of the signature "Ljava.lang.String;". All
- * nested type paramters are resolved
- *
- * @see org.eclipse.jst.jsf.common.util.TypeUtil#resolveTypeSignature(IType, String, boolean)
- * for more information on how specific kinds of unresolved generics are resolved
- *
- * @return a list of type signatures (fully resolved if possible)
- * of this property's bounding type parameters.
- */
- public List<String> getTypeParameterSignatures()
- {
- List<String> signatures = new ArrayList<String>();
-
- try
- {
- final String[] typeParameters = Signature.getTypeArguments(getUnresolvedType());
- //System.err.println(getUnresolvedType());
- for (String parameter : typeParameters)
- {
- //System.out.println(parameter);
- signatures.add(TypeUtil.resolveTypeSignature(_type, parameter, false));
- }
- }
- catch (JavaModelException jme)
- {
- JSFCommonPlugin.log(jme, "Error resolving bean property type signature"); //$NON-NLS-1$
- // fall-through and return empty array
- }
+ /**
+ * @return the IType for this property's type or null if it cannot determined.
+ * Note that null does not necessarily indicate an error since some
+ * types like arrays of things do not have corresponding JDT IType's
+ * If typeSignature represents an array, the base element IType is
+ * returned if possible
+ */
+ public IType getType()
+ {
+ return type;
+ }
- return signatures;
- }
+ /**
+ * @return the number of array nesting levels in typeSignature. Returns 0 if
+ * not an array.
+ */
+ public int getArrayCount()
+ {
+ final String sig = getTypeSignature();
+ if (sig == null)
+ return 0;
+ return Signature.getArrayCount(sig);
+ }
-// public Map<String, String> getTypeParameterSignatureMap()
-// {
-// Map<String, String> signatures = new HashMap<String, String>();
-//
-// try
-// {
-// final String[] typeParameters = Signature.getTypeArguments(getUnresolvedType());
-//
-// for (String parameter : typeParameters)
-// {
-// signatures.add(TypeUtil.resolveTypeSignature(_type, parameter, false));
-// }
-// }
-// catch (JavaModelException jme)
-// {
-// JSFCommonPlugin.log(jme, "Error resolving bean property type signature"); //$NON-NLS-1$
-// // fall-through and return empty array
-// }
-//
-// return signatures;
-// }
-
- private String getUnresolvedType() throws JavaModelException
- {
- String typeSig = null;
-
- // first decide which method to use; getter always gets precendence
- if (_getter != null)
- {
- typeSig = _getter.getReturnType();
- }
- // TODO: if no getter or setter could we have been created?
- // use setter
- else
- {
- typeSig = _setter.getParameterTypes()[0];
- }
-
- return typeSig;
- }
+ /**
+ * @return true if property is an enum type, false otherwise or if cannot be
+ * resolved
+ */
+ public boolean isEnumType()
+ {
+ return TypeUtil.isEnumType(getType());
+ }
+
+ /**
+ * Fully equivalent to:
+ *
+ * getTypeSignature(true)
+ *
+ * @return the fully resolved (if possible) type signature for the property or
+ * null if unable to determine.
+ *
+ * NOTE: this is the "type erasure" signature, so any type parameters
+ * will be removed and only the raw type signature will be returned.
+ */
+ public String getTypeSignature()
+ {
+ return typeSignature;
+ }
+
+ /**
+ * For example, if this property was formed from: List<String>
+ * getListOfStrings() then the list would consist of the signature
+ * "Ljava.lang.String;". All nested type paramters are resolved
+ *
+ * @return a list of type signatures (fully resolved if possible) of this
+ * property's bounding type parameters.
+ */
+ public List<String> getTypeParameterSignatures()
+ {
+ return typeParameterSignatures;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "JDTBeanProperty [name="+propertyName+ //$NON-NLS-1$
+ " typeSignature="+typeSignature+ //$NON-NLS-1$
+ " typeParameterSignatures "+typeParameterSignatures+ //$NON-NLS-1$
+ "]"; //$NON-NLS-1$
+ }
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanPropertyWorkingCopy.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanPropertyWorkingCopy.java
index 14ef80f..aa06b55 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanPropertyWorkingCopy.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTBeanPropertyWorkingCopy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2010 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,18 +9,19 @@
*
* Contributors:
* Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy Cache resolved types
*******************************************************************************/
package org.eclipse.jst.jsf.common.util;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
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;
/**
@@ -31,165 +32,154 @@
* @author cbateman
*
*/
-public class JDTBeanPropertyWorkingCopy extends JDTBeanProperty
+public class JDTBeanPropertyWorkingCopy
{
- private final List _setters;
-
- /**
- * the IMethod for the boolean "is" accessor method
- */
- private IMethod _isGetter;
+ private final List<IMethod> setters = new ArrayList<IMethod>();
+ private IMethod isGetter;
+ private IMethod getter;
+ private final IType type;
+ private final JDTTypeResolver typeResolver;
+ private final String propertyName;
- private final Map<String, String> _resolvedSignatureMap;
-
- /**
- * @param type
- * @param resolvedSignatureMap
- */
- public JDTBeanPropertyWorkingCopy(IType type, Map<String, String> resolvedSignatureMap)
- {
- super(type);
- _setters = new ArrayList();
- _resolvedSignatureMap = resolvedSignatureMap;
- }
- /**
- * Constructor
- * @param type
- */
- public JDTBeanPropertyWorkingCopy(IType type)
- {
- super(type);
- _setters = new ArrayList();
- _resolvedSignatureMap = new HashMap<String, String>();
- }
-
- /**
- * @return the bean properties spawned from this working copy
- * Normally, there is only one property in the array, however,
- * since this working copy represents all properties with the same
- * name, there could be multiple properties since setters can
- * be overloaded by name and could result in zero or one readable
- * properties plus zero or more write-only properties with the same
- * name. I can't see anywhere in the spec that covers this
- * boundary case
- */
- public JDTBeanProperty toValueObject()
- {
- // if the isGetter is present that it takes precedence
- // over the the normal getter
- IMethod getter = getIsGetter() != null ?
- getIsGetter() : getGetter();
- IMethod matchedSetter = null;
+ /**
+ * @param type
+ * @param typeResolver
+ * @param propertyName
+ */
+ public JDTBeanPropertyWorkingCopy(IType type, JDTTypeResolver typeResolver, String propertyName)
+ {
+ this.type = type;
+ this.typeResolver = typeResolver;
+ this.propertyName = propertyName;
+ }
- if (getter != null)
- {
- matchedSetter = determineMatchedSetter(getter);
- }
- // if there's no getter than pick any setter: there
- // are bigger problem when there's no getter than
- // ambiguous setters
- else if (_setters.size() > 0)
- {
- matchedSetter = (IMethod) _setters.get(0);
- }
-
- JDTBeanProperty beanProp = new JDTBeanProperty(_type);
- beanProp.setGetter(getter);
- beanProp.setSetter(matchedSetter);
- return beanProp;
-
- }
-
- private IMethod determineMatchedSetter(IMethod getter)
- {
- IMethod matchedSetter = null;
-
- // if there are no setters, there is no point in proceeding
- if (_setters.size() < 1)
- {
- return null;
- }
+ /**
+ * @param getter
+ */
+ public void setGetter(IMethod getter)
+ {
+ this.getter = getter;
+ }
- try
- {
- final String getterSig = getResolvedSignature(_type, getter.getReturnType());
- FIND_MATCHING_SETTER:for
- (final Iterator it = _setters.iterator(); it.hasNext();)
- {
- final IMethod setter = (IMethod) it.next();
- assert (setter.getNumberOfParameters() == 1);
- final String paramSig =
- getResolvedSignature
- (_type,setter.getParameterTypes()[0]);
-
- if (paramSig.equals(getterSig))
- {
- // we've found our match since only one
- // setter with the same name as the getter
- // can have the same matching type for a
- // single arg method
- matchedSetter = setter;
- break FIND_MATCHING_SETTER;
- }
- }
- }
- catch (JavaModelException jme)
- {
- JSFCommonPlugin.log(jme, "Error determining getter return type, bean properties analysis may be inaccurate"); //$NON-NLS-1$
- }
+ /**
+ * @param isGetter
+ */
+ public void setIsGetter(IMethod isGetter)
+ {
+ this.isGetter = isGetter;
+ }
- return matchedSetter;
- }
-
- //@Override
- public void setGetter(IMethod getter) {
- super.setGetter(getter);
- }
-
- /**
- * @param isGetter
- */
- public void setIsGetter(IMethod isGetter) {
- _isGetter = isGetter;
- }
-
- /**
- * @param setter
- */
- public void addSetter(IMethod setter) {
- if (setter != null
- && setter.getNumberOfParameters() == 1)
- {
- _setters.add(setter);
- }
- }
-
- /**
- * Not supported on working copy. This is synthetically generated
- * on toValueObject()
- * @return nothing; throws exception
- */
- public final IMethod getSetter()
+ /**
+ * @param setter
+ */
+ public void addSetter(IMethod setter)
+ {
+ if (setter != null
+ && setter.getNumberOfParameters() == 1)
{
- throw new UnsupportedOperationException("Setter not calculated in working copy. Call toValueObject().getSetter()"); //$NON-NLS-1$
+ setters.add(setter);
}
-
- /**
- * @return the "is" getter method or null if not found
- */
- public IMethod getIsGetter() {
- return _isGetter;
- }
-
- private String getResolvedSignature(final IType type, final String unresolved)
- {
- String resolved = _resolvedSignatureMap.get(unresolved);
-
- if (resolved == null)
- {
- resolved = TypeUtil.resolveTypeSignature(_type, unresolved);
- _resolvedSignatureMap.put(unresolved, resolved);
- }
- return resolved;
- }
+ }
+
+ /**
+ * @return the bean properties spawned from this working copy Normally, there
+ * is only one property in the array, however, since this working copy
+ * represents all properties with the same name, there could be
+ * multiple properties since setters can be overloaded by name and
+ * could result in zero or one readable properties plus zero or more
+ * write-only properties with the same name. I can't see anywhere in
+ * the spec that covers this boundary case
+ */
+ public JDTBeanProperty toValueObject()
+ {
+ IMethod choosenGetter = isGetter != null ? isGetter : getter;
+ IMethod choosenSetter = chooseSetter(choosenGetter);
+ String unresolvedTypeSig = getUnresolvedType(choosenGetter, choosenSetter);
+ if (unresolvedTypeSig == null)
+ {
+ return new JDTBeanProperty(propertyName, null, null, Collections.EMPTY_LIST, choosenGetter, choosenSetter);
+ }
+ String resolvedTypeSig = typeResolver.resolveEraseTypeParams(unresolvedTypeSig);
+ IType resolvedType = resolveType(resolvedTypeSig);
+ List<String> parameterizedTypeSignatures = getParameterizedTypeSignature(unresolvedTypeSig);
+ return new JDTBeanProperty(
+ propertyName,
+ resolvedType,
+ resolvedTypeSig,
+ parameterizedTypeSignatures,
+ choosenGetter,
+ choosenSetter);
+ }
+
+ private IMethod chooseSetter(IMethod choosenGetter)
+ {
+ if (choosenGetter != null)
+ {
+ return determineMatchedSetter(choosenGetter);
+ }
+ else if (! setters.isEmpty())
+ {
+ return setters.get(0);
+ }
+ return null;
+ }
+
+ private IMethod determineMatchedSetter(IMethod choosenGetter)
+ {
+ if (setters.isEmpty())
+ {
+ return null;
+ }
+
+ final String getterSig = typeResolver.resolveEraseTypeParams(getUnresolvedType(choosenGetter, null));
+ if (getterSig == null)
+ {
+ return null;
+ }
+ for (final Iterator it = setters.iterator(); it.hasNext();)
+ {
+ final IMethod setter = (IMethod) it.next();
+ assert (setter.getNumberOfParameters() == 1);
+ final String paramSig = typeResolver.resolveEraseTypeParams(setter.getParameterTypes()[0]);
+
+ if (paramSig.equals(getterSig))
+ {
+ return setter;
+ }
+ }
+ return null;
+ }
+
+ private static String getUnresolvedType(IMethod choosenGetter, IMethod choosenSetter)
+ {
+ try
+ {
+ if (choosenGetter != null)
+ {
+ return choosenGetter.getReturnType();
+ }
+ return choosenSetter.getParameterTypes()[0];
+ }
+ catch (JavaModelException jme)
+ {
+ JSFCommonPlugin.log(jme, "Error resolving bean property type signature"); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ private IType resolveType(String resolvedTypeSig)
+ {
+ final String typeSig = Signature.getElementType(resolvedTypeSig);
+ return TypeUtil.resolveType(type, typeSig);
+ }
+
+ private List<String> getParameterizedTypeSignature(String unresolvedTypeSignature)
+ {
+ List<String> typeSig = new ArrayList<String>();
+ for (String typeArg : Signature.getTypeArguments(unresolvedTypeSignature))
+ {
+ typeSig.add(typeResolver.resolveKeepTypeParams(typeArg));
+ }
+ return typeSig;
+ }
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTTypeResolver.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTTypeResolver.java
new file mode 100644
index 0000000..5f7e69b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/JDTTypeResolver.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2020, 2021 Axon Ivy.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Reto Weiss/Axon Ivy Cache resolved types
+ *
+ ********************************************************************************/
+package org.eclipse.jst.jsf.common.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
+
+/**
+ * Resolves types of a type and caches them
+ * @author rwei
+ * @since 27.11.2020
+ */
+public class JDTTypeResolver
+{
+ private final Map<String, IType> resolvedTypes = new HashMap<String, IType>();
+ private final IType type;
+ private final IType[] superTypes;
+
+ /**
+ * Constructor
+ * @param type
+ * @param superTypes
+ */
+ public JDTTypeResolver(IType type, IType[] superTypes)
+ {
+ this.type = type;
+ this.superTypes = superTypes;
+ }
+
+ /**
+ * @param unresolvedSignature
+ * @return resolved method signatures with erased type parameters
+ */
+ public String resolveMethodEraseTypeParams(String unresolvedSignature)
+ {
+ return resolveMethod(unresolvedSignature, TypeParameters.ERASE);
+ }
+
+ /**
+ * @param unresolvedSignature
+ * @return resolve method signature with type parameters
+ */
+ public String resolveMethodKeepTypeParams(String unresolvedSignature)
+ {
+ return resolveMethod(unresolvedSignature, TypeParameters.KEEP);
+ }
+
+ private String resolveMethod(String unresolvedSignature, TypeParameters eraseTypeParameters)
+ {
+ final String unresolvedSignatureNormalized = unresolvedSignature.replaceAll("/", "."); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // get the list of parameters
+ final String[] parameters = Signature.getParameterTypes(unresolvedSignatureNormalized);
+
+ for (int i = 0; i < parameters.length; i++)
+ {
+ // try to full resolve the type
+ parameters[i] = resolve(parameters[i], eraseTypeParameters);
+ }
+
+ // resolve return type
+ final String resolvedReturn = resolve(Signature.getReturnType(unresolvedSignatureNormalized),
+ eraseTypeParameters);
+ return Signature.createMethodSignature(parameters, resolvedReturn);
+ }
+
+ /**
+ * @param unresolvedSignature
+ * @return resolved signature with erased type params
+ */
+ public String resolveEraseTypeParams(String unresolvedSignature)
+ {
+ return resolve(unresolvedSignature, TypeParameters.ERASE);
+ }
+
+ /**
+ * @param unresolvedSignature
+ * @return resolved signature with type params
+ */
+ public String resolveKeepTypeParams(String unresolvedSignature)
+ {
+ return resolve(unresolvedSignature, TypeParameters.KEEP);
+ }
+
+ private String resolve(String unresolvedSignature, TypeParameters eraseTypeParameters)
+ {
+ final int sigKind = Signature.getTypeSignatureKind(unresolvedSignature);
+
+ switch (sigKind)
+ {
+ case Signature.BASE_TYPE_SIGNATURE:
+ return unresolvedSignature;
+
+ case Signature.ARRAY_TYPE_SIGNATURE:
+ {
+ final String elementType = Signature.getElementType(unresolvedSignature);
+
+ if (Signature.getTypeSignatureKind(elementType) == Signature.BASE_TYPE_SIGNATURE)
+ {
+ return unresolvedSignature;
+ }
+
+ final String resolvedElementType = resolveRelative(elementType, eraseTypeParameters);
+ String resultType = ""; //$NON-NLS-1$
+ for (int i = 0; i < Signature.getArrayCount(unresolvedSignature); i++)
+ {
+ resultType += Signature.C_ARRAY;
+ }
+
+ return resultType + resolvedElementType;
+ }
+
+ case Signature.TYPE_VARIABLE_SIGNATURE:
+ return resolveRelative(unresolvedSignature, eraseTypeParameters);
+
+ case Signature.CLASS_TYPE_SIGNATURE:
+ return resolveRelative(unresolvedSignature, eraseTypeParameters);
+
+ case Signature.WILDCARD_TYPE_SIGNATURE:
+ // strip the wildcard and try again. Too bad Signature doesn't seem to
+ // have a method
+ // for this
+ if (unresolvedSignature.charAt(0) == Signature.C_STAR)
+ {
+ return TypeConstants.TYPE_JAVAOBJECT;
+ }
+ return resolve(unresolvedSignature.substring(1), eraseTypeParameters);
+
+ case Signature.CAPTURE_TYPE_SIGNATURE:
+ // strip the capture and try again
+ return resolve(Signature.removeCapture(unresolvedSignature), eraseTypeParameters);
+ // case Signature.TYPE_VARIABLE_SIGNATURE:
+ // resolveSignatureRelative(owningType, typeSignature,
+ // eraseTypeParameters);
+
+ default:
+ return unresolvedSignature;
+ }
+ }
+
+ /**
+ * @param owningType -- type relative to which typeSignature will be resolved
+ * @param typeSignature -- non-array type signature
+ * @return the resolved type signature if possible or typeSignature if not
+ */
+ private String resolveRelative(final String typeSignature, final TypeParameters eraseTypeParameters)
+ {
+ // if already fully resolved, return the input
+ if (typeSignature.charAt(0) == Signature.C_RESOLVED)
+ {
+ return typeSignature;
+ }
+
+ List<String> typeParameters = new ArrayList<String>();
+
+ IType resolvedType = resolveType(typeSignature);
+
+ if (resolvedType != null)
+ {
+ if (eraseTypeParameters == TypeParameters.KEEP)
+ {
+ // ensure that type parameters are resolved recursively
+ for (String typeParam : Signature.getTypeArguments(typeSignature))
+ {
+ typeParam = Signature.removeCapture(typeParam);
+ // check and remove bound wildcarding (extends/super/?)
+ if (Signature.getTypeSignatureKind(typeParam) == Signature.WILDCARD_TYPE_SIGNATURE)
+ {
+ // convert ? to Object, strip extends/super
+ if (typeParam.charAt(0) == Signature.C_STAR)
+ {
+ typeParam = TypeConstants.TYPE_JAVAOBJECT;
+ }
+ else
+ {
+ typeParam = typeParam.substring(1);
+ }
+ }
+ final String resolvedParameter = resolveRelative(
+ // use the enclosing type,
+ // *not* the resolved type because
+ // we need to resolve in that context
+ typeParam, eraseTypeParameters);
+ typeParameters.add(resolvedParameter);
+ }
+ }
+
+ final String resolvedTypeSignature = Signature.createTypeSignature(resolvedType.getFullyQualifiedName(),
+ true);
+
+ if (typeParameters.size() > 0 && eraseTypeParameters == TypeParameters.KEEP)
+ {
+ StringBuffer sb = new StringBuffer(resolvedTypeSignature);
+
+ if (sb.charAt(sb.length() - 1) == ';')
+ {
+ sb = sb.delete(sb.length() - 1, sb.length());
+ }
+
+ sb.append("<"); //$NON-NLS-1$
+ for (String param : typeParameters)
+ {
+ // System.out.println("type param:
+ // "+resolvedType.getTypeParameter(param));
+ sb.append(param);
+ }
+
+ // replace the dangling ',' with the closing ">"
+ sb.append(">;"); //$NON-NLS-1$
+ return sb.toString();
+ }
+
+ return resolvedTypeSignature;
+ }
+
+ if (Signature.getTypeSignatureKind(typeSignature) == Signature.CLASS_TYPE_SIGNATURE
+ || Signature.getTypeSignatureKind(typeSignature) == Signature.TYPE_VARIABLE_SIGNATURE)
+ {
+ // if we are unable to resolve, check to see if the owning type has
+ // a parameter by this name
+ ITypeParameter typeParam = type.getTypeParameter(Signature.getSignatureSimpleName(typeSignature));
+
+ // if we have a type parameter and it hasn't been resolved to a type,
+ // then assume it is a method template placeholder (i.e. T in ArrayList).
+ // at runtime these unresolved parameter variables are effectively
+ // turned into Object's. For example, think List.add(E o). At runtime,
+ // E will behave exactly like java.lang.Object in that signature
+ if (typeParam.exists())
+ {
+ return TypeConstants.TYPE_JAVAOBJECT;
+ }
+
+ // TODO: is there a better way to handle a failure to resolve
+ // than just garbage out?
+ // JSFCommonPlugin.log(new Exception("Failed to resolve type:
+ // "+typeSignature), "Failed to resolve type: "+typeSignature);
+ // //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ return typeSignature;
+ }
+
+ private IType resolveType(final String typeSignature)
+ {
+ final String typeName = TypeUtil.getFullyQualifiedName(typeSignature);
+ return resolveTypeName(typeName);
+ }
+
+ IType resolveTypeName(String typeName)
+ {
+ IType resolved = resolvedTypes.get(typeName);
+ if (resolved != null)
+ {
+ return resolved;
+ }
+ resolved = resolveTypeNameRelative(typeName);
+ resolvedTypes.put(typeName, resolved);
+ return resolved;
+ }
+
+ private IType resolveTypeNameRelative(String typeName)
+ {
+ try
+ {
+ String[][] resolved = type.resolveType(typeName);
+ if (resolved != null && resolved.length > 0)
+ {
+ return type.getJavaProject().findType(resolved[0][0], resolved[0][1]);
+ }
+ return resolveInParents(typeName);
+ }
+ catch (JavaModelException jme)
+ {
+ return null;
+ }
+ }
+
+ private IType resolveInParents(String fullyQualifiedName)
+ throws JavaModelException
+ {
+ for (IType superType : superTypes)
+ {
+ String[][] resolved = superType.resolveType(fullyQualifiedName);
+ if (resolved != null && resolved.length > 0)
+ {
+ return type.getJavaProject().findType(resolved[0][0], resolved[0][1]);
+ }
+ }
+ return null;
+ }
+
+ private enum TypeParameters
+ {
+ ERASE, KEEP
+ }
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java
index 134d95b..067d520 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 Oracle Corporation.
+ * Copyright (c) 2006, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,12 +9,12 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache resolved types
*
********************************************************************************/
package org.eclipse.jst.jsf.common.util;
-import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.IField;
@@ -45,236 +45,20 @@
|| (Signature.getTypeSignatureKind(typeSignature) == Signature.ARRAY_TYPE_SIGNATURE
&& Signature.getElementType(typeSignature).charAt(0) == Signature.C_RESOLVED))
{
- IType type = null;
-
try
{
- type = owningType.getJavaProject().
+ return owningType.getJavaProject().
findType(getFullyQualifiedName(typeSignature));
}
catch (JavaModelException jme)
{
// do nothing; return type == null;
}
-
- return type;
+ return null;
}
-
-
return resolveTypeRelative(owningType, typeSignature);
}
- /**
- * Fully equivalent to:
- *
- * #resolveTypeSignature(owningType, typeSignature, true)
- *
- * If resolved, type signature has generic type parameters erased (absent).
- *
- * @param owningType
- * @param typeSignature
- * @return the resolved type signature for typeSignature in owningType or
- * typeSignature unchanged if cannot resolve.
- */
- public static String resolveTypeSignature(final IType owningType, final String typeSignature)
- {
- return resolveTypeSignature(owningType, typeSignature, true);
- }
-
- /**
- * Resolve typeSignature in the context of owningType. This method will return
- * a type erased signture if eraseTypeParameters == true and will attempt to
- * resolve and include parameters if eraseTypeParamters == false
- *
- * NOTE: special rules apply to the way unresolved type parameters and wildcards
- * are resolved:
- *
- * 1) If a fully unresolved type parameter is found, then it will be replaced with Ljava.lang.Object;
- *
- * i.e. List<T> -> Ljava.util.List<Ljava.lang.Object;>; for any unresolved T.
- *
- * 2) Any bounded wildcard will be replaced by the bound:
- *
- * i.e. List<? extends String> -> Ljava.util.List<Ljava.lang.String;>;
- * i.e. List<? super String> -> Ljava.util.List<Ljava.lang.String;>;
- *
- * Note limitation here: bounds that use 'super' will take the "best case" scenario that the list
- * type is of that type.
- *
- * 3) The unbounded wildcard will be replaced by Ljava.lang.Object;
- *
- * i.e. List<?> -> Ljava.util.List<Ljava.lang.Object;>;
- *
- *
- * The reason for this substition is to return the most accurate reasonable approximation
- * of the type within what is known by owningType
- *
- * @param owningType
- * @param typeSignature
- * @param eraseTypeParameters if set to false, type parameters are resolved included
- * in the signature
- * @return the resolved type signature for typeSignature in owningType or
- * typeSignature unchanged if cannot resolve.
- */
- public static String resolveTypeSignature(final IType owningType, final String typeSignature, boolean eraseTypeParameters)
- {
- final int sigKind = Signature.getTypeSignatureKind(typeSignature);
-
- switch (sigKind)
- {
- case Signature.BASE_TYPE_SIGNATURE:
- return typeSignature;
-
- case Signature.ARRAY_TYPE_SIGNATURE:
- {
- final String elementType = Signature.getElementType(typeSignature);
-
- if (Signature.getTypeSignatureKind(elementType) == Signature.BASE_TYPE_SIGNATURE)
- {
- return typeSignature;
- }
-
- final String resolvedElementType = resolveSignatureRelative(owningType, elementType, eraseTypeParameters);
- String resultType = ""; //$NON-NLS-1$
- for (int i = 0; i < Signature.getArrayCount(typeSignature);i++)
- {
- resultType+=Signature.C_ARRAY;
- }
-
- return resultType+resolvedElementType;
- }
-
- case Signature.TYPE_VARIABLE_SIGNATURE:
- return resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters);
-
- case Signature.CLASS_TYPE_SIGNATURE:
- return resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters);
-
- case Signature.WILDCARD_TYPE_SIGNATURE:
- // strip the wildcard and try again. Too bad Signature doesn't seem to have a method
- // for this
- if (typeSignature.charAt(0) == Signature.C_STAR)
- {
- return TypeConstants.TYPE_JAVAOBJECT;
- }
- return resolveTypeSignature(owningType, typeSignature.substring(1), eraseTypeParameters);
-
- case Signature.CAPTURE_TYPE_SIGNATURE:
- // strip the capture and try again
- return resolveTypeSignature(owningType, Signature.removeCapture(typeSignature), eraseTypeParameters);
-// case Signature.TYPE_VARIABLE_SIGNATURE:
-// resolveSignatureRelative(owningType, typeSignature, eraseTypeParameters);
-
- default:
- return typeSignature;
- }
- }
-
- /**
- * @param owningType -- type relative to which typeSignature will be resolved
- * @param typeSignature -- non-array type signature
- * @return the resolved type signature if possible or typeSignature if not
- */
- private static String resolveSignatureRelative(final IType owningType, final String typeSignature, final boolean eraseTypeParameters)
- {
- // if already fully resolved, return the input
- if (typeSignature.charAt(0) == Signature.C_RESOLVED)
- {
- return typeSignature;
- }
-
- List<String> typeParameters = new ArrayList<String>();
-
- IType resolvedType = resolveTypeRelative(owningType, typeSignature);
-
- if (resolvedType != null)
- {
- if (!eraseTypeParameters)
- {
- // ensure that type parameters are resolved recursively
- for (String typeParam : Signature.getTypeArguments(typeSignature))
- {
- typeParam = Signature.removeCapture(typeParam);
- // check and remove bound wildcarding (extends/super/?)
- if (Signature.getTypeSignatureKind(typeParam) == Signature.WILDCARD_TYPE_SIGNATURE)
- {
- // convert ? to Object, strip extends/super
- if (typeParam.charAt(0) == Signature.C_STAR)
- {
- typeParam = TypeConstants.TYPE_JAVAOBJECT;
- }
- else
- {
- typeParam = typeParam.substring(1);
- }
- }
- final String resolvedParameter =
- resolveSignatureRelative(
- // use the enclosing type,
- // *not* the resolved type because
- // we need to resolve in that context
- owningType,
- typeParam, eraseTypeParameters);
- typeParameters.add(resolvedParameter);
- }
- }
-
- final String resolvedTypeSignature =
- Signature.createTypeSignature
- (resolvedType.getFullyQualifiedName(), true);
-
-
- if (typeParameters.size() > 0 && !eraseTypeParameters)
- {
- StringBuffer sb = new StringBuffer(resolvedTypeSignature);
-
- if (sb.charAt(sb.length()-1) == ';')
- {
- sb = sb.delete(sb.length()-1, sb.length());
- }
-
- sb.append("<"); //$NON-NLS-1$
- for(String param : typeParameters)
- {
- //System.out.println("type param: "+resolvedType.getTypeParameter(param));
- sb.append(param);
- }
-
- // replace the dangling ',' with the closing ">"
- sb.append(">;"); //$NON-NLS-1$
- return sb.toString();
- }
-
- return resolvedTypeSignature;
- }
-
- if (Signature.getTypeSignatureKind(typeSignature) ==
- Signature.CLASS_TYPE_SIGNATURE
- || Signature.getTypeSignatureKind(typeSignature)
- == Signature.TYPE_VARIABLE_SIGNATURE)
- {
- // if we are unable to resolve, check to see if the owning type has
- // a parameter by this name
- ITypeParameter typeParam = owningType.getTypeParameter(Signature.getSignatureSimpleName(typeSignature));
-
- // if we have a type parameter and it hasn't been resolved to a type,
- // then assume it is a method template placeholder (i.e. T in ArrayList).
- // at runtime these unresolved parameter variables are effectively
- // turned into Object's. For example, think List.add(E o). At runtime,
- // E will behave exactly like java.lang.Object in that signature
- if (typeParam.exists())
- {
- return TypeConstants.TYPE_JAVAOBJECT;
- }
-
- // TODO: is there a better way to handle a failure to resolve
- // than just garbage out?
- //JSFCommonPlugin.log(new Exception("Failed to resolve type: "+typeSignature), "Failed to resolve type: "+typeSignature); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- return typeSignature;
- }
-
private static IType resolveTypeRelative(final IType owningType, final String typeSignature)
{
final String fullName = getFullyQualifiedName(typeSignature);
@@ -313,37 +97,6 @@
return Signature.createTypeSignature(fullyQualifiedName, true);
}
-
- /**
- * @param owner
- * @param unresolvedSignature
- * @return the resolved method signature for unresolvedSignature in owner
- */
- public static String resolveMethodSignature(final IType owner,
- final String unresolvedSignature)
- {
-
- final String unresolvedSignatureNormalized =
- unresolvedSignature.replaceAll("/", "."); //$NON-NLS-1$ //$NON-NLS-2$
-
- // get the list of parameters
- final String[] parameters =
- Signature.getParameterTypes(unresolvedSignatureNormalized);
-
- for (int i = 0; i < parameters.length; i++)
- {
- // try to full resolve the type
- parameters[i] = resolveTypeSignature(owner, parameters[i]);
- }
-
- // resolve return type
- final String resolvedReturn =
- resolveTypeSignature(owner,
- Signature.getReturnType(unresolvedSignatureNormalized));
-
- return Signature.createMethodSignature(parameters, resolvedReturn);
- }
-
/**
* @param typeSignature
* @return a fully qualified Java class name from a type signature
@@ -355,7 +108,7 @@
final String typeName = Signature.getSignatureSimpleName(typeSignature);
return "".equals(packageName) ? typeName : packageName + "." + typeName; //$NON-NLS-1$//$NON-NLS-2$
}
-
+
private static IType resolveInParents(IType childType, String fullyQualifiedName)
throws JavaModelException
{
@@ -407,7 +160,7 @@
return null;
}
}
-
+
/**
* @param type
* @param typeParamSignature -- must be a Type Variable Signature
@@ -452,7 +205,7 @@
return null;
}
-
+
/**
* @param type
* @param fieldName
@@ -493,7 +246,7 @@
return false;
}
-
+
/**
* @param typeSig1 the type signature of the first enum. Must be non-null, fully resolved enum type.
* @param typeSig2 the type signature of the second enum. Must be non-null, fully resolved enum type.
@@ -525,7 +278,7 @@
// only comparable if is the same class
return typeSig1.equals(typeSig2);
}
-
+
/**
* @param typeSig1 the type signature of the first enum. Must be non-null, fully resolved enum type.
* @param typeSig2 the type signature of the second enum. Must be non-null, fully resolved enum type.
@@ -556,7 +309,6 @@
// can never be equal
return !typeSig1.equals(typeSig2);
}
-
/**
* NOTE: we diverge from IType.isEnum() because we also return true if the base type
@@ -591,7 +343,7 @@
// if unresolved assume false
return false;
}
-
+
private TypeUtil()
{
// no external instantiation
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IBoundedListTypeDescriptorImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IBoundedListTypeDescriptorImpl.java
index e7b7a00..7061268 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IBoundedListTypeDescriptorImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IBoundedListTypeDescriptorImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2019 IBM Corporation and others.
+ * Copyright (c) 2006, 2021 IBM Corporation and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * IBM Corporation - initial API and implementation
+ * IBM Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache JDTBeanIntrospector
*******************************************************************************/
/**
* <copyright>
@@ -24,14 +25,11 @@
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.common.util.JDTBeanMethod;
import org.eclipse.jst.jsf.context.symbol.IBoundedListTypeDescriptor;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
@@ -73,6 +71,7 @@
* <!-- end-user-doc -->
* @generated
*/
+ @Override
protected EClass eStaticClass() {
return SymbolPackage.Literals.IBOUNDED_LIST_TYPE_DESCRIPTOR;
}
@@ -137,68 +136,55 @@
if (type != null)
{
- final JDTBeanIntrospector introspector =
- new JDTBeanIntrospector(type);
+ final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
- final IMethod callMethod =
- matchMethod(methodName, methodArguments, introspector.getAllMethods());
+ final JDTBeanMethod callMethod =
+ matchMethod(methodName, methodArguments, introspector.getMethods());
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();
+ // resolve the method's return type; don't erase parameters
+ final String retTypeSignature = callMethod.getResolvedReturnTypeUnerased();
+ 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
- }
+ // 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;
}
}
return result;
}
- private IMethod matchMethod(String name, List methodArguments, IMethod[] allMethods)
+ private JDTBeanMethod matchMethod(String name, List methodArguments, JDTBeanMethod[] allMethods)
{
final List argSigs = convertArgsToSignatures(methodArguments);
- IMethod matchedMethod = null;
for (int i = 0; i < allMethods.length; i++)
{
- final IMethod method = allMethods[i];
+ final JDTBeanMethod method = allMethods[i];
// check for names and argument count match
- if (method.getParameterTypes().length == argSigs.size()
+ if (method.getUnresolvedParameterTypesUnerased().length == argSigs.size()
&& method.getElementName().equals(name))
{
- String[] methods = method.getParameterTypes();
+ String[] paramSigs = method.getUnresolvedParameterTypesUnerased(); // RWEI seems not be correct to get unresolved types here
// need to verify argument matches
boolean isMatched = true;
- CHECK_ARGUMENTS: for (int j = 0; j < methods.length; j++)
+ CHECK_ARGUMENTS: for (int j = 0; j < paramSigs.length; j++)
{
- if (!methods[j].equals(argSigs.get(j)))
+ if (!paramSigs[j].equals(argSigs.get(j)))
{
// not a match
isMatched = false;
@@ -213,7 +199,7 @@
}
}
- return matchedMethod;
+ return null;
}
private List convertArgsToSignatures(List methodArgs)
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IJavaTypeDescriptor2Impl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IJavaTypeDescriptor2Impl.java
index 95fbaa8..d1588ef 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IJavaTypeDescriptor2Impl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/IJavaTypeDescriptor2Impl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 Oracle Corporation.
+ * Copyright (c) 2006, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache JDTBeanIntrospector
*
********************************************************************************/
package org.eclipse.jst.jsf.context.symbol.internal.impl;
@@ -28,13 +29,13 @@
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.JDTBeanMethod;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
import org.eclipse.jst.jsf.common.util.TypeUtil;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
@@ -70,27 +71,27 @@
* @generated
*/
@SuppressWarnings("hiding")
- public static final String copyright = "Copyright 2006 Oracle"; //$NON-NLS-1$
+ 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 -->
+ * <!-- end-user-doc -->
* @see #getType()
* @generated
* @ordered
*/
- protected static final IType TYPE_EDEFAULT = null;
+ protected static final IType TYPE_EDEFAULT = null;
/**
* The cached value of the '{@link #getType() <em>Type</em>}' attribute.
* <!-- begin-user-doc -->
- * <!-- end-user-doc -->
+ * <!-- end-user-doc -->
* @see #getType()
* @generated
* @ordered
*/
- protected IType type = TYPE_EDEFAULT;
+ protected IType type = TYPE_EDEFAULT;
/**
* The default value of the '{@link #getArrayCount() <em>Array Count</em>}' attribute.
@@ -125,7 +126,7 @@
* @ordered
*/
@SuppressWarnings("hiding")
- protected static final IJavaElement JDT_CONTEXT_EDEFAULT = null;
+ protected static final IJavaElement JDT_CONTEXT_EDEFAULT = null;
/**
* The cached value of the '{@link #getJdtContext() <em>Jdt Context</em>}' attribute.
@@ -136,24 +137,25 @@
* @ordered
*/
@SuppressWarnings("hiding")
- protected IJavaElement jdtContext = JDT_CONTEXT_EDEFAULT;
+ protected IJavaElement jdtContext = JDT_CONTEXT_EDEFAULT;
/**
* <!-- begin-user-doc -->
- * <!-- end-user-doc -->
+ * <!-- end-user-doc -->
* @generated
*/
- protected IJavaTypeDescriptor2Impl() {
+ protected IJavaTypeDescriptor2Impl() {
super();
}
/**
* <!-- begin-user-doc -->
* @return the static class
- * <!-- end-user-doc -->
+ * <!-- end-user-doc -->
* @generated
*/
- protected EClass eStaticClass() {
+ @Override
+ protected EClass eStaticClass() {
return SymbolPackage.Literals.IJAVA_TYPE_DESCRIPTOR2;
}
@@ -161,31 +163,32 @@
* <!-- 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 -->
+ * <!-- end-user-doc -->
* @generated
*/
- public IType getType() {
+ public IType getType() {
return type;
}
/**
* <!-- begin-user-doc -->
* @param newType
- * <!-- end-user-doc -->
+ * <!-- end-user-doc -->
* @generated
*/
- public void setType(IType newType) {
+ 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()
+ /**
+ * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getInterfaceTypeSignatures()
+ * @generated NOT
+ */
+ @Override
+ public EList getInterfaceTypeSignatures()
{
EList interfaces = new BasicEList();
@@ -208,6 +211,7 @@
* @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getSuperTypeSignatures()
* @generated NOT
*/
+ @Override
public EList getSuperTypeSignatures()
{
EList interfaces = new BasicEList();
@@ -247,64 +251,66 @@
}
}
+ @Override
public EList getProperties()
{
return getBeanProperties();
}
+ @Override
public EList getMethods()
{
return getBeanMethods();
}
/**
- * <!-- begin-user-doc -->
+ * <!-- 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
- {
+ * <!-- 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;
- }
+ }
+ BasicEList list = new BasicEList(propertyColl);
+ return list;
+ }
- /**
- * <!-- begin-user-doc -->
+ /**
+ * <!-- 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;
- }
+ * <!-- 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;
+ }
/**
@@ -328,11 +334,12 @@
eNotify(new ENotificationImpl(this, Notification.SET, SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__ARRAY_COUNT, oldArrayCount, arrayCount));
}
- /**
+ /**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
+ @Override
public IJavaElement getJdtContext() {
return jdtContext;
}
@@ -342,6 +349,7 @@
* <!-- end-user-doc -->
* @generated
*/
+ @Override
public void setJdtContext(IJavaElement newJdtContext) {
IJavaElement oldJdtContext = jdtContext;
jdtContext = newJdtContext;
@@ -360,6 +368,7 @@
* <!-- end-user-doc -->
* @generated NOT
*/
+ @Override
public IType resolveType(String resolvedTypeSignature)
{
IType resolvedType = null;
@@ -401,6 +410,7 @@
* <!-- end-user-doc -->
* @generated
*/
+ @Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
@@ -420,6 +430,7 @@
* <!-- end-user-doc -->
* @generated
*/
+ @Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
@@ -445,6 +456,7 @@
* <!-- end-user-doc -->
* @generated
*/
+ @Override
public void eUnset(int featureID) {
switch (featureID) {
case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
@@ -468,6 +480,7 @@
* <!-- end-user-doc -->
* @generated
*/
+ @Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case SymbolPackage.IJAVA_TYPE_DESCRIPTOR2__TYPE:
@@ -482,71 +495,74 @@
return super.eIsSet(featureID);
}
+ @Override
public boolean isArray()
{
- return getArrayCount() > 0;
+ 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);
+ * @generated NOT
+ */
+ @Override
+ 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;
+ 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
- }
+ 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);
- }
+ 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);
+
+ IPropertySymbol newPropertySymbol =
+ SymbolFactory.eINSTANCE.createIPropertySymbol();
+ newPropertySymbol.setTypeDescriptor(elementTypeDesc);
+ newPropertySymbol.setWritable(true);
+ newPropertySymbol.setReadable(true);
+ newPropertySymbol.setName(fullyQualifiedElementType);
return newPropertySymbol;
- }
+ }
- return null;
- }
+ return null;
+ }
- /* (non-Javadoc)
- * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getTypeSignature()
+ /* (non-Javadoc)
+ * @see org.eclipse.jst.jsf.context.symbol.internal.impl.ITypeDescriptorImpl#getTypeSignature()
* @generated NOT
- */
- public String getTypeSignature()
+ */
+ @Override
+ public String getTypeSignature()
{
if (getType() == null)
{
@@ -564,35 +580,34 @@
}
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 JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
- final Map<String, JDTBeanProperty> properties = introspector.getProperties();
-
- final Collection calculatedProps = new ArrayList(properties.size());
+ final Map<String, JDTBeanProperty> properties = introspector.getProperties();
- 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 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 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.setReadable(property.isReadable());
workingCopy.setWritable(property.isWritable());
workingCopyDesc.setArrayCount(property.getArrayCount());
@@ -612,61 +627,58 @@
}
calculatedProps.add(workingCopy);
- }
+ }
- return calculatedProps;
- }
+ return calculatedProps;
+ }
private Collection getMethodsInternal()
- {
- JDTBeanIntrospector introspector =
- new JDTBeanIntrospector(getType());
+ {
+ JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
- IMethod[] methods = introspector.getAllMethods();
+ JDTBeanMethod[] methods = introspector.getMethods();
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
+ for (int i = 0; i < methods.length; i++)
+ {
+ JDTBeanMethod 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(method.getResolvedSignatureErased());
+ methodSymbols.add(workingCopy);
+ }
+ }
+ catch (JavaModelException jme)
+ {
+ // error reading meta-data. Skip to next one
JSFCommonPlugin.log(jme);
- }
- }
-
- return methodSymbols;
- }
+ }
+ }
+
+ return methodSymbols;
+ }
/**
* <!-- begin-user-doc -->
* @return the default string rep
- * <!-- end-user-doc -->
+ * <!-- end-user-doc -->
* @generated
*/
- public String toString() {
+ @Override
+ public String toString() {
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer(super.toString());
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/JavaUtil.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/JavaUtil.java
index e7549c1..822438d 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/JavaUtil.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/JavaUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2007 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Oracle Corporation - initial API and implementation
+ * Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache JDTBeanIntrospector
*******************************************************************************/
package org.eclipse.jst.jsf.context.symbol.internal.impl;
@@ -22,8 +23,8 @@
import org.eclipse.jdt.ui.JavadocContentAccess;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
+import org.eclipse.jst.jsf.common.util.JDTBeanMethod;
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;
@@ -76,19 +77,13 @@
*/
public static IMethod findCorrespondingMethod(final IBeanMethodSymbol symbol) {
final IType type = symbol.getOwner().getType();
- final JDTBeanIntrospector introspector = new JDTBeanIntrospector(type);
- final IMethod[] methods = introspector.getAllMethods();
- for (final IMethod method : methods) {
+ final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
+ final JDTBeanMethod[] methods = introspector.getMethods();
+ for (final JDTBeanMethod method : methods) {
if (method.getElementName().equals(symbol.getName())) {
- try {
- final String currentMethodsSignature = TypeUtil.resolveMethodSignature(method.getDeclaringType(),
- method.getSignature());
- if (currentMethodsSignature.equals(symbol.getSignature())) {
- return method;
- }
- } catch (final JavaModelException e) {
- JSFCommonPlugin.log(IStatus.WARNING, "error determining for method '" //$NON-NLS-1$
- + method.getElementName() + "'.", e); //$NON-NLS-1$
+ final String currentMethodsSignature = method.getResolvedSignatureErased();
+ if (currentMethodsSignature.equals(symbol.getSignature())) {
+ return method.getMethod();
}
}
}
@@ -100,7 +95,7 @@
* @return a JDTBeanProperty for the given property symbol
*/
public static JDTBeanProperty findCorrespondingJDTProperty(final IBeanPropertySymbol propertySymbol) {
- final JDTBeanIntrospector introspector = new JDTBeanIntrospector(propertySymbol.getOwner().getType());
+ final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(propertySymbol.getOwner().getType());
return introspector.getProperties().get(propertySymbol.getName());
}
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/Util.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/Util.java
index da955c8..7f57e7f 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/Util.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/context/symbol/internal/impl/Util.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Oracle Corporation.
+ * Copyright (c) 2007, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache JDTBeanIntrospector
*
********************************************************************************/
package org.eclipse.jst.jsf.context.symbol.internal.impl;
@@ -17,7 +18,6 @@
import java.util.List;
import org.eclipse.emf.common.util.EList;
-import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
@@ -25,6 +25,7 @@
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.internal.types.ValueType;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
+import org.eclipse.jst.jsf.common.util.JDTBeanMethod;
import org.eclipse.jst.jsf.common.util.TypeUtil;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
import org.eclipse.jst.jsf.context.symbol.IPropertySymbol;
@@ -46,96 +47,90 @@
// the call then do this the hard way...
if (type != null && result == null)
{
- final JDTBeanIntrospector introspector =
- new JDTBeanIntrospector(type);
+ final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
- final IMethod callMethod =
- Util.matchMethod(methodName, methodArguments, introspector.getAllMethods(),typeDesc.getTypeParameterSignatures());
+ final JDTBeanMethod callMethod =
+ Util.matchMethod(methodName, methodArguments, introspector.getMethods(),typeDesc.getTypeParameterSignatures());
if (callMethod != null)
{
- try
+ try
{
- // resolve the method's return type; don't erase parameters
- String retTypeSignature = callMethod.getReturnType();
-
- // if we have a type variable, try to parameter match it
- if (Signature.getTypeSignatureKind(retTypeSignature) == Signature.TYPE_VARIABLE_SIGNATURE)
- {
- retTypeSignature = TypeUtil.matchTypeParameterToArgument
- (type
- , retTypeSignature, typeDesc.getTypeParameterSignatures());
-
- if (retTypeSignature == null)
- {
- retTypeSignature = TypeConstants.TYPE_JAVAOBJECT;
- }
- }
- // otherwise, try and resolve it in type
- else
- {
- 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 newTypeDesc = null;
-
- if (retTypeSignature.equals(TypeConstants.TYPE_JAVAOBJECT))
- {
- newTypeDesc = SymbolFactory.eINSTANCE.createIBoundedJavaTypeDescriptor();
- }
- else
- {
- newTypeDesc = SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
- }
-
- newTypeDesc.setArrayCount(Signature.getArrayCount(retTypeSignature));
-
- // may be null
- newTypeDesc.setType(typeDesc.resolveType(retTypeSignature));
- newTypeDesc.setTypeSignatureDelegate(retTypeSignature);
- propSymbol.setTypeDescriptor(newTypeDesc);
- }
-
- result = propSymbol;
- }
- catch (JavaModelException e)
- {
- JSFCommonPlugin.log(e);
- // fall-through and return null result
- }
+ // resolve the method's return type; don't erase parameters
+ String retTypeSignature = callMethod.getUnresolvedReturnTypeUnerased();
+
+ // if we have a type variable, try to parameter match it
+ if (Signature.getTypeSignatureKind(retTypeSignature) == Signature.TYPE_VARIABLE_SIGNATURE)
+ {
+ retTypeSignature = TypeUtil.matchTypeParameterToArgument
+ (type
+ , retTypeSignature, typeDesc.getTypeParameterSignatures());
+
+ if (retTypeSignature == null)
+ {
+ retTypeSignature = TypeConstants.TYPE_JAVAOBJECT;
+ }
+ }
+ else
+ {
+ retTypeSignature = callMethod.getResolvedReturnTypeUnerased();
+ }
+
+ 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 newTypeDesc = null;
+
+ if (retTypeSignature.equals(TypeConstants.TYPE_JAVAOBJECT))
+ {
+ newTypeDesc = SymbolFactory.eINSTANCE.createIBoundedJavaTypeDescriptor();
+ }
+ else
+ {
+ newTypeDesc = SymbolFactory.eINSTANCE.createIJavaTypeDescriptor2();
+ }
+
+ newTypeDesc.setArrayCount(Signature.getArrayCount(retTypeSignature));
+
+ // may be null
+ newTypeDesc.setType(typeDesc.resolveType(retTypeSignature));
+ newTypeDesc.setTypeSignatureDelegate(retTypeSignature);
+ propSymbol.setTypeDescriptor(newTypeDesc);
+ }
+
+ result = propSymbol;
+ }
+ catch (JavaModelException e)
+ {
+ JSFCommonPlugin.log(e);
+ // fall-through and return null result
+ }
}
}
return result;
}
- static IMethod matchMethod(String methodName, List methodArguments, IMethod[] allMethods, List typeParameterSignatures)
+ static JDTBeanMethod matchMethod(String methodName, List methodArguments, JDTBeanMethod[] allMethods, List typeParameterSignatures)
{
-// final List argSigs = convertArgsToSignatures(methodArguments);
- IMethod matchedMethod = null;
-
for (int i = 0; i < allMethods.length; i++)
{
- final IMethod method = allMethods[i];
+ final JDTBeanMethod method = allMethods[i];
// check for names and argument count match
- if (method.getParameterTypes().length == methodArguments.size()
+ if (method.getResolvedParameterTypesUnerased().length == methodArguments.size()
&& method.getElementName().equals(methodName))
{
- List<String> methods = resolveMethodParameters(method, typeParameterSignatures);
+ List<String> params = resolveMethodParameters(method, typeParameterSignatures);
// need to verify argument matches
boolean isMatched = true;
- CHECK_ARGUMENTS: for (int j = 0; j < methods.size(); j++)
+ CHECK_ARGUMENTS: for (int j = 0; j < params.size(); j++)
{
final ValueType valueType = (ValueType) methodArguments.get(j);
@@ -145,8 +140,8 @@
// - method name overloading
// - autoboxing primitives
// - certain kinds of parameterized args
- if (!methods.get(j).equals(valueType.getSignature())
- && !(methods.get(j).equals(TypeConstants.TYPE_JAVAOBJECT)
+ if (!params.get(j).equals(valueType.getSignature())
+ && !(params.get(j).equals(TypeConstants.TYPE_JAVAOBJECT)
&& Signature.getTypeSignatureKind(valueType.getSignature())==Signature.CLASS_TYPE_SIGNATURE))
{
// not a match
@@ -162,18 +157,15 @@
}
}
- return matchedMethod;
+ return null;
}
- static List<String> resolveMethodParameters(IMethod method, List typeParametersSignatures)
+ static List<String> resolveMethodParameters(JDTBeanMethod method, List typeParametersSignatures)
{
List<String> resolved = new ArrayList<String>();
- String[] parameterTypes = method.getParameterTypes();
+ String[] parameterTypes = method.getResolvedParameterTypesUnerased();
for (String parameter : parameterTypes)
{
- parameter = TypeUtil.resolveTypeSignature(method.getDeclaringType()
- , parameter, false);
-
if (Signature.getTypeSignatureKind(parameter) == Signature.TYPE_VARIABLE_SIGNATURE)
{
parameter = TypeUtil.matchTypeParameterToArgument
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java
index 2ce5af6..7d2ed42 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/AnnotationSearchRequestor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Oracle Corporation.
+ * Copyright (c) 2011, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,31 +8,33 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Andrew McCulloch - initial API and implementation
- * Ian Trimble - maintenance
+ * Andrew McCulloch - initial API and implementation
+ * Ian Trimble - maintenance
+ * Reto Weiss/Axon Ivy - Use cached JDTBeanIntrospector to resolve annotation types
*******************************************************************************/
package org.eclipse.jst.jsf.core.jsfappconfig;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.MANAGED_BEAN_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.REFERENCED_BEAN_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.APPLICATION_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_APPLICATION_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_MODEL_BEAN_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_NAMED_BEAN_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_REQUEST_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_SESSION_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CUSTOM_SCOPED_ANNOTATION_CLASS;
import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_COMPONENT_ANNOTATION_CLASS;
import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_CONVERTER_ANNOTATION_CLASS;
import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_RENDERER_ANNOTATION_CLASS;
import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.FACES_VALIDATOR_ANNOTATION_CLASS;
-
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.MANAGED_BEAN_ANNOTATION_CLASS;
import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.NONE_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.VIEW_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.REFERENCED_BEAN_ANNOTATION_CLASS;
import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.SESSION_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.APPLICATION_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CUSTOM_SCOPED_ANNOTATION_CLASS;
+import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.VIEW_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_NAMED_BEAN_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_MODEL_BEAN_ANNOTATION_CLASS;
-
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_REQUEST_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_SESSION_SCOPED_ANNOTATION_CLASS;
-import static org.eclipse.jst.jsf.core.jsfappconfig.AnnotationJSFAppConfigProvider.CDI_APPLICATION_SCOPED_ANNOTATION_CLASS;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.EList;
@@ -40,8 +42,10 @@
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchRequestor;
+import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.facesconfig.emf.ComponentClassType;
import org.eclipse.jst.jsf.facesconfig.emf.ComponentFamilyType;
import org.eclipse.jst.jsf.facesconfig.emf.ComponentType;
@@ -71,76 +75,163 @@
/**
* SearchRequestor that looks at annotations for JSF configuration.
*
- * <p><b>Provisional API - subject to change</b></p>
+ * <p>
+ * <b>Provisional API - subject to change</b>
+ * </p>
*
* @author Andrew McCulloch - Oracle
*/
-public class AnnotationSearchRequestor extends SearchRequestor {
-
+public class AnnotationSearchRequestor extends SearchRequestor
+{
private final FacesConfigType facesConfig;
- AnnotationSearchRequestor(final FacesConfigType facesConfig) {
- this.facesConfig = facesConfig;
- }
+ private static final Set<String> ANNOATION_CANDIDATES = ofAnnotation(
+ MANAGED_BEAN_ANNOTATION_CLASS,
+ REFERENCED_BEAN_ANNOTATION_CLASS,
+ FACES_COMPONENT_ANNOTATION_CLASS,
+ FACES_CONVERTER_ANNOTATION_CLASS,
+ FACES_RENDERER_ANNOTATION_CLASS,
+ FACES_VALIDATOR_ANNOTATION_CLASS,
+ CDI_NAMED_BEAN_ANNOTATION_CLASS,
+ CDI_MODEL_BEAN_ANNOTATION_CLASS);
- public void acceptSearchMatch(SearchMatch match) throws CoreException {
- if (match.getAccuracy() == SearchMatch.A_ACCURATE) {
- Object element = match.getElement();
- if (element instanceof IType) {
- IType type = (IType) element;
- IAnnotation[] annotations = type.getAnnotations();
- if (annotations != null) {
- for (int i = 0, k = annotations.length; i < k; i++) {
- if (annotations[i].exists()) {
- String annotationType = annotations[i].getElementName();
- String[][] resolvedAnnotationTypes = type.resolveType(annotationType);
- if (resolvedAnnotationTypes != null) {
- String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString();
- if (MANAGED_BEAN_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addManagedBean(annotations[i], type);
- } else if (REFERENCED_BEAN_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addReferencedBean(annotations[i], type);
- } else if (FACES_COMPONENT_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addComponent(annotations[i], type);
- } else if (FACES_CONVERTER_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addConverter(annotations[i], type);
- } else if (FACES_RENDERER_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addRenderer(annotations[i], type);
- } else if (FACES_VALIDATOR_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addValidator(annotations[i], type);
- } else if (CDI_NAMED_BEAN_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addCDINamedBean(annotations[i], type);
- } else if (CDI_MODEL_BEAN_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- addCDIModelBean(type);
- }
- }
- }
- }
- }
+ private static final Set<String> SCOPED_ANNOTATION_CANDIDATES = ofAnnotation(
+ NONE_SCOPED_ANNOTATION_CLASS,
+ VIEW_SCOPED_ANNOTATION_CLASS,
+ SESSION_SCOPED_ANNOTATION_CLASS,
+ APPLICATION_SCOPED_ANNOTATION_CLASS,
+ CUSTOM_SCOPED_ANNOTATION_CLASS);
+
+ private static final Set<String> CDI_SCOPED_ANNOTATION_CANDIDATES = ofAnnotation(
+ CDI_REQUEST_SCOPED_ANNOTATION_CLASS,
+ CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS,
+ CDI_SESSION_SCOPED_ANNOTATION_CLASS,
+ CDI_APPLICATION_SCOPED_ANNOTATION_CLASS);
+
+ private static Set<String> ofAnnotation(String... annotationClasses)
+ {
+ Set<String> candidates = new HashSet<String>();
+ for (String annotationClass : annotationClasses)
+ {
+ candidates.add(annotationClass);
+ candidates.add(Signature.getSimpleName(annotationClass));
+ }
+ return Collections.unmodifiableSet(candidates);
+ }
+
+ AnnotationSearchRequestor(final FacesConfigType facesConfig)
+ {
+ this.facesConfig = facesConfig;
+ }
+
+ @Override
+ public void acceptSearchMatch(SearchMatch match) throws CoreException
+ {
+ if (match.getAccuracy() != SearchMatch.A_ACCURATE)
+ {
+ return;
+ }
+
+ Object element = match.getElement();
+ if (!(element instanceof IType))
+ {
+ return;
+ }
+ IType type = (IType) element;
+ JDTBeanIntrospector beanIntrospector = JDTBeanIntrospector.forType(type);
+ IAnnotation[] annotations = type.getAnnotations();
+ if (annotations == null)
+ {
+ return;
+ }
+ for (IAnnotation annotation : annotations)
+ {
+ processAnnotation(type, beanIntrospector, annotation);
+ }
+ }
+
+ private void processAnnotation(IType type, JDTBeanIntrospector beanIntrospector, IAnnotation annotation) throws CoreException
+ {
+ if (!annotation.exists())
+ {
+ return;
+ }
+ String annotationType = annotation.getElementName();
+ if (! isAnnotationCandidate(annotationType))
+ {
+ return;
+ }
+ String annotationClassName = beanIntrospector.resolveFullQualifiedTypeName(annotationType);
+ if (annotationClassName != null)
+ {
+ if (MANAGED_BEAN_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addManagedBean(annotation, type, beanIntrospector);
+ }
+ else if (REFERENCED_BEAN_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addReferencedBean(annotation, type);
+ }
+ else if (FACES_COMPONENT_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addComponent(annotation, type);
+ }
+ else if (FACES_CONVERTER_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addConverter(annotation, type);
+ }
+ else if (FACES_RENDERER_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addRenderer(annotation, type);
+ }
+ else if (FACES_VALIDATOR_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addValidator(annotation, type);
+ }
+ else if (CDI_NAMED_BEAN_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addCDINamedBean(annotation, beanIntrospector, type);
+ }
+ else if (CDI_MODEL_BEAN_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ addCDIModelBean(type);
}
}
}
- private void addReferencedBean(IAnnotation referencedBeanAnnotation, IType beanType) throws JavaModelException {
+ private boolean isAnnotationCandidate(String annotationType)
+ {
+ return ANNOATION_CANDIDATES.contains(annotationType);
+ }
+
+ private void addReferencedBean(IAnnotation referencedBeanAnnotation, IType beanType)
+ throws JavaModelException
+ {
IMemberValuePair[] pairs = referencedBeanAnnotation.getMemberValuePairs();
String beanNameString = null;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("name".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- beanNameString = (String)pair.getValue();
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("name".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ beanNameString = (String) pair.getValue();
}
}
}
- if (beanNameString == null) {
+ if (beanNameString == null)
+ {
beanNameString = beanType.getElementName();
- if (beanNameString != null && beanNameString.length() > 0) {
+ if (beanNameString != null && beanNameString.length() > 0)
+ {
StringBuffer casedName = new StringBuffer(String.valueOf(beanNameString.charAt(0)).toUpperCase());
beanNameString = casedName.append(beanNameString.substring(1)).toString();
}
}
String beanClassName = beanType.getFullyQualifiedName();
- if (beanNameString != null && beanClassName != null) {
+ if (beanNameString != null && beanClassName != null)
+ {
ReferencedBeanType bean = FacesConfigFactory.eINSTANCE.createReferencedBeanType();
ReferencedBeanNameType beanName = FacesConfigFactory.eINSTANCE.createReferencedBeanNameType();
beanName.setTextContent(beanNameString);
@@ -152,57 +243,40 @@
}
}
- private void addManagedBean(IAnnotation beanAnnotation, IType beanType) throws JavaModelException {
+ private void addManagedBean(IAnnotation beanAnnotation, IType beanType, JDTBeanIntrospector beanIntrospector) throws JavaModelException
+ {
IMemberValuePair[] pairs = beanAnnotation.getMemberValuePairs();
String beanNameString = null;
Boolean isBeanEager = Boolean.FALSE;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("name".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- beanNameString = (String)pair.getValue();
- } else if ("eager".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_BOOLEAN) { //$NON-NLS-1$
- isBeanEager = (Boolean)pair.getValue();
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("name".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ beanNameString = (String) pair.getValue();
+ }
+ else if ("eager".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_BOOLEAN) //$NON-NLS-1$
+ {
+ isBeanEager = (Boolean) pair.getValue();
}
}
}
- if (beanNameString == null || beanNameString.length() < 1) {
+ if (beanNameString == null || beanNameString.length() < 1)
+ {
beanNameString = beanType.getElementName();
- if (beanNameString != null && beanNameString.length() > 0) {
+ if (beanNameString != null && beanNameString.length() > 0)
+ {
StringBuffer casedName = new StringBuffer(String.valueOf(beanNameString.charAt(0)).toLowerCase());
beanNameString = casedName.append(beanNameString.substring(1)).toString();
}
}
String beanClassName = beanType.getFullyQualifiedName();
- String beanScopeString = "request"; //$NON-NLS-1$
- IAnnotation[] annotations = beanType.getAnnotations();
- if (annotations != null) {
- for (int i = 0, k = annotations.length; i < k; i++) {
- if (annotations[i].exists()) {
- String annotationType = annotations[i].getElementName();
- String[][] resolvedAnnotationTypes = beanType.resolveType(annotationType);
- if (resolvedAnnotationTypes != null) {
- String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString();
- if (NONE_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "none"; //$NON-NLS-1$
- } else if (VIEW_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "view"; //$NON-NLS-1$
- } else if (SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "session"; //$NON-NLS-1$
- } else if (APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "application"; //$NON-NLS-1$
- } else if (CUSTOM_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- IMemberValuePair[] scopePairs = annotations[i].getMemberValuePairs();
- if (scopePairs != null && scopePairs.length == 1 && scopePairs[0].getValueKind() == IMemberValuePair.K_STRING) {
- beanScopeString = (String)scopePairs[0].getValue();
- }
- }
- }
- }
- }
- }
+ String beanScopeString = processScopeAnnotations(beanType, beanIntrospector);
- if (beanNameString != null && beanClassName != null) {
+ if (beanNameString != null && beanClassName != null)
+ {
ManagedBeanType bean = FacesConfigFactory.eINSTANCE.createManagedBeanType();
ManagedBeanNameType beanName = FacesConfigFactory.eINSTANCE.createManagedBeanNameType();
beanName.setTextContent(beanNameString);
@@ -219,88 +293,176 @@
}
}
- private void addValidator(IAnnotation validatorAnnotation, IType validatorType) throws JavaModelException {
+ private String processScopeAnnotations(IType beanType, JDTBeanIntrospector beanIntrospector) throws JavaModelException
+ {
+ String beanScopeString = "request"; //$NON-NLS-1$
+ IAnnotation[] annotations = beanType.getAnnotations();
+ if (annotations == null)
+ {
+ return beanScopeString;
+ }
+ for (IAnnotation annotation : annotations)
+ {
+ String scope = processScopeAnnoation(beanType, beanIntrospector, annotation);
+ if (scope != null)
+ {
+ beanScopeString = scope;
+ }
+ }
+ return beanScopeString;
+ }
+
+ private String processScopeAnnoation(IType beanType, JDTBeanIntrospector beanIntrospector, IAnnotation annotation) throws JavaModelException
+ {
+ if (! annotation.exists())
+ {
+ return null;
+ }
+ String annotationType = annotation.getElementName();
+ if (! isScopeAnnotationCandidate(annotationType))
+ {
+ return null;
+ }
+ String annotationClassName = beanIntrospector.resolveFullQualifiedTypeName(annotationType);
+ if (annotationClassName == null)
+ {
+ return null;
+ }
+ if (NONE_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "none"; //$NON-NLS-1$
+ }
+ else if (VIEW_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "view"; //$NON-NLS-1$
+ }
+ else if (SESSION_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "session"; //$NON-NLS-1$
+ }
+ else if (APPLICATION_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "application"; //$NON-NLS-1$
+ }
+ else if (CUSTOM_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ IMemberValuePair[] scopePairs = annotation.getMemberValuePairs();
+ if (scopePairs != null && scopePairs.length == 1
+ && scopePairs[0].getValueKind() == IMemberValuePair.K_STRING)
+ {
+ return (String) scopePairs[0].getValue();
+ }
+ }
+ return null;
+ }
+
+ private boolean isScopeAnnotationCandidate(String annotationType)
+ {
+ return SCOPED_ANNOTATION_CANDIDATES.contains(annotationType);
+ }
+
+ private void addValidator(IAnnotation validatorAnnotation, IType validatorType) throws JavaModelException
+ {
String validatorClassName = validatorType.getFullyQualifiedName();
IMemberValuePair[] pairs = validatorAnnotation.getMemberValuePairs();
String validatorIDString = null;
-// Boolean isDefaultBoolean = null;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- validatorIDString = (String)pair.getValue();
- //isDefault not used in emf model
-// } else if ("isDefault".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_BOOLEAN) { //$NON-NLS-1$
-// isDefaultBoolean = (Boolean)pair.getValue();
+ // Boolean isDefaultBoolean = null;
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ validatorIDString = (String) pair.getValue();
+ // isDefault not used in emf model
+ // } else if ("isDefault".equals(pair.getMemberName()) &&
+ // pair.getValueKind() == IMemberValuePair.K_BOOLEAN) { //$NON-NLS-1$
+ // isDefaultBoolean = (Boolean)pair.getValue();
}
}
}
-
- if (validatorClassName != null && validatorIDString != null) {
+
+ if (validatorClassName != null && validatorIDString != null)
+ {
ValidatorType validator = FacesConfigFactory.eINSTANCE.createValidatorType();
ValidatorClassType validatorClass = FacesConfigFactory.eINSTANCE.createValidatorClassType();
validatorClass.setTextContent(validatorClassName);
validator.setValidatorClass(validatorClass);
-
+
ValidatorIdType validatorID = FacesConfigFactory.eINSTANCE.createValidatorIdType();
validatorID.setTextContent(validatorIDString);
validator.setValidatorId(validatorID);
-
-// if (isDefaultBoolean == null) {
-// isDefaultBoolean = Boolean.FALSE;
-// }
-
+ // if (isDefaultBoolean == null) {
+ // isDefaultBoolean = Boolean.FALSE;
+ // }
+
facesConfig.getValidator().add(validator);
}
}
- private void addRenderer(IAnnotation rendererAnnotation, IType rendererType) throws JavaModelException {
+ private void addRenderer(IAnnotation rendererAnnotation, IType rendererType) throws JavaModelException
+ {
String rendererClassName = rendererType.getFullyQualifiedName();
IMemberValuePair[] pairs = rendererAnnotation.getMemberValuePairs();
String rendererTypeString = null;
String componentFamilyString = null;
String renderKitIDString = null;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("rendererType".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- rendererTypeString = (String)pair.getValue();
- } else if ("componentFamily".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- componentFamilyString = (String)pair.getValue();
- } else if ("renderKitId".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- renderKitIDString = (String)pair.getValue();
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("rendererType".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ rendererTypeString = (String) pair.getValue();
+ }
+ else if ("componentFamily".equals(pair.getMemberName()) //$NON-NLS-1$
+ && pair.getValueKind() == IMemberValuePair.K_STRING)
+ {
+ componentFamilyString = (String) pair.getValue();
+ }
+ else if ("renderKitId".equals(pair.getMemberName()) //$NON-NLS-1$
+ && pair.getValueKind() == IMemberValuePair.K_STRING)
+ {
+ renderKitIDString = (String) pair.getValue();
}
}
}
-
- if (rendererClassName != null && rendererTypeString != null && componentFamilyString != null) {
+
+ if (rendererClassName != null && rendererTypeString != null && componentFamilyString != null)
+ {
RendererType renderer = FacesConfigFactory.eINSTANCE.createRendererType();
RendererClassType rendererClass = FacesConfigFactory.eINSTANCE.createRendererClassType();
rendererClass.setTextContent(rendererClassName);
renderer.setRendererClass(rendererClass);
-
RendererTypeType rendererTypeType = FacesConfigFactory.eINSTANCE.createRendererTypeType();
rendererTypeType.setTextContent(rendererTypeString);
renderer.setRendererType(rendererTypeType);
-
+
ComponentFamilyType componentFamily = FacesConfigFactory.eINSTANCE.createComponentFamilyType();
componentFamily.setTextContent(componentFamilyString);
renderer.setComponentFamily(componentFamily);
-
- if (renderKitIDString == null) {
- //use the default
+ if (renderKitIDString == null)
+ {
+ // use the default
renderKitIDString = "HTML_BASIC"; //$NON-NLS-1$
}
EList renderKits = facesConfig.getRenderKit();
- if (renderKits != null) {
+ if (renderKits != null)
+ {
RenderKitType renderKit = null;
- for (int i = 0, k = renderKits.size(); i < k; i++) {
- if (((RenderKitType)renderKits.get(i)).getRenderKitId() != null && renderKitIDString.equals(((RenderKitType)renderKits.get(i)).getRenderKitId().getTextContent())) {
- renderKit = (RenderKitType)(renderKits.get(i));
+ for (int i = 0, k = renderKits.size(); i < k; i++)
+ {
+ if (((RenderKitType) renderKits.get(i)).getRenderKitId() != null && renderKitIDString
+ .equals(((RenderKitType) renderKits.get(i)).getRenderKitId().getTextContent()))
+ {
+ renderKit = (RenderKitType) (renderKits.get(i));
}
}
- if (renderKit == null) {
+ if (renderKit == null)
+ {
renderKit = FacesConfigFactory.eINSTANCE.createRenderKitType();
RenderKitIdType renderKitID = FacesConfigFactory.eINSTANCE.createRenderKitIdType();
renderKitID.setTextContent(renderKitIDString);
@@ -312,34 +474,43 @@
}
}
- private void addConverter(IAnnotation converterAnnotation, IType converterType) throws JavaModelException {
+ private void addConverter(IAnnotation converterAnnotation, IType converterType) throws JavaModelException
+ {
String converterClassName = converterType.getFullyQualifiedName();
IMemberValuePair[] pairs = converterAnnotation.getMemberValuePairs();
String converterIDString = null;
String converterForClassString = null;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- converterIDString = (String)pair.getValue();
- } else if ("forClass".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_CLASS) { //$NON-NLS-1$
- converterForClassString = (String)pair.getValue();
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ converterIDString = (String) pair.getValue();
+ }
+ else if ("forClass".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_CLASS) //$NON-NLS-1$
+ {
+ converterForClassString = (String) pair.getValue();
}
}
}
- if (converterClassName != null) {
+ if (converterClassName != null)
+ {
ConverterType converter = FacesConfigFactory.eINSTANCE.createConverterType();
ConverterClassType converterClass = FacesConfigFactory.eINSTANCE.createConverterClassType();
converterClass.setTextContent(converterClassName);
converter.setConverterClass(converterClass);
- if (converterIDString != null) {
+ if (converterIDString != null)
+ {
ConverterIdType converterID = FacesConfigFactory.eINSTANCE.createConverterIdType();
converterID.setTextContent(converterIDString);
converter.setConverterId(converterID);
- }
-
- if (converterForClassString == null) {
- //use the default
+ }
+
+ if (converterForClassString == null)
+ {
+ // use the default
converterForClassString = "java.lang.Object"; //$NON-NLS-1$
}
ConverterForClassType converterForClass = FacesConfigFactory.eINSTANCE.createConverterForClassType();
@@ -349,45 +520,56 @@
}
}
- private void addComponent(IAnnotation componentAnnotation, IType componentType) throws JavaModelException {
+ private void addComponent(IAnnotation componentAnnotation, IType componentType) throws JavaModelException
+ {
String componentClassName = componentType.getFullyQualifiedName();
IMemberValuePair[] pairs = componentAnnotation.getMemberValuePairs();
String componentTypeString = null;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- componentTypeString = (String)pair.getValue();
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ componentTypeString = (String) pair.getValue();
}
}
}
- if (componentTypeString != null && componentClassName != null) {
- ComponentType component = FacesConfigFactory.eINSTANCE.createComponentType();
+ if (componentTypeString != null && componentClassName != null)
+ {
+ ComponentType component = FacesConfigFactory.eINSTANCE.createComponentType();
ComponentClassType componentClass = FacesConfigFactory.eINSTANCE.createComponentClassType();
componentClass.setTextContent(componentClassName);
component.setComponentClass(componentClass);
-
+
ComponentTypeType componentTypeType = FacesConfigFactory.eINSTANCE.createComponentTypeType();
componentTypeType.setTextContent(componentTypeString);
component.setComponentType(componentTypeType);
-
+
facesConfig.getComponent().add(component);
}
}
- private void addCDINamedBean(IAnnotation beanAnnotation, IType beanType) throws JavaModelException {
+ private void addCDINamedBean(IAnnotation beanAnnotation, JDTBeanIntrospector beanIntrospector, IType beanType) throws JavaModelException
+ {
IMemberValuePair[] pairs = beanAnnotation.getMemberValuePairs();
String beanNameString = null;
- if (pairs != null) {
- for (IMemberValuePair pair : pairs) {
- if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) { //$NON-NLS-1$
- beanNameString = (String)pair.getValue();
+ if (pairs != null)
+ {
+ for (IMemberValuePair pair : pairs)
+ {
+ if ("value".equals(pair.getMemberName()) && pair.getValueKind() == IMemberValuePair.K_STRING) //$NON-NLS-1$
+ {
+ beanNameString = (String) pair.getValue();
}
}
}
- if (beanNameString == null || beanNameString.length() < 1) {
+ if (beanNameString == null || beanNameString.length() < 1)
+ {
beanNameString = beanType.getElementName();
- if (beanNameString != null && beanNameString.length() > 0) {
+ if (beanNameString != null && beanNameString.length() > 0)
+ {
StringBuffer casedName = new StringBuffer(String.valueOf(beanNameString.charAt(0)).toLowerCase());
beanNameString = casedName.append(beanNameString.substring(1)).toString();
}
@@ -395,30 +577,10 @@
String beanClassName = beanType.getFullyQualifiedName();
- String beanScopeString = "dependent"; //$NON-NLS-1$
- IAnnotation[] annotations = beanType.getAnnotations();
- if (annotations != null) {
- for (int i = 0, k = annotations.length; i < k; i++) {
- if (annotations[i].exists()) {
- String annotationType = annotations[i].getElementName();
- String[][] resolvedAnnotationTypes = beanType.resolveType(annotationType);
- if (resolvedAnnotationTypes != null) {
- String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString();
- if (CDI_REQUEST_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "request"; //$NON-NLS-1$
- } else if (CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "conversation"; //$NON-NLS-1$
- } else if (CDI_SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "session"; //$NON-NLS-1$
- } else if (CDI_APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "application"; //$NON-NLS-1$
- }
- }
- }
- }
- }
+ String beanScopeString = processCDIScopeAnnotations(beanType, beanIntrospector);
- if (beanNameString != null && beanClassName != null) {
+ if (beanNameString != null && beanClassName != null)
+ {
ManagedBeanType bean = FacesConfigFactory.eINSTANCE.createManagedBeanType();
ManagedBeanNameType beanName = FacesConfigFactory.eINSTANCE.createManagedBeanNameType();
beanName.setTextContent(beanNameString);
@@ -435,9 +597,70 @@
}
}
- private void addCDIModelBean(IType beanType) throws JavaModelException {
+ private String processCDIScopeAnnotations(IType beanType, JDTBeanIntrospector beanIntrospector) throws JavaModelException
+ {
+ String beanScopeString = "dependent"; //$NON-NLS-1$
+ IAnnotation[] annotations = beanType.getAnnotations();
+ if (annotations == null)
+ {
+ return beanScopeString;
+ }
+ for (IAnnotation annotation : annotations)
+ {
+ String scope = processCDIScopeAnnotation(beanType, beanIntrospector, annotation);
+ if (scope != null)
+ {
+ beanScopeString = scope;
+ }
+ }
+ return beanScopeString;
+ }
+
+ private String processCDIScopeAnnotation(IType beanType, JDTBeanIntrospector beanIntrospector, IAnnotation annotation)
+ {
+ if (!annotation.exists())
+ {
+ return null;
+ }
+ String annotationType = annotation.getElementName();
+ if (! isCDIScopeAnnotationCandidate(annotationType))
+ {
+ return null;
+ }
+ String annotationClassName = beanIntrospector.resolveFullQualifiedTypeName(annotationType);
+ if (annotationClassName == null)
+ {
+ return null;
+ }
+ if (CDI_REQUEST_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "request"; //$NON-NLS-1$
+ }
+ else if (CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "conversation"; //$NON-NLS-1$
+ }
+ else if (CDI_SESSION_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "session"; //$NON-NLS-1$
+ }
+ else if (CDI_APPLICATION_SCOPED_ANNOTATION_CLASS.equals(annotationClassName))
+ {
+ return "application"; //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ private boolean isCDIScopeAnnotationCandidate(String annotationType)
+ {
+ return CDI_SCOPED_ANNOTATION_CANDIDATES.contains(annotationType);
+ }
+
+ private void addCDIModelBean(IType beanType) throws JavaModelException
+ {
String beanNameString = beanType.getElementName();
- if (beanNameString != null && beanNameString.length() > 0) {
+ if (beanNameString != null && beanNameString.length() > 0)
+ {
StringBuffer casedName = new StringBuffer(String.valueOf(beanNameString.charAt(0)).toLowerCase());
beanNameString = casedName.append(beanNameString.substring(1)).toString();
}
@@ -446,26 +669,37 @@
String beanScopeString = "request"; //$NON-NLS-1$
IAnnotation[] annotations = beanType.getAnnotations();
- if (annotations != null) {
- for (int i = 0, k = annotations.length; i < k; i++) {
- if (annotations[i].exists()) {
+ if (annotations != null)
+ {
+ for (int i = 0, k = annotations.length; i < k; i++)
+ {
+ if (annotations[i].exists())
+ {
String annotationType = annotations[i].getElementName();
String[][] resolvedAnnotationTypes = beanType.resolveType(annotationType);
- if (resolvedAnnotationTypes != null) {
- String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.').append(resolvedAnnotationTypes[0][1]).toString();
- if (CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "conversation"; //$NON-NLS-1$
- } else if (CDI_SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "session"; //$NON-NLS-1$
- } else if (CDI_APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName)) {
- beanScopeString = "application"; //$NON-NLS-1$
+ if (resolvedAnnotationTypes != null)
+ {
+ String resolvedAnnotationClassName = new StringBuffer(resolvedAnnotationTypes[0][0]).append('.')
+ .append(resolvedAnnotationTypes[0][1]).toString();
+ if (CDI_CONVERSATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName))
+ {
+ beanScopeString = "conversation"; //$NON-NLS-1$
+ }
+ else if (CDI_SESSION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName))
+ {
+ beanScopeString = "session"; //$NON-NLS-1$
+ }
+ else if (CDI_APPLICATION_SCOPED_ANNOTATION_CLASS.equals(resolvedAnnotationClassName))
+ {
+ beanScopeString = "application"; //$NON-NLS-1$
}
}
}
- }
+ }
}
- if (beanNameString != null && beanClassName != null) {
+ if (beanNameString != null && beanClassName != null)
+ {
ManagedBeanType bean = FacesConfigFactory.eINSTANCE.createManagedBeanType();
ManagedBeanNameType beanName = FacesConfigFactory.eINSTANCE.createManagedBeanNameType();
beanName.setTextContent(beanNameString);
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/view/DTComponentIntrospector.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/view/DTComponentIntrospector.java
index 3a9b89a..8a12976 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/view/DTComponentIntrospector.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/designtime/internal/view/DTComponentIntrospector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2011 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Oracle Corporation - initial API and implementation
+ * Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy - Use cached JDTBeanIntrospector
*******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view;
@@ -357,9 +358,7 @@
if (type != null)
{
- // TODO: should be able to use type cache for this
- final JDTBeanIntrospector introspector = new JDTBeanIntrospector(
- type);
+ final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
properties = introspector.getProperties();
}
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/appconfig/PropertyNameValidationVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/appconfig/PropertyNameValidationVisitor.java
index 3c3d3f2..0d949a0 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/appconfig/PropertyNameValidationVisitor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/appconfig/PropertyNameValidationVisitor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2010 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Oracle Corporation - initial API and implementation
+ * Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy - Use cached JDTBeanIntrospector
*******************************************************************************/
package org.eclipse.jst.jsf.validation.internal.appconfig;
@@ -54,11 +55,13 @@
_typeCache = new HashMap<String, IType>();
}
+ @Override
protected EObjectValidationVisitor[] getChildNodeValidators()
{
return PropertyValidationVisitor.NO_CHILDREN;
}
+ @Override
protected void doValidate(EObject object, List messages, IFile file)
{
final String parentClassType = getParentClassType(object);
@@ -144,7 +147,7 @@
private Map<String, JDTBeanProperty> getProperties(final IType type, final IProject project)
{
- final JDTBeanIntrospector introspector = new JDTBeanIntrospector(type);
+ final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(type);
return introspector.getProperties();
}
diff --git a/jsf/tests/org.eclipse.jst.jsf.context.symbol.tests/src/org/eclipse/jst/jsf/context/symbol/tests/TestIJavaTypeDescriptor2_ChangeStability.java b/jsf/tests/org.eclipse.jst.jsf.context.symbol.tests/src/org/eclipse/jst/jsf/context/symbol/tests/TestIJavaTypeDescriptor2_ChangeStability.java
index a623456..a92f1a1 100644
--- a/jsf/tests/org.eclipse.jst.jsf.context.symbol.tests/src/org/eclipse/jst/jsf/context/symbol/tests/TestIJavaTypeDescriptor2_ChangeStability.java
+++ b/jsf/tests/org.eclipse.jst.jsf.context.symbol.tests/src/org/eclipse/jst/jsf/context/symbol/tests/TestIJavaTypeDescriptor2_ChangeStability.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2001, 2007 Oracle Corporation and others.
+ * Copyright (c) 2001, 2021 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -8,7 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Oracle Corporation - initial API and implementation
+ * Oracle Corporation - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache resolved types
*******************************************************************************/
package org.eclipse.jst.jsf.context.symbol.tests;
@@ -20,6 +21,7 @@
import org.eclipse.jdt.core.ICompilationUnit;
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.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
@@ -29,7 +31,7 @@
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jface.text.Document;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
-import org.eclipse.jst.jsf.common.util.TypeUtil;
+import org.eclipse.jst.jsf.common.util.JDTTypeResolver;
import org.eclipse.jst.jsf.context.symbol.IBeanInstanceSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IJavaTypeDescriptor2;
@@ -52,6 +54,7 @@
*/
public class TestIJavaTypeDescriptor2_ChangeStability extends ModelBaseTestCase
{
+ private static final IType[] EMPTY_SUPER_TYPES = new IType[0];
private IBeanInstanceSymbol _testBean1Symbol;
private IBeanInstanceSymbol _testBean2Symbol;
@@ -64,6 +67,7 @@
private final static String testBeanName1 = "TestBean1";
private final static String testBeanName2 = "TestBean2";
+ @Override
protected void setUp() throws Exception
{
super.setUp();
@@ -111,6 +115,7 @@
return bean;
}
+ @Override
protected void tearDown() throws Exception
{
super.tearDown();
@@ -129,7 +134,7 @@
IType type = _testBean1Symbol.getJavaTypeDescriptor().getType();
IMethod newMethod = type.createMethod(NON_BEAN_METHOD_CONTENTS, null, true, null);
assertNotNull(newMethod);
- assertEquals(NON_BEAN_METHOD_SIG, TypeUtil.resolveMethodSignature(type, newMethod.getSignature()));
+ assertEquals(NON_BEAN_METHOD_SIG, resolveMethodSignature(type, newMethod));
assertTrue(newMethod.exists());
// post-cond: bean has new method
@@ -184,7 +189,7 @@
IMethod newMethod = type.createMethod(BEAN_METHOD_CONTENTS, null, true, null);
assertNotNull(newMethod);
assertTrue(newMethod.exists());
- assertEquals(BEAN_METHOD_SIG, TypeUtil.resolveMethodSignature(type, newMethod.getSignature()));
+ assertEquals(BEAN_METHOD_SIG, resolveMethodSignature(type, newMethod));
{
// post-cond: bean has new method
@@ -218,7 +223,7 @@
IType type = _testBean1Symbol.getJavaTypeDescriptor().getType();
IMethod method = type.getMethod(EXISTING_BEAN_METHOD, new String[0]);
assertNotNull(method);
- assertEquals(EXISTING_BEAN_METHOD_SIG, TypeUtil.resolveMethodSignature(type, method.getSignature()));
+ assertEquals(EXISTING_BEAN_METHOD_SIG, resolveMethodSignature(type, method));
assertTrue(method.exists());
method.delete(true, null);
assertFalse(method.exists());
@@ -253,7 +258,7 @@
IType type = _testBean1Symbol.getJavaTypeDescriptor().getType();
IMethod method = type.getMethod(EXISTING_BEAN_METHOD, new String[0]);
assertNotNull(method);
- assertEquals(EXISTING_BEAN_METHOD_SIG, TypeUtil.resolveMethodSignature(type, method.getSignature()));
+ assertEquals(EXISTING_BEAN_METHOD_SIG, resolveMethodSignature(type, method));
assertTrue(method.exists());
method.rename(NEW_READONLY_BEAN_METHOD_NAME, false, null);
method = type.getMethod(NEW_READONLY_BEAN_METHOD_NAME, new String[0]);
@@ -283,7 +288,7 @@
_beanProperties.put(prop.getName(), prop);
compareSymbolMaps(_beanProperties, newProperties);
}
-
+
private static final String READONLY_BEAN_REPLACEMENT_METHOD =
"public Integer "+EXISTING_BEAN_METHOD+"(){return new Integer(4);}";
private static final String READONLY_BEAN_REPLACEMENT_SIG =
@@ -518,4 +523,10 @@
cu.getBuffer().setContents(newSource);
cu.commitWorkingCopy(true, null);
}
+
+ private String resolveMethodSignature(IType type, IMethod method) throws JavaModelException
+ {
+ return new JDTTypeResolver(type, EMPTY_SUPER_TYPES).resolveMethodEraseTypeParams(method.getSignature());
+ }
+
}
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanIntrospector.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanIntrospector.java
index 69259f1..d878784 100644
--- a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanIntrospector.java
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanIntrospector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 Oracle Corporation.
+ * Copyright (c) 2006, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+* Reto Weiss/Axon Ivy - Cache resolved types
*
********************************************************************************/
@@ -16,8 +17,6 @@
import java.util.Map;
-import junit.framework.TestCase;
-
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IType;
@@ -25,13 +24,14 @@
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
-import org.eclipse.jst.jsf.common.util.JDTBeanPropertyWorkingCopy;
import org.eclipse.jst.jsf.core.tests.TestsPlugin;
import org.eclipse.jst.jsf.test.util.JDTTestEnvironment;
import org.eclipse.jst.jsf.test.util.JSFTestUtil;
import org.eclipse.jst.jsf.test.util.TestFileResource;
import org.eclipse.jst.jsf.test.util.WebProjectTestEnvironment;
+import junit.framework.TestCase;
+
/**
* Tester fot he JDTBeanIntrospector class
*
@@ -144,17 +144,16 @@
// introspect after classes loaded to ensure all dependencies
// are in the project
- JDTBeanIntrospector beanIntrospector =
- new JDTBeanIntrospector(_testBean1Type);
+ JDTBeanIntrospector beanIntrospector = JDTBeanIntrospector.forType(_testBean1Type);
_properties = beanIntrospector.getProperties();
- beanIntrospector = new JDTBeanIntrospector(_testBeanSubclassType);
+ beanIntrospector = JDTBeanIntrospector.forType(_testBeanSubclassType);
_subClassProperties = beanIntrospector.getProperties();
- beanIntrospector = new JDTBeanIntrospector(_testBeanGenericType);
+ beanIntrospector = JDTBeanIntrospector.forType(_testBeanGenericType);
_genericTypeProperties = beanIntrospector.getProperties();
- beanIntrospector = new JDTBeanIntrospector(_testInterface);
+ beanIntrospector = JDTBeanIntrospector.forType(_testInterface);
_interfaceProperties = beanIntrospector.getProperties();
}
@@ -197,13 +196,6 @@
.size());
assertNull("Empty string is invalid property name", properties.get(""));
assertNull("Null is not a valid property name", properties.get(null));
-
- // ensure type correctness of all values
- for (final JDTBeanProperty value : properties.values())
- {
- // no working copies should slip their way in
- assertFalse(value instanceof JDTBeanPropertyWorkingCopy);
- }
}
/**
@@ -622,9 +614,7 @@
{
final JDTBeanProperty property =
_genericTypeProperties.get("listOfListOfStrings");
- assertEquals("Ljava.util.List;", property.getTypeSignature(true));
- assertEquals("Ljava.util.List<Ljava.util.List<Ljava.lang.String;>;>;",
- property.getTypeSignature(false));
+ assertEquals("Ljava.util.List;", property.getTypeSignature());
assertEquals(1, property.getTypeParameterSignatures().size());
assertEquals("Ljava.util.List<Ljava.lang.String;>;", property
@@ -635,9 +625,7 @@
{
final JDTBeanProperty property =
_genericTypeProperties.get("mapOfString_String");
- assertEquals("Ljava.util.Map;", property.getTypeSignature(true));
- assertEquals("Ljava.util.Map<Ljava.lang.String;Ljava.lang.String;>;",
- property.getTypeSignature(false));
+ assertEquals("Ljava.util.Map;", property.getTypeSignature());
assertEquals(2, property.getTypeParameterSignatures().size());
assertEquals("Ljava.lang.String;", property
@@ -650,9 +638,7 @@
public void testUnboundedProperty_List() throws Exception
{
final JDTBeanProperty property = _genericTypeProperties.get("unboundedList");
- assertEquals("Ljava.util.List;", property.getTypeSignature(true));
- assertEquals("Ljava.util.List<Ljava.lang.Object;>;", property
- .getTypeSignature(false));
+ assertEquals("Ljava.util.List;", property.getTypeSignature());
assertEquals(1, property.getTypeParameterSignatures().size());
assertEquals("Ljava.lang.Object;", property
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanPropertyWorkingCopy.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanPropertyWorkingCopy.java
index 522e0f2..4562267 100644
--- a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanPropertyWorkingCopy.java
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestJDTBeanPropertyWorkingCopy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2008 Oracle Corporation.
+ * Copyright (c) 2006, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,12 +9,11 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache resolved types *
*
********************************************************************************/
package org.eclipse.jst.jsf.core.tests.util;
-import junit.framework.TestCase;
-
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IMethod;
@@ -22,12 +21,15 @@
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
import org.eclipse.jst.jsf.common.util.JDTBeanPropertyWorkingCopy;
+import org.eclipse.jst.jsf.common.util.JDTTypeResolver;
import org.eclipse.jst.jsf.core.tests.TestsPlugin;
import org.eclipse.jst.jsf.test.util.JDTTestEnvironment;
import org.eclipse.jst.jsf.test.util.JSFTestUtil;
import org.eclipse.jst.jsf.test.util.TestFileResource;
import org.eclipse.jst.jsf.test.util.WebProjectTestEnvironment;
+import junit.framework.TestCase;
+
/**
* Tests basic operations on the jdt bean property
*
@@ -95,8 +97,7 @@
*/
public void testSimpleBeanProperty()
{
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type.getMethod("getStringProp1", new String[0]);
@@ -132,8 +133,7 @@
*/
public void testSimpleIsBeanProperty()
{
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type.getMethod("isBooleanIsProp1", new String[0]);
@@ -171,8 +171,7 @@
*/
public void testIsAccessorTakesPrecedence()
{
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleIsGetter =
_testBean1Type.getMethod("isBooleanIsProp2", new String[0]);
@@ -254,8 +253,7 @@
*/
public void testDoNotUseSetterIfDoesNotMatchGetterType()
{
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type.getMethod("getStringProperty2", new String[0]);
@@ -295,8 +293,7 @@
public void testReadonlyBeanProperty()
{
// readonly get
- JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type.getMethod("getReadonlyStringProperty",
@@ -326,7 +323,7 @@
// should be an IType for a String
assertNotNull(beanProperty.getType());
- workingCopy = new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ workingCopy = createPropertyWorkingCopy();
// readonly is getter
final IMethod isGetter =
@@ -365,8 +362,7 @@
public void testWriteonlyBeanProperty()
{
// readonly get
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleSetter =
_testBean1Type.getMethod("setWriteonlyStringProperty",
@@ -403,8 +399,7 @@
public void testStringArrayProperty()
{
// readonly get
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type.getMethod("getStringArrayProperty",
@@ -444,8 +439,7 @@
public void testCollectionProperty()
{
// readonly get
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type
@@ -485,8 +479,7 @@
public void testMapProperty()
{
// readonly get
- final JDTBeanPropertyWorkingCopy workingCopy =
- new JDTBeanPropertyWorkingCopy(_testBean1Type);
+ final JDTBeanPropertyWorkingCopy workingCopy = createPropertyWorkingCopy();
final IMethod simpleGetter =
_testBean1Type.getMethod("getMapProperty", new String[0]);
@@ -518,4 +511,9 @@
assertNotNull(beanProperty.getType());
}
+ private JDTBeanPropertyWorkingCopy createPropertyWorkingCopy()
+ {
+ return new JDTBeanPropertyWorkingCopy(_testBean1Type, new JDTTypeResolver(_testBean1Type, new IType[0]), "StringProp1");
+ }
+
}
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestTypeUtil.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestTypeUtil.java
index 62036e7..6f90630 100644
--- a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestTypeUtil.java
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/util/TestTypeUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Oracle Corporation.
+ * Copyright (c) 2007, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache resolved types
*
********************************************************************************/
package org.eclipse.jst.jsf.core.tests.util;
@@ -16,12 +17,11 @@
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
+import org.eclipse.jst.jsf.common.util.JDTTypeResolver;
import org.eclipse.jst.jsf.common.util.TypeUtil;
import org.eclipse.jst.jsf.core.tests.TestsPlugin;
import org.eclipse.jst.jsf.test.util.JDTTestEnvironment;
@@ -29,8 +29,12 @@
import org.eclipse.jst.jsf.test.util.TestFileResource;
import org.eclipse.jst.jsf.test.util.WebProjectTestEnvironment;
+import junit.framework.TestCase;
+
public class TestTypeUtil extends TestCase
{
+ private static final IType[] EMPTY_SUPER_TYPES = new IType[0];
+
private JDTTestEnvironment _jdtTestEnvironment;
private IType _testBean1Type;
private IType _testBeanSubclassType;
@@ -52,6 +56,7 @@
// private final static String testEnumName2 = "TestEnum2";
+ @Override
protected void setUp() throws Exception
{
super.setUp();
@@ -153,6 +158,7 @@
// new JDTBeanIntrospector(_testBeanGenericType);
}
+ @Override
protected void tearDown() throws Exception
{
super.tearDown();
@@ -169,28 +175,28 @@
public void testResolveTypeSignatureITypeString()
{
// this one should be the same regardless of type erasure
- assertEquals(TypeConstants.TYPE_STRING, TypeUtil.resolveTypeSignature(
- _testBean1Type, "QString;", true));
- assertEquals(TypeConstants.TYPE_STRING, TypeUtil.resolveTypeSignature(
- _testBean1Type, "QString;", false));
+ assertEquals(TypeConstants.TYPE_STRING,
+ resolver(_testBean1Type).resolveEraseTypeParams("QString;"));
+ assertEquals(TypeConstants.TYPE_STRING,
+ resolver(_testBean1Type).resolveKeepTypeParams("QString;"));
// no parameters are provided here, so we should see the same result
- assertEquals(TypeConstants.TYPE_COLLECTION, TypeUtil
- .resolveTypeSignature(_testBean1Type, "QCollection;", true));
- assertEquals(TypeConstants.TYPE_COLLECTION, TypeUtil
- .resolveTypeSignature(_testBean1Type, "QCollection;", false));
- assertEquals(TypeConstants.TYPE_MAP, TypeUtil.resolveTypeSignature(
- _testBean1Type, "QMap;", true));
- assertEquals(TypeConstants.TYPE_MAP, TypeUtil.resolveTypeSignature(
- _testBean1Type, "QMap;", false));
+ assertEquals(TypeConstants.TYPE_COLLECTION,
+ resolver(_testBean1Type).resolveEraseTypeParams("QCollection;"));
+ assertEquals(TypeConstants.TYPE_COLLECTION,
+ resolver(_testBean1Type).resolveKeepTypeParams("QCollection;"));
+ assertEquals(TypeConstants.TYPE_MAP,
+ resolver(_testBean1Type).resolveEraseTypeParams("QMap;"));
+ assertEquals(TypeConstants.TYPE_MAP,
+ resolver(_testBean1Type).resolveKeepTypeParams("QMap;"));
// in this case, the provided signature has type erasure, so the answer
// will different depending on typeErasure flag
- final String typeSigWithErasure = TypeUtil.resolveTypeSignature(
- _testBean1Type, "QMap<QString;QString;>;", true);
+ final String typeSigWithErasure = resolver(_testBean1Type)
+ .resolveEraseTypeParams("QMap<QString;QString;>;");
assertEquals(TypeConstants.TYPE_MAP, typeSigWithErasure);
- final String typeSigNoErasure = TypeUtil.resolveTypeSignature(
- _testBean1Type, "QMap<QString;QString;>;", false);
+ final String typeSigNoErasure = resolver(_testBean1Type)
+ .resolveKeepTypeParams("QMap<QString;QString;>;");
assertEquals("Ljava.util.Map<Ljava.lang.String;Ljava.lang.String;>;",
typeSigNoErasure);
@@ -198,28 +204,28 @@
final IType mapType = TypeUtil.resolveType(_jdtTestEnvironment
.getJavaProject(), "Ljava.util.Map;");
assertNotNull(mapType);
- assertEquals(TypeConstants.TYPE_JAVAOBJECT, TypeUtil
- .resolveTypeSignature(mapType, "TV;", false));
+ assertEquals(TypeConstants.TYPE_JAVAOBJECT,
+ resolver(mapType).resolveKeepTypeParams("TV;"));
// unfound signature
- assertEquals("QSomeNotRealClass;", TypeUtil.resolveTypeSignature(
- _testBean1Type, "QSomeNotRealClass;", false));
+ assertEquals("QSomeNotRealClass;",
+ resolver(_testBean1Type).resolveKeepTypeParams("QSomeNotRealClass;"));
// arrays
- assertEquals("[I", TypeUtil.resolveTypeSignature(_testBean1Type, "[I"));
+ assertEquals("[I", resolver(_testBean1Type).resolveEraseTypeParams("[I"));
- assertEquals("[Ljava.lang.String;", TypeUtil.resolveTypeSignature(
- _testBean1Type, "[QString;"));
+ assertEquals("[Ljava.lang.String;",
+ resolver(_testBean1Type).resolveKeepTypeParams("[QString;"));
- assertEquals("[Ljava.util.Map;", TypeUtil.resolveTypeSignature(
- _testBean1Type, "[QMap;"));
+ assertEquals("[Ljava.util.Map;",
+ resolver(_testBean1Type).resolveKeepTypeParams("[QMap;"));
- assertEquals("[Ljava.util.Collection;", TypeUtil.resolveTypeSignature(
- _testBean1Type, "[QCollection;"));
+ assertEquals("[Ljava.util.Collection;",
+ resolver(_testBean1Type).resolveKeepTypeParams("[QCollection;"));
// array of arrays
- assertEquals("[[[Ljava.lang.String;", TypeUtil.resolveTypeSignature(
- _testBean1Type, "[[[QString;"));
+ assertEquals("[[[Ljava.lang.String;",
+ resolver(_testBean1Type).resolveKeepTypeParams("[[[QString;"));
// cover cases where wildcards and/or capture are used. All should be
// equivalent to the case for
@@ -235,50 +241,50 @@
final boolean typeErasure)
{
// extends
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<+QString;+QString;>;", typeErasure));
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<+QString;QString;>;", typeErasure));
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<QString;+QString;>;", typeErasure));
// super
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<-QString;-QString;>;", typeErasure));
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<-QString;QString;>;", typeErasure));
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<QString;-QString;>;", typeErasure));
// star
// this one is distinct because * are converted to Object
final String expected1 = "Ljava.util.Map"
+ (typeErasure ? ";"
: "<Ljava.lang.Object;Ljava.lang.Object;>;");
- assertEquals(expected1, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected1, resolveTypeSignature(_testBean1Type,
"QMap<**>;", typeErasure));
final String expected2 = "Ljava.util.Map"
+ (typeErasure ? ";"
: "<Ljava.lang.Object;Ljava.lang.String;>;");
- assertEquals(expected2, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected2, resolveTypeSignature(_testBean1Type,
"QMap<*QString;>;", typeErasure));
final String expected3 = "Ljava.util.Map"
+ (typeErasure ? ";"
: "<Ljava.lang.String;Ljava.lang.Object;>;");
- assertEquals(expected3, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected3, resolveTypeSignature(_testBean1Type,
"QMap<QString;*>;", typeErasure));
// capture extends
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<!+QString;!+QString;>;", typeErasure));
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<!+QString;QString;>;", typeErasure));
- assertEquals(expected, TypeUtil.resolveTypeSignature(_testBean1Type,
+ assertEquals(expected, resolveTypeSignature(_testBean1Type,
"QMap<QString;!+QString;>;", typeErasure));
- assertEquals("Ljava.lang.String;", TypeUtil.resolveTypeSignature(
+ assertEquals("Ljava.lang.String;", resolveTypeSignature(
_testBean1Type, "!+QString;", typeErasure));
// test regression on
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=197506
- assertEquals("Ljava.lang.Object;", TypeUtil.resolveTypeSignature(
+ assertEquals("Ljava.lang.Object;", resolveTypeSignature(
_testBean1Type, "*", typeErasure));
}
@@ -322,21 +328,21 @@
public void testResolveMethodSignature() throws Exception
{
- assertEquals("()Ljava.lang.String;", TypeUtil.resolveMethodSignature(
- _testBean1Type, "()QString;"));
- assertEquals("(Ljava.lang.String;)V", TypeUtil.resolveMethodSignature(
- _testBean1Type, "(QString;)V"));
- assertEquals("(Ljava.lang.String;Z)V", TypeUtil.resolveMethodSignature(
- _testBean1Type, "(QString;Z)V"));
+ assertEquals("()Ljava.lang.String;",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams("()QString;"));
+ assertEquals("(Ljava.lang.String;)V",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams("(QString;)V"));
+ assertEquals("(Ljava.lang.String;Z)V",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams("(QString;Z)V"));
IMethod method = _testBean1Type.getMethod("getStringProp1", null);
- assertEquals("()Ljava.lang.String;", TypeUtil.resolveMethodSignature(
- _testBean1Type, method.getSignature()));
+ assertEquals("()Ljava.lang.String;",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams(method.getSignature()));
method = _testBean1Type.getMethod("setStringProperty2", new String[]
{ "I" });
- assertEquals("(I)V", TypeUtil.resolveMethodSignature(_testBean1Type,
- method.getSignature()));
+ assertEquals("(I)V",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams(method.getSignature()));
// test binary methods
// the framework returns method signatures using "/" instead of "."
@@ -345,38 +351,36 @@
// sanity: _binaryType must a JDT BinaryType impl for this test to
// be valid
assertTrue(_binaryType.isBinary());
- assertEquals("()Ljava.lang.String;", TypeUtil.resolveMethodSignature(
- _binaryType, _binaryType.getMethod("getStringProperty", null)
+ assertEquals("()Ljava.lang.String;", resolver(_testBean1Type).resolveMethodEraseTypeParams(
+ _binaryType.getMethod("getStringProperty", null)
.getSignature()));
- assertEquals("(Ljava.lang.String;)V", TypeUtil.resolveMethodSignature(
- _binaryType, _binaryType.getMethod("setStringProperty",
+ assertEquals("(Ljava.lang.String;)V", resolver(_testBean1Type).resolveMethodEraseTypeParams(
+ _binaryType.getMethod("setStringProperty",
new String[]
{ "Ljava.lang.String;" }).getSignature()));
- assertEquals("()I", TypeUtil.resolveMethodSignature(_binaryType,
+ assertEquals("()I", resolver(_testBean1Type).resolveMethodEraseTypeParams(
_binaryType.getMethod("getIntegerProperty", null)
.getSignature()));
- assertEquals("(I)V", TypeUtil.resolveMethodSignature(_binaryType,
+ assertEquals("(I)V", resolver(_testBean1Type).resolveMethodEraseTypeParams(
_binaryType.getMethod("setIntegerProperty", new String[]
{ "I" }).getSignature()));
- assertEquals("()Lcom.test.BinaryPropertyAndMethodType;", TypeUtil
- .resolveMethodSignature(_binaryType, _binaryType.getMethod(
+ assertEquals("()Lcom.test.BinaryPropertyAndMethodType;",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams(_binaryType.getMethod(
"getUserDefined", null).getSignature()));
- assertEquals("(Lcom.test.BinaryPropertyAndMethodType;)V", TypeUtil
- .resolveMethodSignature(_binaryType, _binaryType.getMethod(
+ assertEquals("(Lcom.test.BinaryPropertyAndMethodType;)V",
+ resolver(_testBean1Type).resolveMethodEraseTypeParams(_binaryType.getMethod(
"setUserDefined", new String[]
{ "Lcom.test.BinaryPropertyAndMethodType;" })
.getSignature()));
assertEquals(
"(Ljava.lang.String;Lcom.test.BinaryPropertyAndMethodType;I)I",
- TypeUtil
- .resolveMethodSignature(
- _binaryType,
+ resolver(_testBean1Type).resolveMethodEraseTypeParams(
_binaryType
.getMethod(
"methodWithMultipleArgs",
@@ -443,4 +447,21 @@
assertTrue(TypeUtil.isEnumMember(type, "deadbeef"));
}
+
+ String resolveTypeSignature(IType type, String typeSignature, boolean erased)
+ {
+ if (erased)
+ {
+ return new JDTTypeResolver(type, EMPTY_SUPER_TYPES).resolveEraseTypeParams(typeSignature);
+ }
+ else
+ {
+ return new JDTTypeResolver(type, EMPTY_SUPER_TYPES).resolveKeepTypeParams(typeSignature);
+ }
+ }
+
+ JDTTypeResolver resolver(IType type)
+ {
+ return new JDTTypeResolver(type, EMPTY_SUPER_TYPES);
+ }
}
diff --git a/jsf/tests/org.eclipse.jst.jsf.designtime.tests/src/org/eclipse/jst/jsf/designtime/tests/TestDefaultPropertyResolver.java b/jsf/tests/org.eclipse.jst.jsf.designtime.tests/src/org/eclipse/jst/jsf/designtime/tests/TestDefaultPropertyResolver.java
index cdf0161..bb811d1 100644
--- a/jsf/tests/org.eclipse.jst.jsf.designtime.tests/src/org/eclipse/jst/jsf/designtime/tests/TestDefaultPropertyResolver.java
+++ b/jsf/tests/org.eclipse.jst.jsf.designtime.tests/src/org/eclipse/jst/jsf/designtime/tests/TestDefaultPropertyResolver.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2011 Oracle Corporation.
+ * Copyright (c) 2007, 2021 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
*
* Contributors:
* Cameron Bateman/Oracle - initial API and implementation
+ * Reto Weiss/Axon Ivy - Cache JDTBeanIntrospector
*
********************************************************************************/
package org.eclipse.jst.jsf.designtime.tests;
@@ -17,8 +18,6 @@
import java.util.HashMap;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IType;
@@ -44,6 +43,8 @@
import org.eclipse.jst.jsf.test.util.TestFileResource;
import org.eclipse.jst.jsf.test.util.WebProjectTestEnvironment;
+import junit.framework.TestCase;
+
/**
* Unit tests for the default property resolver
*
@@ -199,44 +200,43 @@
*/
public void testSanity()
{
- JDTBeanIntrospector beanIntrospector =
- new JDTBeanIntrospector(_testBean1Type);
+ JDTBeanIntrospector beanIntrospector = JDTBeanIntrospector.forType(_testBean1Type);
Map<String, JDTBeanProperty> props = beanIntrospector.getProperties();
assertEquals(NUM_PROPERTIES_TEST_BEAN_1, props.size());
assertTrue(props.containsKey("stringProp1"));
assertTrue(props.containsKey("booleanIsProp1"));
- beanIntrospector = new JDTBeanIntrospector(_testMapBean1Type);
+ beanIntrospector = JDTBeanIntrospector.forType(_testMapBean1Type);
props = beanIntrospector.getProperties();
// has 2 as a bean: isEmpty -> empty property + class
assertEquals(2, props.size());
- beanIntrospector = new JDTBeanIntrospector(_testBean2Type);
+ beanIntrospector = JDTBeanIntrospector.forType(_testBean2Type);
props = beanIntrospector.getProperties();
// two props: myBean3, class
assertEquals(2, props.size());
- beanIntrospector = new JDTBeanIntrospector(_testBean3Type);
+ beanIntrospector = JDTBeanIntrospector.forType(_testBean3Type);
props = beanIntrospector.getProperties();
// two props: one of type TestBean2 + class
assertEquals(2, props.size());
- beanIntrospector = new JDTBeanIntrospector(_testBeanWithMapProp);
+ beanIntrospector = JDTBeanIntrospector.forType(_testBeanWithMapProp);
props = beanIntrospector.getProperties();
// two props: one of type Map + class
assertEquals(2, props.size());
- beanIntrospector = new JDTBeanIntrospector(_testListBeanType);
+ beanIntrospector = JDTBeanIntrospector.forType(_testListBeanType);
props = beanIntrospector.getProperties();
// includes isEmpty and class
assertEquals(3, props.size());
- beanIntrospector = new JDTBeanIntrospector(_testBeanWithListPropType);
+ beanIntrospector = JDTBeanIntrospector.forType(_testBeanWithListPropType);
props = beanIntrospector.getProperties();
assertEquals(2, props.size());
beanIntrospector =
- new JDTBeanIntrospector(_testBeanWithGenericProperties);
+ JDTBeanIntrospector.forType(_testBeanWithGenericProperties);
props = beanIntrospector.getProperties();
assertEquals(3, props.size());
}