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;
                }
        }
 

Reply via email to