diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java index cca10b4c9..f159717a3 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java @@ -6,10 +6,10 @@ import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -84,24 +84,22 @@ static void registerModuleProvidedTypes(Set providedTypes) { for (final var module : modules) { final var name = module.getClass().getTypeName(); final var provides = new TreeSet(); - for (final var provide : module.provides()) { - provides.add(provide.getTypeName()); - } - for (final var provide : module.autoProvides()) { - provides.add(provide.getTypeName()); - } - for (final var provide : module.autoProvidesAspects()) { - final var aspectType = Util.wrapAspect(provide.getTypeName()); + Collections.addAll(provides, module.providesBeans()); + Collections.addAll(provides, module.autoProvidesBeans()); + for (final var provide : module.autoProvidesAspectBeans()) { + final var aspectType = Util.wrapAspect(provide); provides.add(aspectType); } registerExternalMetaData(name); readMetaDataProvides(provides); providedTypes.addAll(provides); - final var requires = Arrays.stream(module.requires()).map(Type::getTypeName).collect(toList()); - - Arrays.stream(module.autoRequires()).map(Type::getTypeName).forEach(requires::add); - Arrays.stream(module.requiresPackages()).map(Type::getTypeName).forEach(requires::add); - Arrays.stream(module.autoRequiresAspects()).map(Type::getTypeName).map(Util::wrapAspect).forEach(requires::add); + final List requires = new ArrayList<>(); + Collections.addAll(requires, module.requiresBeans()); + Collections.addAll(requires, module.autoRequiresBeans()); + Collections.addAll(requires, module.requiresPackagesFromType()); + Arrays.stream(module.autoRequiresAspectBeans()) + .map(Util::wrapAspect) + .forEach(requires::add); ProcessingContext.addModule(new ModuleData(name, List.copyOf(provides), requires)); } @@ -127,11 +125,11 @@ static void registerPluginProvidedTypes(ScopeInfo defaultScope) { continue; } APContext.logNote("Loaded Plugin: %s", plugin.getClass().getTypeName()); - for (final var provide : plugin.provides()) { - defaultScope.pluginProvided(provide.getTypeName()); + for (final var provide : plugin.providesBeans()) { + defaultScope.pluginProvided(provide); } - for (final var provide : plugin.providesAspects()) { - defaultScope.pluginProvided(Util.wrapAspect(provide.getTypeName())); + for (final var provide : plugin.providesAspectBeans()) { + defaultScope.pluginProvided(Util.wrapAspect(provide)); } } } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/ScopeInfo.java b/inject-generator/src/main/java/io/avaje/inject/generator/ScopeInfo.java index 9596791d7..73e176f83 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/ScopeInfo.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/ScopeInfo.java @@ -130,6 +130,8 @@ private void read(Element element) { ignoreSingleton = injectModule.ignoreSingleton(); injectModule.requires().stream().map(Object::toString).forEach(requires::add); injectModule.provides().stream().map(Object::toString).forEach(provides::add); + requires.addAll(injectModule.requiresString()); + provides.addAll(injectModule.providesString()); injectModule.requiresPackages().stream() .map(Object::toString) .forEach( @@ -391,12 +393,42 @@ void buildAtInjectModule(Append writer) { writer.append(Constants.AT_GENERATED).eol(); writer.append("@InjectModule("); boolean leadingComma = false; - if (!provides.isEmpty()) { + List regularProvides = new ArrayList<>(); + List genericProvides = new ArrayList<>(); + + for (var type : provides) { + if (type.contains("<")) { + genericProvides.add(type); + } else { + regularProvides.add(type); + } + } + + if (!regularProvides.isEmpty()) { attributeClasses(false, writer, "provides", provides); leadingComma = true; } - if (!requires.isEmpty()) { - attributeClasses(leadingComma, writer, "requires", requires); + if (!genericProvides.isEmpty()) { + attributeString(false, writer, "providesString", provides); + leadingComma = true; + } + + List regularRequires = new ArrayList<>(); + List genericRequires = new ArrayList<>(); + + for (var type : requires) { + if (type.contains("<")) { + genericRequires.add(type); + } else { + regularRequires.add(type); + } + } + if (!regularRequires.isEmpty()) { + attributeClasses(leadingComma, writer, "requires", regularRequires); + leadingComma = true; + } + if (!genericRequires.isEmpty()) { + attributeString(leadingComma, writer, "requiresString", requires); leadingComma = true; } if (!requiresPackages.isEmpty()) { @@ -412,7 +444,23 @@ void buildAtInjectModule(Append writer) { writer.append(")").eol(); } - private void attributeClasses(boolean leadingComma, Append writer, String prefix, Set classNames) { + private void attributeString( + boolean leadingComma, Append writer, String prefix, Set classNames) { + if (leadingComma) { + writer.append(", "); + } + writer.append("%s = {", prefix); + int c = 0; + for (final String value : classNames) { + if (c++ > 0) { + writer.append(","); + } + writer.append("\"%s\"", value); + } + writer.append("}"); + } + + private void attributeClasses(boolean leadingComma, Append writer, String prefix, Collection classNames) { if (leadingComma) { writer.append(", "); } @@ -429,32 +477,26 @@ private void attributeClasses(boolean leadingComma, Append writer, String prefix void buildProvides(Append writer) { if (!provides.isEmpty()) { - buildProvidesMethod(writer, "provides", provides); + buildProvidesMethod(writer, "providesBeans", provides); } if (!requires.isEmpty()) { - buildProvidesMethod(writer, "requires", requires); + buildProvidesMethod(writer, "requiresBeans", requires); } if (!requiresPackages.isEmpty()) { - buildProvidesMethod(writer, "requiresPackages", requiresPackages); + buildProvidesMethod(writer, "requiresPackagesFromType", requiresPackages); } } private void buildProvidesMethod(Append writer, String fieldName, Set types) { writer.append(" @Override").eol(); - final var arrayType = fieldName.contains("Aspects") ? "Class" : "Type"; - writer.append(" public %s[] %s() {", arrayType, fieldName).eol(); - writer.append(" return new %s[] {", arrayType).eol(); + writer.append(" public String[] %s() {", fieldName).eol(); + writer.append(" return new String[] {").eol(); for (final String rawType : types) { if (rawType.contains(":")) { continue; } - - if (rawType.contains("<")) { - writer.append(" new GenericType<%s>(){},", rawType).eol(); - } else { - writer.append(" %s.class,", rawType).eol(); - } + writer.append(" \"%s\",", rawType).eol(); } writer.append(" };").eol(); writer.append(" }").eol().eol(); @@ -463,28 +505,28 @@ private void buildProvidesMethod(Append writer, String fieldName, Set ty void buildAutoProvides(Append writer, Set autoProvides) { autoProvides.removeAll(provides); if (!autoProvides.isEmpty()) { - buildProvidesMethod(writer, "autoProvides", autoProvides); + buildProvidesMethod(writer, "autoProvidesBeans", autoProvides); } } void buildAutoProvidesAspects(Append writer, Set autoProvidesAspects) { autoProvidesAspects.removeAll(provides); if (!autoProvidesAspects.isEmpty()) { - buildProvidesMethod(writer, "autoProvidesAspects", autoProvidesAspects); + buildProvidesMethod(writer, "autoProvidesAspectBeans", autoProvidesAspects); } } void buildAutoRequires(Append writer, Set autoRequires) { autoRequires.removeAll(requires); if (!autoRequires.isEmpty()) { - buildProvidesMethod(writer, "autoRequires", autoRequires); + buildProvidesMethod(writer, "autoRequiresBeans", autoRequires); } } void buildAutoRequiresAspects(Append writer, Set autoRequires) { autoRequires.removeAll(requires); if (!autoRequires.isEmpty()) { - buildProvidesMethod(writer, "autoRequiresAspects", autoRequires); + buildProvidesMethod(writer, "autoRequiresAspectBeans", autoRequires); } } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleModuleWriter.java b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleModuleWriter.java index 2fe9f5b78..13b1dbf94 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleModuleWriter.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleModuleWriter.java @@ -1,13 +1,23 @@ package io.avaje.inject.generator; -import static io.avaje.inject.generator.APContext.*; -import static io.avaje.inject.generator.ProcessingContext.*; +import static io.avaje.inject.generator.APContext.logError; +import static io.avaje.inject.generator.APContext.typeElement; +import static io.avaje.inject.generator.ProcessingContext.allScopes; +import static io.avaje.inject.generator.ProcessingContext.createMetaInfWriterFor; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import java.io.IOException; import java.io.Writer; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; import java.util.function.Predicate; import java.util.stream.Stream; diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/_Wiring.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/_Wiring.java index 9dd537014..973217dbb 100644 --- a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/_Wiring.java +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/_Wiring.java @@ -2,7 +2,7 @@ import io.avaje.inject.Factory; import io.avaje.inject.InjectModule; -@InjectModule(strictWiring = true) + +@InjectModule(strictWiring = true, providesString = "java.util.Queue") @Factory -public class _Wiring { -} \ No newline at end of file +public class _Wiring {} diff --git a/inject-gradle-plugin/src/main/java/io/avaje/inject/plugin/AvajeInjectPlugin.java b/inject-gradle-plugin/src/main/java/io/avaje/inject/plugin/AvajeInjectPlugin.java index 8fa751ab8..bab001186 100644 --- a/inject-gradle-plugin/src/main/java/io/avaje/inject/plugin/AvajeInjectPlugin.java +++ b/inject-gradle-plugin/src/main/java/io/avaje/inject/plugin/AvajeInjectPlugin.java @@ -74,10 +74,10 @@ private void writeProvidedPlugins(ClassLoader classLoader, FileWriter pluginWrit final List provides = new ArrayList<>(); final var typeName = plugin.getClass().getTypeName(); System.out.println("Loaded Plugin: " + typeName); - for (final var provide : plugin.provides()) { - provides.add(provide.getTypeName()); + for (final var provide : plugin.providesBeans()) { + provides.add(provide); } - for (final var provide : plugin.providesAspects()) { + for (final var provide : plugin.providesAspectBeans()) { provides.add(wrapAspect(provide.getCanonicalName())); } pluginEntries.put(typeName, provides); @@ -129,25 +129,24 @@ private void writeModuleCSV(ClassLoader classLoader, FileWriter moduleWriter) th System.out.println("Detected External Module: " + name); final var provides = new ArrayList(); - for (final var provide : module.provides()) { - var type = provide.getTypeName(); + for (final var provide : module.providesBeans()) { + var type = provide; provides.add(type); } - for (final var provide : module.autoProvides()) { - var type = provide.getTypeName(); + for (final var provide : module.autoProvidesBeans()) { + var type = provide; provides.add(type); } - for (final var provide : module.autoProvidesAspects()) { - var type = wrapAspect(provide.getTypeName()); + for (final var provide : module.autoprovidesAspectBeans()) { + var type = wrapAspect(provide); provides.add(type); } - final var requires = Arrays.stream(module.requires()).map(Type::getTypeName).collect(toList()); + final var requires = Arrays.stream(module.requiresBeans()).collect(toList()); - Arrays.stream(module.autoRequires()).map(Type::getTypeName).forEach(requires::add); - Arrays.stream(module.requiresPackages()).map(Type::getTypeName).forEach(requires::add); - Arrays.stream(module.autoRequiresAspects()) - .map(Type::getTypeName) + Arrays.stream(module.autoRequires()).forEach(requires::add); + Arrays.stream(module.requiresPackages()).forEach(requires::add); + Arrays.stream(module.autoRequiresAspects()) .map(AvajeInjectPlugin::wrapAspect) .forEach(requires::add); modules.add(new ModuleData(name, provides, requires)); diff --git a/inject-maven-plugin/src/main/java/io/avaje/inject/mojo/AutoProvidesMojo.java b/inject-maven-plugin/src/main/java/io/avaje/inject/mojo/AutoProvidesMojo.java index 2f15349e0..7a8e3d4de 100644 --- a/inject-maven-plugin/src/main/java/io/avaje/inject/mojo/AutoProvidesMojo.java +++ b/inject-maven-plugin/src/main/java/io/avaje/inject/mojo/AutoProvidesMojo.java @@ -5,12 +5,12 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -85,14 +85,16 @@ private List compileDependencies() throws MojoExecutionException { } private URLClassLoader createClassLoader(List listUrl) { - return new URLClassLoader(listUrl.toArray(new URL[listUrl.size()]), Thread.currentThread().getContextClassLoader()); + return new URLClassLoader( + listUrl.toArray(new URL[listUrl.size()]), Thread.currentThread().getContextClassLoader()); } private FileWriter createFileWriter(String string) throws IOException { return new FileWriter(new File(project.getBuild().getDirectory(), string)); } - private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter pluginWriter) throws IOException { + private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter pluginWriter) + throws IOException { final Log log = getLog(); final List plugins = new ArrayList<>(); @@ -105,15 +107,13 @@ private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter plug final Map> pluginEntries = new HashMap<>(); for (final var plugin : plugins) { final List provides = new ArrayList<>(); - final var typeName = plugin.getClass().getTypeName(); + final var typeName = plugin.getClass(); log.info("Loaded Plugin: " + typeName); - for (final var provide : plugin.provides()) { - provides.add(provide.getTypeName()); - } + Collections.addAll(provides, plugin.providesBeans()); for (final var provide : plugin.providesAspects()) { provides.add(wrapAspect(provide.getCanonicalName())); } - pluginEntries.put(typeName, provides); + pluginEntries.put(typeName.getTypeName(), provides); } pluginWriter.write("External Plugin Type|Provides"); @@ -126,7 +126,8 @@ private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter plug } } - private void writeModuleCSV(ClassLoader newClassLoader, FileWriter moduleWriter) throws IOException { + private void writeModuleCSV(ClassLoader newClassLoader, FileWriter moduleWriter) + throws IOException { final Log log = getLog(); final List avajeModules = new ArrayList<>(); ServiceLoader.load(InjectExtension.class, newClassLoader).stream() @@ -137,35 +138,33 @@ private void writeModuleCSV(ClassLoader newClassLoader, FileWriter moduleWriter) List modules = new ArrayList<>(); for (final var module : avajeModules) { - final var name = module.getClass().getTypeName(); + final var name = module.getClass(); log.info("Detected External Module: " + name); final var provides = new ArrayList(); - for (final var provide : module.provides()) { - var type = provide.getTypeName(); + for (final var provide : module.providesBeans()) { + var type = provide; provides.add(type); } - for (final var provide : module.autoProvides()) { - var type = provide.getTypeName(); + for (final var provide : module.autoProvidesBeans()) { + var type = provide; provides.add(type); } - for (final var provide : module.autoProvidesAspects()) { - var type = wrapAspect(provide.getTypeName()); + for (final var provide : module.autoProvidesAspectBeans()) { + var type = wrapAspect(provide); provides.add(type); } - final var requires = - Arrays.stream(module.requires()).map(Type::getTypeName).collect(toList()); + final var requires = Arrays.stream(module.requiresBeans()).collect(toList()); - Arrays.stream(module.autoRequires()).map(Type::getTypeName).forEach(requires::add); - Arrays.stream(module.requiresPackages()).map(Type::getTypeName).forEach(requires::add); - Arrays.stream(module.autoRequiresAspects()) - .map(Type::getTypeName) - .map(AutoProvidesMojo::wrapAspect) - .forEach(requires::add); - modules.add(new ModuleData(name, provides, requires)); + Collections.addAll(requires, module.autoRequiresBeans()); + Collections.addAll(requires, module.requiresPackagesFromType()); + Arrays.stream(module.autoRequiresAspectBeans()) + .map(AutoProvidesMojo::wrapAspect) + .forEach(requires::add); + modules.add(new ModuleData(name.getTypeName(), provides, requires)); } moduleWriter.write("External Module Type|Provides|Requires"); diff --git a/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java b/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java index 813ac0b94..a8261d449 100644 --- a/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java +++ b/inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java @@ -326,9 +326,9 @@ public void add(AvajeModule module) { .computeIfAbsent(module.getClass().getTypeName(), s -> new FactoryList()) .add(factoryState); - addFactoryProvides(factoryState, module.provides()); - addFactoryProvides(factoryState, module.autoProvides()); - addFactoryProvides(factoryState, module.autoProvidesAspects()); + addFactoryProvides(factoryState, module.providesBeans()); + addFactoryProvides(factoryState, module.autoProvidesBeans()); + addFactoryProvides(factoryState, module.autoProvidesAspectBeans()); if (factoryState.isRequiresEmpty()) { if (factoryState.explicitlyProvides()) { @@ -344,9 +344,9 @@ public void add(AvajeModule module) { } } - private void addFactoryProvides(FactoryState factoryState, Type[] provides) { + private void addFactoryProvides(FactoryState factoryState, String[] provides) { for (final var feature : provides) { - providesMap.computeIfAbsent(feature.getTypeName(), s -> new FactoryList()).add(factoryState); + providesMap.computeIfAbsent(feature, s -> new FactoryList()).add(factoryState); } } @@ -403,10 +403,10 @@ private void processQueue() { } } - private void unsatisfiedRequires(StringBuilder sb, Type[] requiredType, String requires) { + private void unsatisfiedRequires(StringBuilder sb, String[] requiredType, String requires) { for (final var depModuleName : requiredType) { - if (notProvided(depModuleName.getTypeName())) { - sb.append(String.format(" %s [%s]", requires, depModuleName.getTypeName())); + if (notProvided(depModuleName)) { + sb.append(String.format(" %s [%s]", requires, depModuleName)); } } } @@ -447,9 +447,9 @@ && satisfiedDependencies(factory.autoRequiresAspects()) && satisfiedDependencies(factory.autoRequires()); } - private boolean satisfiedDependencies(Type[] requires) { + private boolean satisfiedDependencies(String[] requires) { for (final var dependency : requires) { - if (notProvided(dependency.getTypeName())) { + if (notProvided(dependency)) { return false; } } @@ -485,20 +485,20 @@ AvajeModule factory() { return factory; } - Type[] requires() { - return factory.requires(); + String[] requires() { + return factory.requiresBeans(); } - Type[] requiresPackages() { - return factory.requiresPackages(); + String[] requiresPackages() { + return factory.requiresPackagesFromType(); } - Type[] autoRequires() { - return factory.autoRequires(); + String[] autoRequires() { + return factory.autoRequiresBeans(); } - Type[] autoRequiresAspects() { - return factory.autoRequiresAspects(); + String[] autoRequiresAspects() { + return factory.autoRequiresAspectBeans(); } @Override @@ -507,15 +507,17 @@ public String toString() { } boolean isRequiresEmpty() { - return isEmpty(factory.requires()) && isEmpty(factory.requiresPackages()) - && isEmpty(factory.autoRequires()) && isEmpty(factory.autoRequiresAspects()); + return isEmpty(factory.requiresBeans()) + && isEmpty(factory.requiresPackagesFromType()) + && isEmpty(factory.autoRequiresBeans()) + && isEmpty(factory.autoRequiresAspectBeans()); } boolean explicitlyProvides() { - return !isEmpty(factory.provides()); + return !isEmpty(factory.providesBeans()); } - private boolean isEmpty(@Nullable Type[] values) { + private boolean isEmpty(@Nullable String[] values) { return values == null || values.length == 0; } } diff --git a/inject/src/main/java/io/avaje/inject/InjectModule.java b/inject/src/main/java/io/avaje/inject/InjectModule.java index a1e31af3d..d9265e350 100644 --- a/inject/src/main/java/io/avaje/inject/InjectModule.java +++ b/inject/src/main/java/io/avaje/inject/InjectModule.java @@ -76,24 +76,36 @@ boolean ignoreSingleton() default false; /** - * Explicitly define features that are provided by this module and required by other modules. - *

- * This is used to order wiring across multiple modules. Modules that provide dependencies + * Explicitly define beans that are provided by this module and required by other modules. + * + *

This is used to order wiring across multiple modules. Modules that provide dependencies * should be wired before modules that require dependencies. */ Class[] provides() default {}; /** - * The dependencies that are provided externally or by other modules and that are required - * when wiring this module. - *

- * This effectively tells the annotation processor that these types are expected to be - * provided and to not treat them as missing dependencies. If we don't do this the annotation - * processor thinks the dependency is missing and will error the compilation saying there is - * a missing dependency. + * Required external beans for wiring this module. + * + *

This tells the annotation processor that these types are expected to be provided and to not + * treat them as missing dependencies. If we don't do this the annotation processor thinks the + * dependency is missing and will error the compilation saying there is a missing dependency. */ Class[] requires() default {}; + /** + * Explicitly define beans provided by this module and required by other modules. + * + * @see #provides() + */ + String[] providesString() default {}; + + /** + * Required external beans for wiring this module. + * + * @see #requires() + */ + String[] requiresString() default {}; + /** * Dependencies in these packages are expected to be provided by other modules. *

diff --git a/inject/src/main/java/io/avaje/inject/spi/AvajeModule.java b/inject/src/main/java/io/avaje/inject/spi/AvajeModule.java index 1cfb33e72..daab44d99 100644 --- a/inject/src/main/java/io/avaje/inject/spi/AvajeModule.java +++ b/inject/src/main/java/io/avaje/inject/spi/AvajeModule.java @@ -1,58 +1,114 @@ package io.avaje.inject.spi; import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Objects; -/** - * A Module containing dependencies that will be included in BeanScope. - */ +/** A Module containing dependencies that will be included in BeanScope. */ public interface AvajeModule extends InjectExtension { - /** - * Empty array of classes. - */ + /** Empty array of classes. */ + @Deprecated(forRemoval = true) Class[] EMPTY_CLASSES = {}; + /** Empty array of strings. */ + String[] EMPTY_STRINGS = {}; + /** * Return the set of types this module explicitly provides to other modules. + * + * @deprecated use {@link #providesBeans()} */ + @Deprecated(forRemoval = true) default Type[] provides() { return EMPTY_CLASSES; } + /** Return the type names of types this module explicitly provides to other modules. */ + default String[] providesBeans() { + return Arrays.stream(Objects.requireNonNullElse(provides(), EMPTY_CLASSES)) + .map(Type::getTypeName) + .toArray(String[]::new); + } + /** * Return the types this module needs to be provided externally or via other modules. + * + * @deprecated use {@link #requiresBeans()} */ + @Deprecated(forRemoval = true) default Type[] requires() { return EMPTY_CLASSES; } + /** + * Return the type names of types this module needs to be provided externally or via other + * modules. + */ + default String[] requiresBeans() { + return Arrays.stream(Objects.requireNonNullElse(requires(), EMPTY_CLASSES)) + .map(Type::getTypeName) + .toArray(String[]::new); + } + /** * Return the packages this module needs to be provided via other modules. + * + * @deprecated use {@link #requiresPackagesFromType()} */ + @Deprecated(forRemoval = true) default Type[] requiresPackages() { return EMPTY_CLASSES; } + /** Return the type names of packages this module needs to be provided via other modules. */ + default String[] requiresPackagesFromType() { + return Arrays.stream(Objects.requireNonNullElse(requiresPackages(), EMPTY_CLASSES)) + .map(Type::getTypeName) + .toArray(String[]::new); + } + /** * Return the classes that this module provides that we allow other modules to auto depend on. * *

This is a convenience when using multiple modules that is otherwise controlled manually by * explicitly using {@link AvajeModule#provides()}. + * + * @deprecated use {@link #autoProvidesBeans()} */ + @Deprecated(forRemoval = true) default Type[] autoProvides() { return EMPTY_CLASSES; } + /** + * Return the type names of classes that this module provides that we allow other modules to auto + * depend on. + */ + default String[] autoProvidesBeans() { + return Arrays.stream(Objects.requireNonNullElse(autoProvides(), EMPTY_CLASSES)) + .map(Type::getTypeName) + .toArray(String[]::new); + } + /** * Return the aspects that this module provides. * *

This is a convenience when using multiple modules that we otherwise manually specify via * {@link AvajeModule#provides()}. */ + @Deprecated(forRemoval = true) default Class[] autoProvidesAspects() { return EMPTY_CLASSES; } + /** Return the type names of aspects that this module provides. */ + default String[] autoProvidesAspectBeans() { + return Arrays.stream(Objects.requireNonNullElse(autoProvidesAspects(), EMPTY_CLASSES)) + .map(Class::getTypeName) + .toArray(String[]::new); + } + /** * These are the classes that this module requires for wiring that are provided by other external * modules (that are in the classpath at compile time). @@ -60,18 +116,40 @@ default Class[] autoProvidesAspects() { *

This is a convenience when using multiple modules that is otherwise controlled manually by * explicitly using {@link AvajeModule#requires()} or {@link AvajeModule#requiresPackages()}. */ + @Deprecated(forRemoval = true) default Type[] autoRequires() { return EMPTY_CLASSES; } + /** + * Return the type names of classes that this module requires for wiring that are provided by + * other external modules. + */ + default String[] autoRequiresBeans() { + return Arrays.stream(Objects.requireNonNullElse(autoRequires(), EMPTY_CLASSES)) + .map(Type::getTypeName) + .toArray(String[]::new); + } + /** * These are the aspects that this module requires whose implementations are provided by other * external modules (that are in the classpath at compile time). */ + @Deprecated(forRemoval = true) default Class[] autoRequiresAspects() { return EMPTY_CLASSES; } + /** + * Return the type names of aspects that this module requires whose implementations are provided + * by other external modules. + */ + default String[] autoRequiresAspectBeans() { + return Arrays.stream(Objects.requireNonNullElse(autoRequiresAspects(), EMPTY_CLASSES)) + .map(Class::getTypeName) + .toArray(String[]::new); + } + /** * Return public classes of the beans that would be registered by this module. * @@ -80,14 +158,9 @@ default Class[] autoRequiresAspects() { */ Class[] classes(); - /** - * Build all the beans. - */ + /** Build all the beans. */ void build(Builder builder); - /** - * Marker for custom scoped modules. - */ - interface Custom extends AvajeModule { - } + /** Marker for custom scoped modules. */ + interface Custom extends AvajeModule {} } diff --git a/inject/src/main/java/io/avaje/inject/spi/InjectPlugin.java b/inject/src/main/java/io/avaje/inject/spi/InjectPlugin.java index 3677b88a7..103ba7412 100644 --- a/inject/src/main/java/io/avaje/inject/spi/InjectPlugin.java +++ b/inject/src/main/java/io/avaje/inject/spi/InjectPlugin.java @@ -1,8 +1,9 @@ package io.avaje.inject.spi; -import io.avaje.inject.BeanScopeBuilder; - import java.lang.reflect.Type; +import java.util.Arrays; + +import io.avaje.inject.BeanScopeBuilder; /** * A Plugin that can be applied when creating a bean scope. @@ -12,27 +13,32 @@ */ public interface InjectPlugin extends InjectExtension { - /** - * Empty array of classes. - */ + /** Empty array of classes. */ Class[] EMPTY_CLASSES = {}; - /** - * Apply the plugin to the scope builder. - */ + /** Empty array of classes. */ + String[] EMPTY_STRINGS = {}; + + /** Apply the plugin to the scope builder. */ void apply(BeanScopeBuilder builder); - /** - * Return the classes that the plugin provides. - */ + /** Return the classes that the plugin provides. */ default Type[] provides() { return EMPTY_CLASSES; } - /** - * Return the aspect classes that the plugin provides. - */ + /** Return the type names of types this module explicitly provides to other modules. */ + default String[] providesBeans() { + return Arrays.stream(provides()).map(Type::getTypeName).toArray(String[]::new); + } + + /** Return the aspect classes that the plugin provides. */ default Class[] providesAspects() { return EMPTY_CLASSES; } + + /** Return the type names of types this module explicitly provides to other modules. */ + default String[] providesAspectBeans() { + return Arrays.stream(providesAspects()).map(Type::getTypeName).toArray(String[]::new); + } }