> extends Bindable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ProviderDefinition.class);
+ private final Type from;
+
+ ProviderDefinition(Class
provider) {
+ super(provider);
+ Type type = checkNotNull(TypeResolver.resolveGenericType(Provider.class, provider),
+ "Unable to resolve generic type of provider " + provider.getName());
+ if (type instanceof ParameterizedType) {
+ from = ((ParameterizedType) type).getActualTypeArguments()[0];
+ } else {
+ throw new IllegalArgumentException("A generic type is required for provider " + provider.getName());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void apply(Binder binder) {
+ AnnotatedBindingBuilder bind = binder.bind((TypeLiteral) TypeLiteral.get(from));
+ if (qualifier != null) {
+ LOGGER.debug("Binding {} annotated with {} to provider {}",
+ from.getTypeName(),
+ qualifier,
+ target.getName());
+ bind.annotatedWith(qualifier).toProvider(target);
+ } else {
+ LOGGER.debug("Binding {} to provider {}", from.getTypeName(), target.getName());
+ bind.toProvider(target);
+ }
+ }
+}
diff --git a/core/src/test/java/custom/CustomApplicationProvider.java b/core/src/test/java/custom/CustomApplicationProvider.java
new file mode 100644
index 000000000..479fad557
--- /dev/null
+++ b/core/src/test/java/custom/CustomApplicationProvider.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package custom;
+
+import java.io.File;
+import java.util.Map;
+import javax.inject.Provider;
+import org.seedstack.coffig.Coffig;
+import org.seedstack.seed.Application;
+import org.seedstack.seed.ClassConfiguration;
+import org.seedstack.seed.Provide;
+
+@Provide(override = true)
+public class CustomApplicationProvider implements Provider {
+ @Override
+ public Application get() {
+ return new Application() {
+ @Override
+ public String getName() {
+ return "custom";
+ }
+
+ @Override
+ public String getId() {
+ return null;
+ }
+
+ @Override
+ public String getVersion() {
+ return null;
+ }
+
+ @Override
+ public File getStorageLocation(String context) {
+ return null;
+ }
+
+ @Override
+ public boolean isStorageEnabled() {
+ return false;
+ }
+
+ @Override
+ public Coffig getConfiguration() {
+ return null;
+ }
+
+ @Override
+ public ClassConfiguration getConfiguration(Class someClass) {
+ return null;
+ }
+
+ @Override
+ public String substituteWithConfiguration(String value) {
+ return null;
+ }
+
+ @Override
+ public Map getKernelParameters() {
+ return null;
+ }
+
+ @Override
+ public String[] getArguments() {
+ return new String[0];
+ }
+ };
+ }
+}
diff --git a/core/src/test/java/org/seedstack/seed/core/CorePluginIT.java b/core/src/test/java/org/seedstack/seed/core/CoreIT.java
similarity index 88%
rename from core/src/test/java/org/seedstack/seed/core/CorePluginIT.java
rename to core/src/test/java/org/seedstack/seed/core/CoreIT.java
index 74aae17eb..814fecbcf 100644
--- a/core/src/test/java/org/seedstack/seed/core/CorePluginIT.java
+++ b/core/src/test/java/org/seedstack/seed/core/CoreIT.java
@@ -5,6 +5,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+
package org.seedstack.seed.core;
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,6 +32,7 @@
import org.seedstack.seed.core.fixtures.DummyService1;
import org.seedstack.seed.core.fixtures.DummyService2;
import org.seedstack.seed.core.fixtures.DummyService3;
+import org.seedstack.seed.core.fixtures.ProvidedInterface;
import org.seedstack.seed.core.fixtures.Service;
import org.seedstack.seed.core.fixtures.Service1;
import org.seedstack.seed.core.fixtures.Service2;
@@ -43,7 +45,7 @@
import some.other.pkg.ForeignClass;
@RunWith(SeedITRunner.class)
-public class CorePluginIT {
+public class CoreIT {
@Inject
private Injector injector;
@@ -118,6 +120,14 @@ public void explicitBindingsAreWorking() {
BoundOverrideFromInterfaceWithAnnotation.class);
}
+ @Test
+ public void explicitProvidedBindingsAreWorking() {
+ HolderNominal holder = injector.getInstance(HolderNominal.class);
+ assertThat(holder.providedFromInterface).isInstanceOf(ProvidedInterface.class);
+ assertThat(holder.providedFromInterfaceWithName).isInstanceOf(ProvidedInterface.class);
+ assertThat(holder.providedFromInterfaceWithAnnotation).isInstanceOf(ProvidedInterface.class);
+ }
+
@Bind
private static class LoggerHolder {
private static final Logger logger = LoggerFactory.getLogger(LoggerHolder.class);
@@ -170,6 +180,14 @@ private static class HolderNominal {
@Inject
@Dummy
BoundInterface boundFromInterfaceWithAnnotation;
+ @Inject
+ ProvidedInterface providedFromInterface;
+ @Inject
+ @Named("toto")
+ ProvidedInterface providedFromInterfaceWithName;
+ @Inject
+ @Dummy
+ ProvidedInterface providedFromInterfaceWithAnnotation;
}
private static class HolderException {
diff --git a/core/src/test/java/org/seedstack/seed/core/OverrideSeedStackIT.java b/core/src/test/java/org/seedstack/seed/core/OverrideSeedStackIT.java
new file mode 100644
index 000000000..2bf38fa32
--- /dev/null
+++ b/core/src/test/java/org/seedstack/seed/core/OverrideSeedStackIT.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.seedstack.seed.core;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import javax.inject.Inject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.seedstack.seed.Application;
+import org.seedstack.seed.testing.LaunchMode;
+import org.seedstack.seed.testing.LaunchWith;
+import org.seedstack.seed.testing.SystemProperty;
+import org.seedstack.seed.testing.junit4.SeedITRunner;
+
+@RunWith(SeedITRunner.class)
+@LaunchWith(mode = LaunchMode.PER_TEST)
+public class OverrideSeedStackIT {
+ @Inject
+ private Application application;
+
+ @Test
+ public void normalApplicationIsInjectable() {
+ assertThat(application.getName()).isEqualTo("seed-it");
+ }
+
+ @Test
+ @SystemProperty(name = "additionalPackage", value = "custom")
+ public void customApplicationIsInjectable() {
+ assertThat(application.getName()).isEqualTo("custom");
+ }
+}
diff --git a/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterface.java b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterface.java
new file mode 100644
index 000000000..1fb37b10d
--- /dev/null
+++ b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterface.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.seedstack.seed.core.fixtures;
+
+import javax.inject.Provider;
+import org.seedstack.seed.Provide;
+
+@Provide
+public class ProvidedFromInterface implements Provider> {
+ @Override
+ public ProvidedInterface get() {
+ return new Impl();
+ }
+
+ private static class Impl implements ProvidedInterface {
+
+ }
+}
diff --git a/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterfaceWithAnnotation.java b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterfaceWithAnnotation.java
new file mode 100644
index 000000000..efc76244d
--- /dev/null
+++ b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterfaceWithAnnotation.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.seedstack.seed.core.fixtures;
+
+import javax.inject.Provider;
+import org.seedstack.seed.Provide;
+
+@Provide
+@Dummy
+public class ProvidedFromInterfaceWithAnnotation implements Provider> {
+ @Override
+ public ProvidedInterface get() {
+ return new Impl();
+ }
+
+ private static class Impl implements ProvidedInterface {
+
+ }
+}
diff --git a/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterfaceWithName.java b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterfaceWithName.java
new file mode 100644
index 000000000..c30ad9b44
--- /dev/null
+++ b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedFromInterfaceWithName.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.seedstack.seed.core.fixtures;
+
+import javax.inject.Named;
+import javax.inject.Provider;
+import org.seedstack.seed.Provide;
+
+@Provide
+@Named("toto")
+public class ProvidedFromInterfaceWithName implements Provider> {
+ @Override
+ public ProvidedInterface get() {
+ return new Impl();
+ }
+
+ private static class Impl implements ProvidedInterface {
+
+ }
+}
diff --git a/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedInterface.java b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedInterface.java
new file mode 100644
index 000000000..db2b22cf2
--- /dev/null
+++ b/core/src/test/java/org/seedstack/seed/core/fixtures/ProvidedInterface.java
@@ -0,0 +1,12 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.seedstack.seed.core.fixtures;
+
+public interface ProvidedInterface {
+}
diff --git a/core/src/test/resources/application.yaml b/core/src/test/resources/application.yaml
index 5c8cc41d0..127b1e5fc 100644
--- a/core/src/test/resources/application.yaml
+++ b/core/src/test/resources/application.yaml
@@ -26,7 +26,7 @@ logging:
path: test.log
application:
id: seed-it
- basePackages: some.other.pkg
+ basePackages: ["some.other.pkg", "${sys.additionalPackage:'dummy'}"]
jndi:
additionalContexts:
test1: jndi-test1.properties
diff --git a/pom.xml b/pom.xml
index c93807031..aa273370a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
org.seedstack.seed
seed
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
pom
diff --git a/rest/core/pom.xml b/rest/core/pom.xml
index 61ddd22a1..78cf4090f 100644
--- a/rest/core/pom.xml
+++ b/rest/core/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-rest
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-rest-core
diff --git a/rest/jersey2/pom.xml b/rest/jersey2/pom.xml
index 876ae74af..7c7f2b844 100644
--- a/rest/jersey2/pom.xml
+++ b/rest/jersey2/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-rest
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-rest-jersey2
diff --git a/rest/pom.xml b/rest/pom.xml
index 3002b56de..147254312 100644
--- a/rest/pom.xml
+++ b/rest/pom.xml
@@ -13,7 +13,7 @@
org.seedstack.seed
seed
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-rest
diff --git a/rest/specs/pom.xml b/rest/specs/pom.xml
index 9f710e5f2..5e69a25a6 100644
--- a/rest/specs/pom.xml
+++ b/rest/specs/pom.xml
@@ -13,7 +13,7 @@
org.seedstack.seed
seed-rest
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-rest-specs
diff --git a/security/core/pom.xml b/security/core/pom.xml
index e690403ba..56e078e13 100644
--- a/security/core/pom.xml
+++ b/security/core/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-security
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-security-core
diff --git a/security/pom.xml b/security/pom.xml
index dd5ffc1e7..693964ed5 100644
--- a/security/pom.xml
+++ b/security/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-security
diff --git a/security/specs/pom.xml b/security/specs/pom.xml
index 26da88f32..c8914f406 100644
--- a/security/specs/pom.xml
+++ b/security/specs/pom.xml
@@ -13,7 +13,7 @@
org.seedstack.seed
seed-security
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-security-specs
diff --git a/specs/pom.xml b/specs/pom.xml
index a0beb3911..b9d5177ca 100644
--- a/specs/pom.xml
+++ b/specs/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-specs
diff --git a/specs/src/main/java/org/seedstack/seed/Bind.java b/specs/src/main/java/org/seedstack/seed/Bind.java
index 024ae5c99..4fb60b99f 100644
--- a/specs/src/main/java/org/seedstack/seed/Bind.java
+++ b/specs/src/main/java/org/seedstack/seed/Bind.java
@@ -5,6 +5,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+
package org.seedstack.seed;
import java.lang.annotation.Documented;
@@ -20,10 +21,10 @@
*
*
* {@literal @}Bind
- * public class SomeImplementation {...}
+ * public class SomeImplementation {...}
*
* {@literal @}Inject
- * SomeImplementation someImplementation;
+ * SomeImplementation someImplementation;
*
*
*
@@ -33,30 +34,41 @@
*
*
* {@literal @}Bind(from = SomeInterface.class)
- * public class SomeImplementation implements SomeInterface {...}
+ * public class SomeImplementation implements SomeInterface {...}
*
* {@literal @}Inject
- * SomeInterface someInterface;
+ * SomeInterface someInterface;
*
*
*
- * When an injection class is specified and a qualifier annotation is present on the implementation class, it is used to
- * further refine the injection key:
+ * The {@link Bind} annotation allows to override any interface-based SeedStack binding. To do this,
+ * create a custom implementation of the SeedStack interface you want to customize (this is the type you use at the
+ * injection point) and set the {@link Bind#override()} boolean to true. Your custom implementation will replace the
+ * SeedStack one.
+ *
+ *
+ *
+ * When a qualifier annotation is present on the implementation class, it is used to make the injection point more
+ * specific:
*
*
*
* {@literal @}Qualifier
* {@literal @}Retention(RetentionPolicy.RUNTIME)
- * public interface {@literal @}SomeQualifier {...}
+ * public interface {@literal @}SomeQualifier {...}
*
* {@literal @}Bind(from = SomeInterface.class)
* {@literal @}SomeQualifier
- * public class SomeImplementation implements SomeInterface {...}
+ * public class SomeImplementation implements SomeInterface {...}
*
* {@literal @}Inject
* {@literal @}SomeQualifier
- * SomeInterface someInterface;
+ * SomeInterface someInterface;
*
+ *
+ * When having multiple implementations of the same interface, using a different qualifier on each implementation
+ * allows to create multiple bindings. You can then choose the implementation by specifying the corresponding qualifier
+ * at injection point.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
diff --git a/specs/src/main/java/org/seedstack/seed/Provide.java b/specs/src/main/java/org/seedstack/seed/Provide.java
new file mode 100644
index 000000000..6fc379f60
--- /dev/null
+++ b/specs/src/main/java/org/seedstack/seed/Provide.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2013-2019, The SeedStack authors
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.seedstack.seed;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.inject.Provider;
+
+/**
+ * This annotation creates an injection binding when applied on a JSR-330 {@link javax.inject.Provider}. It is
+ * comparable to the {@link Bind} annotation but allow to specify the creation logic of the instance in the
+ * {@link Provider#get()} method. A provider is itself injectable so you can use any required dependency during the
+ * creation of the provided instance.
+ *
+ *
+ * {@literal @}Provide
+ * public class Provider{@literal <}SomeClass{@literal >} {
+ * {@literal @}Inject
+ * private SomeDependency someDependency;
+ *
+ * public SomeInterface get() {
+ * return new SomeClass(someDependency);
+ * }
+ * }
+ *
+ * {@literal @}Inject
+ * SomeClass someClassInstance;
+ *
+ *
+ *
+ * The {@link Provide} annotation allows to override any existing SeedStack binding. To do this,
+ * create a {@link Provider} producing the same type as the SeedStack binding you want to override (this is the type
+ * you use at the injection point) and set the {@link Provide#override()} boolean to true. The instance produced by your
+ * provider will replace the SeedStack one.
+ *
+ *
+ *
+ * When a qualifier annotation is present on the implementation class, it is used to make the injection point more
+ * specific:
+ *
+ *
+ *
+ * {@literal @}Qualifier
+ * {@literal @}Retention(RetentionPolicy.RUNTIME)
+ * public interface {@literal @}SomeQualifier {...}
+ *
+ * {@literal @}Bind(from = SomeInterface.class)
+ * {@literal @}SomeQualifier
+ * public class SomeImplementation implements SomeInterface {...}
+ *
+ * {@literal @}Inject
+ * {@literal @}SomeQualifier
+ * SomeInterface someInterface;
+ *
+ *
+ * When having multiple implementations of the same interface, using a different qualifier on each implementation
+ * allows to create multiple bindings. You can then choose the implementation by specifying the corresponding qualifier
+ * at injection point.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface Provide {
+ /**
+ * If true the binding will be defined as an overriding one, meaning that it will override an identical binding
+ * already defined. If false, the binding will defined as a normal one.
+ *
+ * @return if true the binding is an overriding binding, if false a normal binding.
+ */
+ boolean override() default false;
+}
diff --git a/testing/arquillian/pom.xml b/testing/arquillian/pom.xml
index 8e6c2e05d..48ad1e376 100644
--- a/testing/arquillian/pom.xml
+++ b/testing/arquillian/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-testing
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-testing-arquillian
diff --git a/testing/core/pom.xml b/testing/core/pom.xml
index c3d0aefd2..c694dfe96 100644
--- a/testing/core/pom.xml
+++ b/testing/core/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-testing
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-testing-core
diff --git a/testing/junit4/pom.xml b/testing/junit4/pom.xml
index 7eba586f5..f51064afa 100644
--- a/testing/junit4/pom.xml
+++ b/testing/junit4/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-testing
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-testing-junit4
diff --git a/testing/pom.xml b/testing/pom.xml
index 980911714..113f33b99 100644
--- a/testing/pom.xml
+++ b/testing/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-testing
diff --git a/testing/specs/pom.xml b/testing/specs/pom.xml
index 01e7229a2..bdfc9a3e0 100644
--- a/testing/specs/pom.xml
+++ b/testing/specs/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-testing
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-testing-specs
diff --git a/web/core/pom.xml b/web/core/pom.xml
index 9caa7e62c..f407d9a1f 100644
--- a/web/core/pom.xml
+++ b/web/core/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-web
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-web-core
diff --git a/web/pom.xml b/web/pom.xml
index a96541a04..a6af6e53a 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-web
diff --git a/web/security/pom.xml b/web/security/pom.xml
index a50e68546..3dd1e8bee 100644
--- a/web/security/pom.xml
+++ b/web/security/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-web
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-web-security
diff --git a/web/specs/pom.xml b/web/specs/pom.xml
index f81f76f19..7a9bb23c6 100644
--- a/web/specs/pom.xml
+++ b/web/specs/pom.xml
@@ -13,7 +13,7 @@
org.seedstack.seed
seed-web
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-web-specs
diff --git a/web/undertow/pom.xml b/web/undertow/pom.xml
index 540c45709..79c2fb804 100644
--- a/web/undertow/pom.xml
+++ b/web/undertow/pom.xml
@@ -14,7 +14,7 @@
org.seedstack.seed
seed-web
- 3.8.4-SNAPSHOT
+ 3.8.5-SNAPSHOT
seed-web-undertow