Skip to content

Commit

Permalink
STS-3171: performance optimization for BeanConstructorArgumentRule to…
Browse files Browse the repository at this point in the history
… use cached type hierarchy instead of Introspector.doesExtend
  • Loading branch information
martinlippert committed Jan 23, 2013
1 parent d5f21b4 commit d99048b
Showing 1 changed file with 56 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Spring IDE Developers
* Copyright (c) 2007, 2013 Spring IDE Developers
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand All @@ -15,6 +15,7 @@

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.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
Expand All @@ -27,21 +28,23 @@
import org.springframework.ide.eclipse.beans.core.model.validation.IBeansValidationContext;
import org.springframework.ide.eclipse.core.java.Introspector;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.springframework.ide.eclipse.core.java.SuperTypeHierarchyCache;
import org.springframework.ide.eclipse.core.model.IModelElement;

/**
* Helpers for validation rules.
*
* @author Torsten Juergeleit
* @author Christian Dupuis
* @author Terry Denney
* @author Martin Lippert
* @since 2.0
*/
public final class ValidationRuleUtils {

public static final String FACTORY_BEAN_REFERENCE_PREFIX = "&";

public static final String FACTORY_BEAN_REFERENCE_REGEXP = "["
+ FACTORY_BEAN_REFERENCE_PREFIX + "]";
public static final String FACTORY_BEAN_REFERENCE_REGEXP = "[" + FACTORY_BEAN_REFERENCE_PREFIX + "]";

public static final String ASPECT_OF_METHOD_NAME = "aspectOf";

Expand All @@ -64,12 +67,11 @@ public static String getBeanClassName(IBean bean) {

/**
* Returns the given {@link IBean bean}'s bean class name. For child beans
* the corresponding parents are resolved within the given context ({@link IBeansConfig}
* or {@link IBeansConfigSet}).
* the corresponding parents are resolved within the given context (
* {@link IBeansConfig} or {@link IBeansConfigSet}).
*/
public static String getBeanClassName(IBean bean, IModelElement context) {
BeanDefinition bd = BeansModelUtils.getMergedBeanDefinition(bean,
context);
BeanDefinition bd = BeansModelUtils.getMergedBeanDefinition(bean, context);
if (bd != null) {
return bd.getBeanClassName();
}
Expand All @@ -80,30 +82,46 @@ public static String getBeanClassName(IBean bean, IModelElement context) {
* Returns all registered {@link BeanDefinition} matching the given
* <code>beanName</code> and <code>beanClass</code>.
*/
public static Set<BeanDefinition> getBeanDefinitions(String beanName,
String beanClass, IBeansValidationContext context) {
public static Set<BeanDefinition> getBeanDefinitions(String beanName, String beanClass, IBeansValidationContext context) {
Set<BeanDefinition> beanDefinition = new HashSet<BeanDefinition>();
try {
beanDefinition.add(context.getCompleteRegistry().getBeanDefinition(
beanName));
}
catch (NoSuchBeanDefinitionException e) {
beanDefinition.add(context.getCompleteRegistry().getBeanDefinition(beanName));
} catch (NoSuchBeanDefinitionException e) {
// this is ok here
}

// fall back for manual installation of the post processor
for (String name : context.getCompleteRegistry()
.getBeanDefinitionNames()) {
IType[] allSubtypes = null;
try {
IType beanClassType = JdtUtils.getJavaType(context.getRootElementProject(), beanClass);
ITypeHierarchy hierarchy = SuperTypeHierarchyCache.getTypeHierarchy(beanClassType);
allSubtypes = hierarchy.getAllSubtypes(beanClassType);
}
catch (JavaModelException e) {
// ignore, falls back to JdtUtils.doesExtend
}

for (String name : context.getCompleteRegistry().getBeanDefinitionNames()) {
try {
BeanDefinition db = context.getCompleteRegistry()
.getBeanDefinition(name);
if (db.getBeanClassName() != null
&& Introspector.doesExtend(JdtUtils
.getJavaType(context.getRootElementProject(),
db.getBeanClassName()), beanClass)) {
beanDefinition.add(db);
BeanDefinition db = context.getCompleteRegistry().getBeanDefinition(name);
if (db.getBeanClassName() != null) {
if (db.getBeanClassName().equals(beanClass)) {
beanDefinition.add(db);
}
else if (allSubtypes != null) {
for (int i = 0; i < allSubtypes.length; i++) {
if (allSubtypes[i].getFullyQualifiedName().equals(db.getBeanClassName()) &&
allSubtypes[i].exists()) {
beanDefinition.add(db);
}
}
}
else if (Introspector.doesExtend(JdtUtils.getJavaType(context.getRootElementProject(), db.getBeanClassName()), beanClass)) {
beanDefinition.add(db);
}
}
}
catch (BeanDefinitionStoreException e1) {

} catch (BeanDefinitionStoreException e1) {
// ignore here
}
}
Expand All @@ -115,30 +133,22 @@ public static Set<BeanDefinition> getBeanDefinitions(String beanName,
* <p>
* Honors <code>factory-method</code>s and <code>factory-bean</code>.
*/
public static IType extractBeanClass(BeanDefinition bd, IBean bean,
String mergedClassName, IBeansValidationContext context) {

IType type = JdtUtils.getJavaType(BeansModelUtils.getProject(bean)
.getProject(), mergedClassName);
public static IType extractBeanClass(BeanDefinition bd, IBean bean, String mergedClassName, IBeansValidationContext context) {

IType type = JdtUtils.getJavaType(BeansModelUtils.getProject(bean).getProject(), mergedClassName);
// 1. factory-method on bean
if (bd.getFactoryMethodName() != null
&& bd.getFactoryBeanName() == null) {
if (bd.getFactoryMethodName() != null && bd.getFactoryBeanName() == null) {
type = extractTypeFromFactoryMethod(bd, type);
}
// 2. factory-method on factory-bean
else if (bd.getFactoryMethodName() != null
&& bd.getFactoryBeanName() != null) {
else if (bd.getFactoryMethodName() != null && bd.getFactoryBeanName() != null) {
try {
AbstractBeanDefinition factoryBd = (AbstractBeanDefinition) context
.getCompleteRegistry().getBeanDefinition(
bd.getFactoryBeanName());
IType factoryBeanType = extractBeanClass(factoryBd, bean,
factoryBd.getBeanClassName(), context);
AbstractBeanDefinition factoryBd = (AbstractBeanDefinition) context.getCompleteRegistry().getBeanDefinition(bd.getFactoryBeanName());
IType factoryBeanType = extractBeanClass(factoryBd, bean, factoryBd.getBeanClassName(), context);
if (factoryBeanType != null) {
type = extractTypeFromFactoryMethod(bd, factoryBeanType);
}
}
catch (NoSuchBeanDefinitionException e) {
} catch (NoSuchBeanDefinitionException e) {

}
}
Expand All @@ -150,27 +160,22 @@ else if (bd.getFactoryMethodName() != null
* the <code>factory-method</code>. The passed in {@link IType} <b>must</b>
* be the bean class or the resolved type of the factory bean in use.
*/
private static IType extractTypeFromFactoryMethod(BeanDefinition bd,
IType type) {
private static IType extractTypeFromFactoryMethod(BeanDefinition bd, IType type) {
String factoryMethod = bd.getFactoryMethodName();
try {
int argCount = (!bd.isAbstract() ? bd
.getConstructorArgumentValues().getArgumentCount() : -1);
int argCount = (!bd.isAbstract() ? bd.getConstructorArgumentValues().getArgumentCount() : -1);
Set<IMethod> methods = Introspector.getAllMethods(type);
for (IMethod method : methods) {
if (factoryMethod.equals(method.getElementName())
&& method.getParameterNames().length == argCount) {
type = JdtUtils.getJavaTypeFromSignatureClassName(method
.getReturnType(), type);
if (factoryMethod.equals(method.getElementName()) && method.getParameterNames().length == argCount) {
type = JdtUtils.getJavaTypeFromSignatureClassName(method.getReturnType(), type);
break;
}
}
}
catch (JavaModelException e) {
} catch (JavaModelException e) {
}
return type;
}

public static String getBeanName(IModelElement element) {
if (element instanceof IBean) {
return element.getElementName();
Expand All @@ -181,5 +186,4 @@ public static String getBeanName(IModelElement element) {
return null;
}


}

0 comments on commit d99048b

Please sign in to comment.