Repository: wicket Updated Branches: refs/heads/master 11e6c48b1 -> f0340a3ef
WICKET-5808 SpringBean, support generic beans Improved code and added test for exact matching with list element generic Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/f0340a3e Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/f0340a3e Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/f0340a3e Branch: refs/heads/master Commit: f0340a3ef62a18df14badb26acee01bf102b9a2c Parents: 11e6c48 Author: Andrea Del Bene <[email protected]> Authored: Mon Jan 19 23:52:15 2015 +0100 Committer: Andrea Del Bene <[email protected]> Committed: Mon Jan 19 23:52:15 2015 +0100 ---------------------------------------------------------------------- .../apache/wicket/spring/SpringBeanLocator.java | 70 +++++++++++--------- .../annot/AnnotProxyFieldValueFactory.java | 6 +- .../annot/SpringBeanWithGenericsTest.java | 31 +++++++-- 3 files changed, 67 insertions(+), 40 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/f0340a3e/wicket-spring/src/main/java/org/apache/wicket/spring/SpringBeanLocator.java ---------------------------------------------------------------------- diff --git a/wicket-spring/src/main/java/org/apache/wicket/spring/SpringBeanLocator.java b/wicket-spring/src/main/java/org/apache/wicket/spring/SpringBeanLocator.java index 593aed6..2626b14 100644 --- a/wicket-spring/src/main/java/org/apache/wicket/spring/SpringBeanLocator.java +++ b/wicket-spring/src/main/java/org/apache/wicket/spring/SpringBeanLocator.java @@ -20,20 +20,19 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import org.apache.wicket.core.util.lang.WicketObjects; import org.apache.wicket.proxy.IProxyTargetLocator; import org.apache.wicket.util.lang.Args; import org.apache.wicket.util.lang.Objects; -import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationContext; import org.springframework.context.support.AbstractApplicationContext; -import org.springframework.core.GenericCollectionTypeResolver; import org.springframework.core.ResolvableType; /** @@ -130,10 +129,7 @@ public class SpringBeanLocator implements IProxyTargetLocator { fieldName = beanField.getName(); fieldResolvableType = ResolvableType.forField(beanField); - - Class<?> collectionFieldType = GenericCollectionTypeResolver.getCollectionFieldType(beanField); - fieldCollectionResolvableType = collectionFieldType != null ? - ResolvableType.forClass(collectionFieldType) : null; + fieldCollectionResolvableType = fieldResolvableType.getGeneric(); } } @@ -239,22 +235,18 @@ public class SpringBeanLocator implements IProxyTargetLocator } // If the given class is a list try to get the generic of the list - Class<?> lookupClass = clazz == List.class ? + final boolean isList = clazz == List.class; + Class<?> lookupClass = isList ? fieldResolvableType.getGeneric(0).resolve() : clazz; // Else the lookup is done via Generic List<String> names = loadBeanNames(ctx, lookupClass); - List<Object> beansAsList = getBeansByName(ctx, names); + Object foundBeans = getBeansByName(ctx, names); - if(beansAsList.size() == 1) + if(foundBeans != null) { - return beansAsList.get(0); - } - - if (!beansAsList.isEmpty()) - { - return beansAsList; + return foundBeans; } throw new IllegalStateException( @@ -280,31 +272,44 @@ public class SpringBeanLocator implements IProxyTargetLocator private List<String> loadBeanNames(ApplicationContext ctx, Class<?> lookupClass) { List<String> beanNames = new ArrayList<>(); - String[] beanNamesArr = BeanFactoryUtils - .beanNamesForTypeIncludingAncestors(ctx, lookupClass); - - //add field name if defined - if (ctx.containsBean(fieldName)) + Class<?> fieldType = getBeanType(); + String[] beanNamesArr = ctx.getBeanNamesForType(fieldType); + + //add names for field class + beanNames.addAll(Arrays.asList(beanNamesArr)); + + //add names for lookup class + if (lookupClass != fieldType) { - beanNames.add(fieldName); + beanNamesArr = ctx.getBeanNamesForType(lookupClass); + beanNames.addAll(Arrays.asList(beanNamesArr)); } - - beanNames.addAll(Arrays.asList(beanNamesArr)); - + + Iterator<String> nameIterator = beanNames.iterator(); + + //filter those beans who don't have a definition (used internally by Spring) + while (nameIterator.hasNext()) + { + if (!ctx.containsBeanDefinition(nameIterator.next())) + { + nameIterator.remove(); + } + } + return beanNames; } /** - * Retrieves a list of beans for the given list of names and assignable to the + * Retrieves a list of beans or a single bean for the given list of names and assignable to the * current field to inject. * * @param ctx * spring application context. * @param names * the list of candidate names - * @return a list of matching beans. + * @return a list of matching beans or a single one. */ - private List<Object> getBeansByName(ApplicationContext ctx, List<String> names) + private Object getBeansByName(ApplicationContext ctx, List<String> names) { List<Object> beansAsList = new ArrayList<>(); @@ -349,10 +354,11 @@ public class SpringBeanLocator implements IProxyTargetLocator if (exactMatch) { this.beanName = beanName; - return beansAsList; + return ctx.getBean(beanName); } } - return beansAsList; + + return beansAsList.size() > 0 ? beansAsList : null; } @Override @@ -391,9 +397,11 @@ public class SpringBeanLocator implements IProxyTargetLocator { ConfigurableListableBeanFactory beanFactory = ((AbstractApplicationContext)ctx).getBeanFactory(); - BeanDefinition beanDef = beanFactory.getMergedBeanDefinition(name); + BeanDefinition beanDef = beanFactory.containsBean(name) ? + beanFactory.getMergedBeanDefinition(name) : null; - if (beanDef instanceof RootBeanDefinition) { + if (beanDef instanceof RootBeanDefinition) + { return (RootBeanDefinition)beanDef; } http://git-wip-us.apache.org/repos/asf/wicket/blob/f0340a3e/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java ---------------------------------------------------------------------- diff --git a/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java b/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java index 023fa36..82f05bf 100644 --- a/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java +++ b/wicket-spring/src/main/java/org/apache/wicket/spring/injection/annot/AnnotProxyFieldValueFactory.java @@ -225,10 +225,6 @@ public class AnnotProxyFieldValueFactory implements IFieldValueFactory private String getBeanNameOfClass(final ApplicationContext ctx, final Class<?> clazz, final Class<?> generic, final boolean required) { - // If the clazz is instance of List return null - if (clazz == List.class){ - return null; - } // get the list of all possible matching beans List<String> names = new ArrayList<>( Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(ctx, clazz))); @@ -281,10 +277,12 @@ public class AnnotProxyFieldValueFactory implements IFieldValueFactory return primaries.get(0); } } + if (generic != null) { return null; } + StringBuilder msg = new StringBuilder(); msg.append("More than one bean of type ["); msg.append(clazz.getName()); http://git-wip-us.apache.org/repos/asf/wicket/blob/f0340a3e/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java ---------------------------------------------------------------------- diff --git a/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java b/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java index 3523885..ba657ea 100644 --- a/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java +++ b/wicket-spring/src/test/java/org/apache/wicket/spring/injection/annot/SpringBeanWithGenericsTest.java @@ -77,8 +77,18 @@ public class SpringBeanWithGenericsTest extends Assert AnnotatedListField page = tester.startPage(new AnnotatedListField()); - assertNotNull(page.getStrings()); - assertEquals(3, page.getStrings().size()); + assertNotNull(page.getStringsList()); + assertEquals(3, page.getStringsList().size()); + } + + @Test + public void listOfTypedGenerics() throws Exception + { + AnnotatedListOfBeanTypeQualifier page = + tester.startPage(new AnnotatedListOfBeanTypeQualifier()); + + assertNotNull(page.getBeans()); + assertEquals(1, page.getBeans().size()); } class AnnotatedBeanGenericQualifier extends DummyHomePage @@ -102,15 +112,26 @@ public class SpringBeanWithGenericsTest extends Assert return beans; } } + + class AnnotatedListOfBeanTypeQualifier extends DummyHomePage + { + @SpringBean + private List<BeanWithGeneric<Integer>> beans; + + public List<BeanWithGeneric<Integer>> getBeans() + { + return beans; + } + } class AnnotatedListField extends DummyHomePage { @SpringBean - private List<String> strings; + private List<String> stringsList; - public List<String> getStrings() + public List<String> getStringsList() { - return strings; + return stringsList; } }
