This is an automated email from the ASF dual-hosted git repository.
benw pushed a commit to branch javax
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
The following commit(s) were added to refs/heads/javax by this push:
new 93c70c56d TAP5-2758: Treat @Symbol as explicit injection signal
93c70c56d is described below
commit 93c70c56d0c39e4337fab71e5f7b819917eebe77
Author: Ben Weidig <[email protected]>
AuthorDate: Mon Apr 14 08:33:39 2025 +0200
TAP5-2758: Treat @Symbol as explicit injection signal
The @Symbol annotation should be an explicit injection signal and not be
autowired. That allows using @Symbol without an additional @Inject to
force the behavior in certain scenarios.
---
.../tapestry5/ioc/internal/util/InternalUtils.java | 19 ++++++-
.../groovy/ioc/specs/DecorateWithSymbolSpec.groovy | 24 +++++++++
.../specs/ServiceBuilderMethodInvokerSpec.groovy | 20 ++++++++
.../test/internal/DecorateWithSymbolModule.java | 60 ++++++++++++++++++++++
.../test/internal/ServiceBuilderMethodFixture.java | 17 +++++-
5 files changed, 138 insertions(+), 2 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..98a17c9a1 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
@@ -1,4 +1,4 @@
-// Copyright 2006-2014 The Apache Software Foundation
+// Copyright 2006-2025 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -205,6 +205,23 @@ 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/DecorateWithSymbolSpec.groovy
b/tapestry-ioc/src/test/groovy/ioc/specs/DecorateWithSymbolSpec.groovy
new file mode 100644
index 000000000..dd4a89e45
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/ioc/specs/DecorateWithSymbolSpec.groovy
@@ -0,0 +1,24 @@
+package ioc.specs
+
+import org.apache.tapestry5.ioc.test.internal.DecorateWithSymbolModule
+import org.apache.tapestry5.ioc.test.internal.FoeService
+
+import spock.lang.Issue
+
+@Issue("TAP5-2758")
+class DecorateWithSymbolSpec extends AbstractRegistrySpecification {
+
+
+ def "ServiceDef obtainable by service id"() {
+ given:
+ buildRegistry DecorateWithSymbolModule
+
+ when:
+
+ def service = getService "FoeService", FoeService
+
+ then:
+ service.foe() == DecorateWithSymbolModule.SYMBOL_VALUE
+ service.foe() != DecorateWithSymbolModule.ORIGINAL_VALUE
+ }
+}
diff --git
a/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy
b/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy
index 73109e17e..3b83fd3af 100644
---
a/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy
+++
b/tapestry-ioc/src/test/groovy/ioc/specs/ServiceBuilderMethodInvokerSpec.groovy
@@ -3,11 +3,13 @@ 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
import org.apache.tapestry5.ioc.test.internal.ServiceBuilderMethodFixture
import org.slf4j.Logger
+import spock.lang.Issue
class ServiceBuilderMethodInvokerSpec extends
AbstractSharedRegistrySpecification {
@@ -150,6 +152,24 @@ class ServiceBuilderMethodInvokerSpec extends
AbstractSharedRegistrySpecificatio
1 * resources.getUnorderedConfiguration(Runnable) >> configuration
}
+ @Issue("TAP5-2758")
+ 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 "builder method returns null"() {
fixture.fie = null
diff --git
a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/DecorateWithSymbolModule.java
b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/DecorateWithSymbolModule.java
new file mode 100644
index 000000000..05288e82c
--- /dev/null
+++
b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/internal/DecorateWithSymbolModule.java
@@ -0,0 +1,60 @@
+// Copyright 2025 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.test.internal;
+
+import org.apache.tapestry5.commons.MappedConfiguration;
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Decorate;
+import org.apache.tapestry5.ioc.annotations.Match;
+import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.ioc.services.FactoryDefaults;
+import org.apache.tapestry5.ioc.services.SymbolProvider;
+
+public class DecorateWithSymbolModule
+{
+ public static final String SYMBOL_KEY = "symbol-key";
+
+ public static final int ORIGINAL_VALUE = 23;
+ public static final int SYMBOL_VALUE = 42;
+
+ @FactoryDefaults
+ @Contribute(SymbolProvider.class)
+ public static void contributeFactoryDefaults(MappedConfiguration<String,
Object> conf)
+ {
+ conf.add(SYMBOL_KEY, SYMBOL_VALUE);
+ }
+
+ public FoeService buildFoeService()
+ {
+ return new FoeService()
+ {
+
+ @Override
+ public int foe()
+ {
+ return ORIGINAL_VALUE;
+ }
+ };
+ }
+
+ @Decorate(serviceInterface = FoeService.class)
+ @Match(value = "FoeService")
+ public static FoeService decorateSymbolService(FoeService delegate,
+ @Symbol(SYMBOL_KEY)
+ int symbolValue)
+ {
+ return () -> symbolValue;
+ }
+}
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..28ad0037c 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
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2010, 2012 The Apache Software Foundation
+// Copyright 2006, 2007, 2010, 2012, 2025 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ package org.apache.tapestry5.ioc.test.internal;
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;
@@ -58,6 +59,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)
{
}