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..1415c2e04 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)); } 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/build.gradle b/inject-gradle-plugin/build.gradle index f36c44a60..c48d22706 100644 --- a/inject-gradle-plugin/build.gradle +++ b/inject-gradle-plugin/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'io.avaje.inject' -version '11.1' +version '11.6-RC4' repositories { mavenLocal() @@ -14,7 +14,7 @@ repositories { } dependencies { - implementation 'io.avaje:avaje-inject:11.1' + implementation 'io.avaje:avaje-inject:11.6-RC4' implementation gradleApi() testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' 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..c497959af 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 @@ -49,8 +49,8 @@ private void writeProvides(Project project) { try (var classLoader = classLoader(project); var pluginWriter = createFileWriter(outputDir.getPath(), "avaje-plugins.csv"); var moduleCSV = createFileWriter(outputDir.getPath(), "avaje-module-dependencies.csv")) { - writeProvidedPlugins(classLoader, pluginWriter); - writeModuleCSV(classLoader, moduleCSV); + writeProvidedPlugins(classLoader, pluginWriter); + writeModuleCSV(classLoader, moduleCSV); } catch (IOException e) { throw new GradleException("Failed to write avaje-module-provides", e); } @@ -104,7 +104,8 @@ private URLClassLoader classLoader(Project project) { private static URL[] createClassPath(Project project) { try { - Set compileClasspath = project.getConfigurations().getByName("compileClasspath").resolve(); + Set compileClasspath = + project.getConfigurations().getByName("compileClasspath").resolve(); final List urls = new ArrayList<>(compileClasspath.size()); for (File file : compileClasspath) { urls.add(file.toURI().toURL()); @@ -129,25 +130,15 @@ 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(); - provides.add(type); - } - for (final var provide : module.autoProvidesAspects()) { - var type = wrapAspect(provide.getTypeName()); - provides.add(type); - } - - 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) + final var requires = Arrays.stream(module.requiresBeans()).collect(toList()); + Collections.addAll(requires, module.requiresPackagesFromType()); + Arrays.stream(module.autoRequiresAspects()) + .map(Class::getTypeName) .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..55e0b0775 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,7 +107,7 @@ 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()); @@ -113,7 +115,7 @@ private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter plug 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 +128,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 +140,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..f73b87d7d 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,125 @@ 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. */ + @Deprecated(forRemoval = true) + Class[] EMPTY_CLASSES = {}; + + /** Empty array of strings. */ + String[] EMPTY_STRINGS = {}; + /** - * Empty array of classes. + * Return public classes of the beans that would be registered by this module. + * + *

This method allows code to use reflection to inspect the modules classes before the module + * is wired. This method is not required for DI wiring. */ - Class[] EMPTY_CLASSES = {}; + Class[] classes(); + + /** Build all the beans. */ + void build(Builder builder); /** * 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,34 +127,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 public classes of the beans that would be registered by this module. - * - *

This method allows code to use reflection to inspect the modules classes before the module - * is wired. This method is not required for DI wiring. - */ - Class[] classes(); - - /** - * Build all the beans. + * Return the type names of aspects that this module requires whose implementations are provided + * by other external modules. */ - void build(Builder builder); - - /** - * Marker for custom scoped modules. - */ - interface Custom extends AvajeModule { + default String[] autoRequiresAspectBeans() { + return Arrays.stream(Objects.requireNonNullElse(autoRequiresAspects(), EMPTY_CLASSES)) + .map(Class::getTypeName) + .toArray(String[]::new); } + + /** Marker for custom scoped modules. */ + interface Custom extends AvajeModule {} }