From fbcdc573c203d437905d69d224a4b145b017f283 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 27 Aug 2012 16:36:39 -0500 Subject: [PATCH 1/2] GRAILS-4995 - Improve the handling of List and Map ctor args --- .../groovy/GroovyBeanDefinitionReader.java | 7 +++ .../GroovyBeanDefinitionReaderTests.groovy | 44 ++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/spring-lang-groovy/src/main/java/org/springframework/context/groovy/GroovyBeanDefinitionReader.java b/spring-lang-groovy/src/main/java/org/springframework/context/groovy/GroovyBeanDefinitionReader.java index 5dbe0ccb96..3d33b931e3 100644 --- a/spring-lang-groovy/src/main/java/org/springframework/context/groovy/GroovyBeanDefinitionReader.java +++ b/spring-lang-groovy/src/main/java/org/springframework/context/groovy/GroovyBeanDefinitionReader.java @@ -714,6 +714,13 @@ public class GroovyBeanDefinitionReader extends GroovyObjectSupport { protected List resolveConstructorArguments(Object[] args, int start, int end) { Object[] constructorArgs = subarray(args, start, end); filterGStringReferences(constructorArgs); + for(int i = 0; i < constructorArgs.length; i++) { + if(constructorArgs[i] instanceof List) { + constructorArgs[i] = manageListIfNecessary(constructorArgs[i]); + } else if(constructorArgs[i] instanceof Map){ + constructorArgs[i] = manageMapIfNecessary(constructorArgs[i]); + } + } List constructorArgsList = Arrays.asList(constructorArgs); return constructorArgsList; } diff --git a/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy b/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy index 1f44ab5047..a194795f88 100644 --- a/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy +++ b/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy @@ -772,9 +772,7 @@ beanReader.createApplicationContext() assertEquals "Fred", appCtx.getBean("personA").name } - // test for GRAILS-4995 void testListOfBeansAsConstructorArg() { - if(notYetImplemented()) return def beanReader = new GroovyBeanDefinitionReader() beanReader.beans { @@ -790,6 +788,34 @@ beanReader.createApplicationContext() assert ctx.containsBean('someotherbean2') assert ctx.containsBean('somebean') } + + void testBeanWithListAndMapConstructor() { + def beanReader = new GroovyBeanDefinitionReader() + beanReader.beans { + bart(Bean1) { + person = "bart" + age = 11 + } + lisa(Bean1) { + person = "lisa" + age = 9 + } + + beanWithList(Bean5, [bart, lisa]) + + // test runtime references both as ref() and as plain name + beanWithMap(Bean6, [bart:bart, lisa:ref('lisa')]) + } + def ctx = beanReader.createApplicationContext() + + def beanWithList = ctx.getBean("beanWithList") + assertEquals 2, beanWithList.people.size() + assertEquals "bart", beanWithList.people[0].person + + def beanWithMap = ctx.getBean("beanWithMap") + assertEquals 9, beanWithMap.peopleByName.lisa.age + assertEquals "bart", beanWithMap.peopleByName.bart.person + } void testAnonymousInnerBeanViaBeanMethod() { def beanReader = new GroovyBeanDefinitionReader() @@ -903,6 +929,20 @@ class Bean4 { } String person } +// bean with List-valued constructor arg +class Bean5 { + Bean5(List people) { + this.people = people + } + List people +} +// bean with Map-valued constructor arg +class Bean6 { + Bean6(Map peopleByName) { + this.peopleByName = peopleByName + } + Map peopleByName +} // a factory bean class Bean1Factory { Bean1 newInstance() { From a0b3da716c7e298aaf60f30e3c37b54222f7cfc5 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 27 Aug 2012 17:16:33 -0500 Subject: [PATCH 2/2] fix test Copying in changes from https://github.com/grails/grails-core/commit/54e2f726e1f7ea34444e30438c38bffd15cbbdbb --- .../GroovyBeanDefinitionReaderTests.groovy | 119 ++++++++---------- 1 file changed, 52 insertions(+), 67 deletions(-) diff --git a/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy b/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy index a194795f88..ccd41271c2 100644 --- a/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy +++ b/spring-lang-groovy/src/test/groovy/org/springframework/context/groovy/GroovyBeanDefinitionReaderTests.groovy @@ -133,69 +133,61 @@ class GroovyBeanDefinitionReaderTests extends GroovyTestCase { void testUseTwoSpringNamespaces() { def beanReader = new GroovyBeanDefinitionReader() - SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder() - try { - - builder.bind("bar", "success") - builder.activate() - TestScope scope = new TestScope() - - GenericApplicationContext appCtx = beanReader.getSpringConfig().getUnrefreshedApplicationContext() - appCtx.getBeanFactory().registerScope("test", scope) - beanReader.beans { - xmlns aop:"http://www.springframework.org/schema/aop" - xmlns jee:"http://www.springframework.org/schema/jee" - scopedList(ArrayList) { bean -> - bean.scope = "test" - aop.'scoped-proxy'() - } - - jee.'jndi-lookup'(id:"foo", 'jndi-name':"bar") + TestScope scope = new TestScope() + GenericApplicationContext appCtx = beanReader.getSpringConfig().getUnrefreshedApplicationContext() + appCtx.getBeanFactory().registerScope("test", scope) + beanReader.beans { + xmlns aop:"http://www.springframework.org/schema/aop" + xmlns util:"http://www.springframework.org/schema/util" + scopedList(ArrayList) { bean -> + bean.scope = "test" + aop.'scoped-proxy'() } + util.list(id: 'foo') { + value 'one' + value 'two' + } + } - appCtx = beanReader.createApplicationContext() - - assertEquals "success", appCtx.getBean("foo") - - assertNotNull appCtx.getBean("scopedList") - assertNotNull appCtx.getBean("scopedList").size() - assertNotNull appCtx.getBean("scopedList").size() + appCtx = beanReader.createApplicationContext() - // should only be true because bean not initialized until proxy called - assertEquals 2, scope.instanceCount + assert ['one', 'two'] == appCtx.getBean("foo") - beanReader = new GroovyBeanDefinitionReader() + assertNotNull appCtx.getBean("scopedList") + assertNotNull appCtx.getBean("scopedList").size() + assertNotNull appCtx.getBean("scopedList").size() - appCtx = beanReader.getSpringConfig().getUnrefreshedApplicationContext() - appCtx.getBeanFactory().registerScope("test", scope) - beanReader.beans { - xmlns aop:"http://www.springframework.org/schema/aop", - jee:"http://www.springframework.org/schema/jee" - scopedList(ArrayList) { bean -> - bean.scope = "test" - aop.'scoped-proxy'() - } + // should only be true because bean not initialized until proxy called + assertEquals 2, scope.instanceCount - jee.'jndi-lookup'(id:"foo", 'jndi-name':"bar") + beanReader = new GroovyBeanDefinitionReader() + appCtx = beanReader.getSpringConfig().getUnrefreshedApplicationContext() + appCtx.getBeanFactory().registerScope("test", scope) + beanReader.beans { + xmlns aop:"http://www.springframework.org/schema/aop", + util:"http://www.springframework.org/schema/util" + scopedList(ArrayList) { bean -> + bean.scope = "test" + aop.'scoped-proxy'() } - appCtx = beanReader.createApplicationContext() - - assertEquals "success", appCtx.getBean("foo") - - assertNotNull appCtx.getBean("scopedList") - assertNotNull appCtx.getBean("scopedList").size() - assertNotNull appCtx.getBean("scopedList").size() - // should only be true because bean not initialized until proxy called - assertEquals 4, scope.instanceCount + util.list(id: 'foo') { + value 'one' + value 'two' + } + } + appCtx = beanReader.createApplicationContext() + + assert ['one', 'two'] == appCtx.getBean("foo") + assertNotNull appCtx.getBean("scopedList") + assertNotNull appCtx.getBean("scopedList").size() + assertNotNull appCtx.getBean("scopedList").size() - } - finally { - builder.deactivate() - } + // should only be true because bean not initialized until proxy called + assertEquals 4, scope.instanceCount } void testSpringAOPSupport() { @@ -262,24 +254,17 @@ class GroovyBeanDefinitionReaderTests extends GroovyTestCase { void testSpringNamespaceBean() { def beanReader = new GroovyBeanDefinitionReader() - SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder() - try { - - builder.bind("bar", "success") - builder.activate() - - beanReader.beans { - xmlns jee:"http://www.springframework.org/schema/jee" - jee.'jndi-lookup'(id:"foo", 'jndi-name':"bar") + beanReader.beans { + xmlns util: 'http://www.springframework.org/schema/util' + util.list(id: 'foo') { + value 'one' + value 'two' } - - ApplicationContext appCtx = beanReader.createApplicationContext() - - assertEquals "success", appCtx.getBean("foo") - } - finally { - builder.deactivate() } + + def ctx = beanReader.createApplicationContext() + + assert ['one', 'two'] == ctx.getBean('foo') } void testNamedArgumentConstructor() {