Repository: avaje/avaje-inject
Pull request #380 (2023-07-23 00:32:53)

BeanScopeBuilder.profiles() for explicit profiles
- Explicit profiles via BeanScopeBuilder.profiles()
- Side effect free for InjectTest profiles
- Remove PropertyRequiresPlugin set property


Patch:
diff --git a/inject/src/main/java/io/avaje/inject/BeanScopeBuilder.java b/inject/src/main/java/io/avaje/inject/BeanScopeBuilder.java
index 7b28ffd1..5cb16022 100644
--- a/inject/src/main/java/io/avaje/inject/BeanScopeBuilder.java
+++ b/inject/src/main/java/io/avaje/inject/BeanScopeBuilder.java
@@ -188,6 +188,13 @@ public interface BeanScopeBuilder {
    */
   <D> BeanScopeBuilder bean(Type type, D bean);
 
+  /**
+   * Set the explicit profiles to use when building the scope.
+   *
+   * <p>If profiles are not set explicitly here they are read from the properties plugin.
+   */
+  BeanScopeBuilder profiles(String profiles);
+
   /**
    * Add a supplied bean provider that acts as a default fallback for a dependency.
    * <p>
diff --git a/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java b/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java
index c60c995a..52d74d55 100644
--- a/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java
+++ b/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java
@@ -35,6 +35,7 @@ final class DBeanScopeBuilder implements BeanScopeBuilder.ForTesting {
   private boolean shutdownHook;
   private ClassLoader classLoader;
   private PropertyRequiresPlugin propertyRequiresPlugin;
+  private String profiles;
 
   /**
    * Create a BeanScopeBuilder to ultimately load and return a new BeanScope.
@@ -103,6 +104,12 @@ final class DBeanScopeBuilder implements BeanScopeBuilder.ForTesting {
     return this;
   }
 
+  @Override
+  public BeanScopeBuilder profiles(String profiles) {
+    this.profiles = profiles;
+    return this;
+  }
+
   @Override
   public <D> BeanScopeBuilder provideDefault(@Nullable String name, Type type, Supplier<D> supplier) {
     final Provider<D> provider = supplier::get;
@@ -241,7 +248,7 @@ final class DBeanScopeBuilder implements BeanScopeBuilder.ForTesting {
     final var level = propertyRequiresPlugin.contains("printModules") ? INFO : DEBUG;
     log.log(level, "building with modules {0}", moduleNames);
 
-    final Builder builder = Builder.newBuilder(propertyRequiresPlugin, suppliedBeans, enrichBeans, parent, parentOverride);
+    final Builder builder = Builder.newBuilder(profiles, propertyRequiresPlugin, suppliedBeans, enrichBeans, parent, parentOverride);
     for (final Module factory : factoryOrder.factories()) {
       factory.build(builder);
     }
diff --git a/inject/src/main/java/io/avaje/inject/DConfigProps.java b/inject/src/main/java/io/avaje/inject/DConfigProps.java
index 81124969..51438e18 100644
--- a/inject/src/main/java/io/avaje/inject/DConfigProps.java
+++ b/inject/src/main/java/io/avaje/inject/DConfigProps.java
@@ -5,7 +5,9 @@ import io.avaje.inject.spi.PropertyRequiresPlugin;
 
 import java.util.Optional;
 
-/** Avaje-Config based implementation of PropertyRequiresPlugin. */
+/**
+ * Avaje-Config based implementation of PropertyRequiresPlugin.
+ */
 final class DConfigProps implements PropertyRequiresPlugin {
 
   @Override
@@ -22,9 +24,4 @@ final class DConfigProps implements PropertyRequiresPlugin {
   public boolean equalTo(String property, String value) {
     return value.equals(Config.getNullable(property));
   }
-
-  @Override
-  public void set(String property, String value) {
-    Config.setProperty(property, value);
-  }
 }
diff --git a/inject/src/main/java/io/avaje/inject/DSystemProps.java b/inject/src/main/java/io/avaje/inject/DSystemProps.java
index abde0c86..70391f8c 100644
--- a/inject/src/main/java/io/avaje/inject/DSystemProps.java
+++ b/inject/src/main/java/io/avaje/inject/DSystemProps.java
@@ -19,9 +19,4 @@ final class DSystemProps implements io.avaje.inject.spi.PropertyRequiresPlugin {
   public boolean equalTo(String property, String value) {
     return value.equals(System.getProperty(property)) || value.equals(System.getenv(property));
   }
-
-  @Override
-  public void set(String property, String value) {
-    System.setProperty(property, value);
-  }
 }
diff --git a/inject/src/main/java/io/avaje/inject/spi/Builder.java b/inject/src/main/java/io/avaje/inject/spi/Builder.java
index da934702..b58e6068 100644
--- a/inject/src/main/java/io/avaje/inject/spi/Builder.java
+++ b/inject/src/main/java/io/avaje/inject/spi/Builder.java
@@ -1,6 +1,7 @@
 package io.avaje.inject.spi;
 
 import io.avaje.inject.BeanScope;
+import io.avaje.lang.Nullable;
 import jakarta.inject.Provider;
 
 import java.lang.reflect.Type;
@@ -18,18 +19,19 @@ public interface Builder {
   /**
    * Create the root level Builder.
    *
+   * @param profiles       Explicit profiles used
    * @param suppliedBeans  The list of beans (typically test doubles) supplied when building the context.
    * @param enrichBeans    The list of classes we want to have with mockito spy enhancement
    * @param parent         The parent BeanScope
    * @param parentOverride When false do not add beans that already exist on the parent
    */
   @SuppressWarnings("rawtypes")
-  static Builder newBuilder(PropertyRequiresPlugin plugin, List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans, BeanScope parent, boolean parentOverride) {
+  static Builder newBuilder(@Nullable String profiles, PropertyRequiresPlugin plugin, List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans, BeanScope parent, boolean parentOverride) {
     if (suppliedBeans.isEmpty() && enrichBeans.isEmpty()) {
       // simple case, no mocks or spies
-      return new DBuilder(plugin, parent, parentOverride);
+      return new DBuilder(profiles, plugin, parent, parentOverride);
     }
-    return new DBuilderExtn(plugin, parent, parentOverride, suppliedBeans, enrichBeans);
+    return new DBuilderExtn(profiles, plugin, parent, parentOverride, suppliedBeans, enrichBeans);
   }
 
   /**
diff --git a/inject/src/main/java/io/avaje/inject/spi/DBuilder.java b/inject/src/main/java/io/avaje/inject/spi/DBuilder.java
index a6505ec8..15176931 100644
--- a/inject/src/main/java/io/avaje/inject/spi/DBuilder.java
+++ b/inject/src/main/java/io/avaje/inject/spi/DBuilder.java
@@ -2,15 +2,16 @@ package io.avaje.inject.spi;
 
 import io.avaje.inject.BeanEntry;
 import io.avaje.inject.BeanScope;
+import io.avaje.lang.Nullable;
 import jakarta.inject.Provider;
 
-import static java.util.stream.Collectors.toSet;
-
 import java.lang.reflect.Type;
 import java.util.*;
 import java.util.function.Consumer;
 
 import static io.avaje.inject.spi.DBeanScope.combine;
+import static java.util.Collections.emptySet;
+import static java.util.stream.Collectors.toSet;
 
 class DBuilder implements Builder {
 
@@ -37,14 +38,24 @@ class DBuilder implements Builder {
 
   private DBeanScopeProxy beanScopeProxy;
 
-  DBuilder(PropertyRequiresPlugin propertyRequires, BeanScope parent, boolean parentOverride) {
+  DBuilder(@Nullable String profiles, PropertyRequiresPlugin propertyRequires, BeanScope parent, boolean parentOverride) {
     this.propertyRequires = propertyRequires;
     this.parent = parent;
     this.parentOverride = parentOverride;
-    this.profiles =
-        propertyRequires.get("avaje.profiles").map(p -> p.split(",")).stream()
-            .flatMap(Arrays::stream)
-            .collect(toSet());
+    this.profiles = initProfiles(profiles, propertyRequires);
+  }
+
+  private Set<String> initProfiles(@Nullable String profiles, PropertyRequiresPlugin properties) {
+    if (profiles != null) {
+      return toProfiles(profiles);
+    }
+    return properties.get("avaje.profiles")
+      .map(this::toProfiles)
+      .orElse(emptySet());
+  }
+
+  private Set<String> toProfiles(String profiles) {
+    return Arrays.stream(profiles.split(",")).collect(toSet());
   }
 
   @Override
diff --git a/inject/src/main/java/io/avaje/inject/spi/DBuilderExtn.java b/inject/src/main/java/io/avaje/inject/spi/DBuilderExtn.java
index 65317c1f..78e8cb53 100644
--- a/inject/src/main/java/io/avaje/inject/spi/DBuilderExtn.java
+++ b/inject/src/main/java/io/avaje/inject/spi/DBuilderExtn.java
@@ -2,6 +2,7 @@ package io.avaje.inject.spi;
 
 import io.avaje.inject.BeanEntry;
 import io.avaje.inject.BeanScope;
+import io.avaje.lang.Nullable;
 
 import java.lang.reflect.Type;
 import java.util.HashMap;
@@ -19,8 +20,8 @@ final class DBuilderExtn extends DBuilder {
   private final boolean hasSuppliedBeans;
 
   @SuppressWarnings("rawtypes")
-  DBuilderExtn(PropertyRequiresPlugin plugin, BeanScope parent, boolean parentOverride, List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans) {
-    super(plugin, parent, parentOverride);
+  DBuilderExtn(@Nullable String profiles, PropertyRequiresPlugin plugin, BeanScope parent, boolean parentOverride, List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans) {
+    super(profiles, plugin, parent, parentOverride);
     this.hasSuppliedBeans = (suppliedBeans != null && !suppliedBeans.isEmpty());
     if (hasSuppliedBeans) {
       beanMap.add(suppliedBeans);
diff --git a/inject/src/main/java/io/avaje/inject/spi/PropertyRequiresPlugin.java b/inject/src/main/java/io/avaje/inject/spi/PropertyRequiresPlugin.java
index 571d1834..d8649b1d 100644
--- a/inject/src/main/java/io/avaje/inject/spi/PropertyRequiresPlugin.java
+++ b/inject/src/main/java/io/avaje/inject/spi/PropertyRequiresPlugin.java
@@ -37,9 +37,4 @@ public interface PropertyRequiresPlugin {
     return !equalTo(property, value);
   }
 
-  /** Set a property for wiring. */
-  default void set(String property, String value) {
-
-    throw new UnsupportedOperationException("Not Implemented");
-  }
 }


Test patch:
diff --git a/blackbox-test-inject/src/main/java/org/example/myapp/ConfigPropertiesPlugin.java b/blackbox-test-inject/src/main/java/org/example/myapp/ConfigPropertiesPlugin.java
index eb505913..53f0120a 100644
--- a/blackbox-test-inject/src/main/java/org/example/myapp/ConfigPropertiesPlugin.java
+++ b/blackbox-test-inject/src/main/java/org/example/myapp/ConfigPropertiesPlugin.java
@@ -31,9 +31,4 @@ public class ConfigPropertiesPlugin implements PropertyRequiresPlugin {
   public boolean notEqualTo(String property, String value) {
     return !value.equals(Config.getNullable(property));
   }
-
-  @Override
-  public void set(String property, String value) {
-    Config.setProperty(property, value);
-  }
 }
diff --git a/inject-test/src/main/java/io/avaje/inject/test/MetaInfo.java b/inject-test/src/main/java/io/avaje/inject/test/MetaInfo.java
index 0e11f8fb..d7995801 100644
--- a/inject-test/src/main/java/io/avaje/inject/test/MetaInfo.java
+++ b/inject-test/src/main/java/io/avaje/inject/test/MetaInfo.java
@@ -53,7 +53,7 @@ final class MetaInfo {
             .orElse("");
 
     if (!profiles.isBlank()) {
-      builder.propertyPlugin().set("avaje.profiles", profiles);
+      builder.profiles(profiles);
     }
     // register mocks and spies local to this test
     reader.build(builder, testInstance);