This is an automated email from the ASF dual-hosted git repository. benw pushed a commit to branch TAP5-2758 in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
commit ae22eba41176babd78f3b6915f4f07a1eeecddd1 Author: Ben Weidig <[email protected]> AuthorDate: Sun Jul 23 10:48:07 2023 +0200 TAP5-2758: Treat @Symbol as an explicit signal for injection calculation --- .../tapestry5/ioc/internal/util/InternalUtils.java | 16 ++++++++++ .../specs/ServiceBuilderMethodInvokerSpec.groovy | 35 ++++++++++++++++++++++ .../groovy/ioc/specs/StrategyRegistrySpec.groovy | 2 +- .../test/internal/ServiceBuilderMethodFixture.java | 25 +++++++++++++--- 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java index 2a597ba13..5f5397ff3 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java @@ -205,6 +205,22 @@ public class InternalUtils return asObjectCreator(locator.getService(named.value(), injectionType)); } + // TAP5-2758: An @Symbol is treated as an explicit signal that the injected value + // should not be autowired, but resolved using the MasterObjectProvider instead. + // The check needs to be done before the @Inject one, or the value is solely treated + // by its type. + // Without this check, if any configuration is used, no List/Collection/Map value as + // Symbol can be used without both @Inject and @Symbol, as @Symbol has no explicit + // meaning on how to inject the value, and the configuration detector strikes before + // the final fallback to the MasterObjectProvider. + + Symbol symbol = provider.getAnnotation(Symbol.class); + + if (symbol != null) + { + return asObjectCreator(locator.getObject(injectionType, provider)); + } + // In the absence of @InjectService, try some autowiring. First, does the // parameter type match one of the resources (the parameter defaults)? diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy b/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy index 73109e17e..f34ad02cd 100644 --- a/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy +++ b/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy @@ -3,6 +3,7 @@ package ioc.specs import org.apache.tapestry5.commons.AnnotationProvider import org.apache.tapestry5.commons.ObjectCreator import org.apache.tapestry5.ioc.ServiceBuilderResources +import org.apache.tapestry5.ioc.internal.IOCMessages import org.apache.tapestry5.ioc.internal.ServiceBuilderMethodInvoker import org.apache.tapestry5.ioc.test.internal.FieService import org.apache.tapestry5.ioc.test.internal.FoeService @@ -133,6 +134,40 @@ class ServiceBuilderMethodInvokerSpec extends AbstractSharedRegistrySpecificatio 1 * resources.getOrderedConfiguration(Runnable) >> configuration } + def "injection of ordered configuration as List and another List"() { + + List<Runnable> configuration = Mock() + + fixture.expectedConfiguration = configuration + + when: + + def actual = invoke "buildWithOrderedConfigurationAndList" + + then: + + RuntimeException e = thrown() + + e.message == IOCMessages.tooManyConfigurationParameters(DESCRIPTION) + } + + def "injection of ordered configuration as List and another List as Symbol"() { + + List<Runnable> configuration = Mock() + + fixture.expectedConfiguration = configuration + + when: + + def actual = invoke "buildWithOrderedConfigurationAndSymbolList" + + then: + + actual.is implementation + + 1 * resources.getOrderedConfiguration(Runnable) >> configuration + } + def "injection of unordered collection (as Collection)"() { Collection<Runnable> configuration = Mock() diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/StrategyRegistrySpec.groovy b/tapestry-ioc/src/test/groovy/ioc/specs/StrategyRegistrySpec.groovy index 0b0cde4b1..9bf66cd52 100644 --- a/tapestry-ioc/src/test/groovy/ioc/specs/StrategyRegistrySpec.groovy +++ b/tapestry-ioc/src/test/groovy/ioc/specs/StrategyRegistrySpec.groovy @@ -42,7 +42,7 @@ class StrategyRegistrySpec extends Specification { then: - sr.types.size == 2 + sr.types.size() == 2 sr.types.containsAll(List, Map) } diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/ServiceBuilderMethodFixture.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/ServiceBuilderMethodFixture.java index e4e0e7b1e..97ebe4028 100644 --- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/ServiceBuilderMethodFixture.java +++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/ServiceBuilderMethodFixture.java @@ -14,16 +14,19 @@ package org.apache.tapestry5.ioc.test.internal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.inject.Named; + import org.apache.tapestry5.ioc.ServiceResources; import org.apache.tapestry5.ioc.annotations.InjectService; +import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.ioc.annotations.Value; import org.slf4j.Logger; import org.testng.Assert; -import javax.inject.Named; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; /** * Used by {@link ioc.specs.ServiceBuilderMethodInvokerSpec}. @@ -58,6 +61,20 @@ public class ServiceBuilderMethodFixture extends Assert return fie; } + public FieService buildWithOrderedConfigurationAndList(List<Runnable> configuration, List<Runnable> noConfiguration) + { + assertSame(configuration, expectedConfiguration); + + return fie; + } + + public FieService buildWithOrderedConfigurationAndSymbolList(List<Runnable> configuration, @Symbol("ignored") List<Runnable> noConfiguration) + { + assertSame(configuration, expectedConfiguration); + + return fie; + } + public void methodWithParameterizedList(List<Runnable> list) { }
