GH-9 - Rename core, public abstractions from Module to ApplicationModule.

Remove obsolete @since tags and deprecations.
This commit is contained in:
Oliver Drotbohm
2022-07-19 15:15:29 +02:00
parent 8ba6c11e3d
commit 82c18fe509
60 changed files with 272 additions and 341 deletions

View File

@@ -27,7 +27,7 @@ import java.lang.annotation.Target;
*/
@Target({ ElementType.PACKAGE, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Module {
public @interface ApplicationModule {
String displayName() default "";

View File

@@ -22,7 +22,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation to mark a package as named interface of a {@link Module} (either implicit or explicitly annotated).
* Annotation to mark a package as named interface of a {@link ApplicationModule} (either implicit or explicitly annotated).
*
* @author Oliver Drotbohm
*/

View File

@@ -61,10 +61,10 @@ import com.tngtech.archunit.thirdparty.com.google.common.base.Suppliers;
* @author Oliver Drotbohm
*/
@EqualsAndHashCode(doNotUseGetters = true)
public class Module {
public class ApplicationModule {
private final @Getter JavaPackage basePackage;
private final ModuleInformation information;
private final ApplicationModuleInformation information;
private final @Getter NamedInterfaces namedInterfaces;
private final boolean useFullyQualifiedModuleNames;
@@ -72,10 +72,10 @@ public class Module {
private final Supplier<Classes> entities;
private final Supplier<List<EventType>> publishedEvents;
Module(JavaPackage basePackage, boolean useFullyQualifiedModuleNames) {
ApplicationModule(JavaPackage basePackage, boolean useFullyQualifiedModuleNames) {
this.basePackage = basePackage;
this.information = ModuleInformation.of(basePackage);
this.information = ApplicationModuleInformation.of(basePackage);
this.namedInterfaces = NamedInterfaces.discoverNamedInterfaces(basePackage);
this.useFullyQualifiedModuleNames = useFullyQualifiedModuleNames;
@@ -92,7 +92,7 @@ public class Module {
return information.getDisplayName();
}
public List<Module> getDependencies(Modules modules, DependencyType... type) {
public List<ApplicationModule> getDependencies(ApplicationModules modules, DependencyType... type) {
return getAllModuleDependencies(modules) //
.filter(it -> type.length == 0 ? true : Arrays.stream(type).anyMatch(it::hasType)) //
@@ -108,7 +108,7 @@ public class Module {
* @param modules must not be {@literal null}.
* @return
*/
public List<JavaClass> getEventsListenedTo(Modules modules) {
public List<JavaClass> getEventsListenedTo(ApplicationModules modules) {
Assert.notNull(modules, "Modules must not be null!");
@@ -143,35 +143,20 @@ public class Module {
.collect(Collectors.toList());
}
/**
* Returns all types that are considered aggregate roots.
*
* @param modules must not be {@literal null}.
* @return
* @deprecated since 1.3, use {@link #getAggregateRoots()} instead.
*/
@Deprecated
public List<JavaClass> getAggregateRoots(Modules modules) {
Assert.notNull(modules, "Modules must not be null!");
return getAggregateRoots();
}
/**
* Returns all modules that contain types which the types of the current module depend on.
*
* @param modules must not be {@literal null}.
* @return
*/
public Stream<Module> getBootstrapDependencies(Modules modules) {
public Stream<ApplicationModule> getBootstrapDependencies(ApplicationModules modules) {
Assert.notNull(modules, "Modules must not be null!");
return getBootstrapDependencies(modules, DependencyDepth.IMMEDIATE);
}
public Stream<Module> getBootstrapDependencies(Modules modules, DependencyDepth depth) {
public Stream<ApplicationModule> getBootstrapDependencies(ApplicationModules modules, DependencyDepth depth) {
Assert.notNull(modules, "Modules must not be null!");
Assert.notNull(depth, "Dependency depth must not be null!");
@@ -186,15 +171,15 @@ public class Module {
* @param depth must not be {@literal null}.
* @return
*/
public Stream<JavaPackage> getBasePackages(Modules modules, DependencyDepth depth) {
public Stream<JavaPackage> getBasePackages(ApplicationModules modules, DependencyDepth depth) {
Assert.notNull(modules, "Modules must not be null!");
Assert.notNull(depth, "Dependency depth must not be null!");
Stream<Module> dependencies = streamDependencies(modules, depth);
Stream<ApplicationModule> dependencies = streamDependencies(modules, depth);
return Stream.concat(Stream.of(this), dependencies) //
.map(Module::getBasePackage);
.map(ApplicationModule::getBasePackage);
}
public List<SpringBean> getSpringBeans() {
@@ -212,7 +197,7 @@ public class Module {
}
public boolean contains(@Nullable Class<?> type) {
return type != null && getType(type.getName()).isPresent();
return (type != null) && getType(type.getName()).isPresent();
}
/**
@@ -220,7 +205,6 @@ public class Module {
*
* @param candidate must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 1.1
*/
public Optional<JavaClass> getType(String candidate) {
@@ -245,11 +229,11 @@ public class Module {
return namedInterfaces.stream().anyMatch(it -> it.contains(type));
}
public void verifyDependencies(Modules modules) {
public void verifyDependencies(ApplicationModules modules) {
detectDependencies(modules).throwIfPresent();
}
public Violations detectDependencies(Modules modules) {
public Violations detectDependencies(ApplicationModules modules) {
return getAllModuleDependencies(modules) //
.map(it -> it.isValidDependencyWithin(modules)) //
@@ -265,7 +249,7 @@ public class Module {
return toString(null);
}
public String toString(@Nullable Modules modules) {
public String toString(@Nullable ApplicationModules modules) {
StringBuilder builder = new StringBuilder("## ").append(getDisplayName()).append(" ##\n");
builder.append("> Logical name: ").append(getName()).append('\n');
@@ -282,11 +266,11 @@ public class Module {
if (modules != null) {
List<Module> dependencies = getBootstrapDependencies(modules).collect(Collectors.toList());
List<ApplicationModule> dependencies = getBootstrapDependencies(modules).collect(Collectors.toList());
builder.append("> Direct module dependencies: ");
builder.append(dependencies.isEmpty() ? "none"
: dependencies.stream().map(Module::getName).collect(Collectors.joining(", ")));
: dependencies.stream().map(ApplicationModule::getName).collect(Collectors.joining(", ")));
builder.append('\n');
}
@@ -309,12 +293,12 @@ public class Module {
/**
* Returns all allowed module dependencies, either explicitly declared or defined as shared on the given
* {@link Modules} instance.
* {@link ApplicationModules} instance.
*
* @param modules must not be {@literal null}.
* @return
*/
List<Module> getAllowedDependencies(Modules modules) {
List<ApplicationModule> getAllowedDependencies(ApplicationModules modules) {
Assert.notNull(modules, "Modules must not be null!");
@@ -324,7 +308,7 @@ public class Module {
return Collections.emptyList();
}
Stream<Module> explicitlyDeclaredModules = allowedDependencyNames.stream() //
Stream<ApplicationModule> explicitlyDeclaredModules = allowedDependencyNames.stream() //
.map(modules::getModuleByName) //
.flatMap(it -> it.map(Stream::of).orElse(Stream.empty()));
@@ -338,7 +322,6 @@ public class Module {
*
* @param candidate must not be {@literal null} or empty.
* @return
* @since 1.1
*/
boolean contains(String candidate) {
@@ -373,13 +356,13 @@ public class Module {
Stream.of(type));
}
private Stream<ModuleDependency> getAllModuleDependencies(Modules modules) {
private Stream<ModuleDependency> getAllModuleDependencies(ApplicationModules modules) {
return basePackage.stream() //
.flatMap(it -> getModuleDependenciesOf(it, modules));
}
private Stream<Module> streamDependencies(Modules modules, DependencyDepth depth) {
private Stream<ApplicationModule> streamDependencies(ApplicationModules modules, DependencyDepth depth) {
switch (depth) {
@@ -395,7 +378,7 @@ public class Module {
}
}
private Stream<Module> getDirectModuleDependencies(Modules modules) {
private Stream<ApplicationModule> getDirectModuleDependencies(ApplicationModules modules) {
return getSpringBeansInternal().stream() //
.flatMap(it -> ModuleDependency.fromType(it)) //
@@ -405,7 +388,7 @@ public class Module {
.flatMap(it -> it.map(Stream::of).orElseGet(Stream::empty));
}
private Stream<ModuleDependency> getModuleDependenciesOf(JavaClass type, Modules modules) {
private Stream<ModuleDependency> getModuleDependenciesOf(JavaClass type, ApplicationModules modules) {
Stream<ModuleDependency> injections = ModuleDependency.fromType(type) //
.filter(it -> isDependencyToOtherModule(it.getTarget(), modules)); //
@@ -417,7 +400,7 @@ public class Module {
return Stream.concat(injections, directDependencies).distinct();
}
private boolean isDependencyToOtherModule(JavaClass dependency, Modules modules) {
private boolean isDependencyToOtherModule(JavaClass dependency, ApplicationModules modules) {
return modules.contains(dependency) && !contains(dependency);
}
@@ -483,18 +466,18 @@ public class Module {
return this.type.equals(type);
}
Violations isValidDependencyWithin(Modules modules) {
Violations isValidDependencyWithin(ApplicationModules modules) {
Module originModule = getExistingModuleOf(origin, modules);
Module targetModule = getExistingModuleOf(target, modules);
ApplicationModule originModule = getExistingModuleOf(origin, modules);
ApplicationModule targetModule = getExistingModuleOf(target, modules);
List<Module> allowedTargets = originModule.getAllowedDependencies(modules);
List<ApplicationModule> allowedTargets = originModule.getAllowedDependencies(modules);
Violations violations = Violations.NONE;
if (!allowedTargets.isEmpty() && !allowedTargets.contains(targetModule)) {
String allowedTargetsString = allowedTargets.stream() //
.map(Module::getName) //
.map(ApplicationModule::getName) //
.collect(Collectors.joining(", "));
String message = String.format("Module '%s' depends on module '%s' via %s -> %s. Allowed target modules: %s.",
@@ -514,9 +497,9 @@ public class Module {
return violations;
}
Module getExistingModuleOf(JavaClass javaClass, Modules modules) {
ApplicationModule getExistingModuleOf(JavaClass javaClass, ApplicationModules modules) {
Optional<Module> module = modules.getModuleByType(javaClass);
Optional<ApplicationModule> module = modules.getModuleByType(javaClass);
return module.orElseThrow(() -> new IllegalStateException(
String.format("Origin/Target of a %s should always be within a module, but %s is not",
@@ -550,7 +533,7 @@ public class Module {
Set<JavaConstructor> constructors = source.getConstructors();
return constructors.stream() //
.filter(it -> constructors.size() == 1 || isInjectionPoint(it)) //
.filter(it -> (constructors.size() == 1) || isInjectionPoint(it)) //
.flatMap(it -> it.getRawParameterTypes().stream() //
.map(parameter -> new InjectionModuleDependency(source, parameter, it)));
}
@@ -673,13 +656,13 @@ public class Module {
* @see org.springframework.modulith.model.Module.ModuleDependency#isValidDependencyWithin(org.springframework.modulith.model.Modules)
*/
@Override
Violations isValidDependencyWithin(Modules modules) {
Violations isValidDependencyWithin(ApplicationModules modules) {
Violations violations = super.isValidDependencyWithin(modules);
if (JavaField.class.isInstance(member) && !isConfigurationClass) {
Module module = getExistingModuleOf(member.getOwner(), modules);
ApplicationModule module = getExistingModuleOf(member.getOwner(), modules);
violations = violations.and(new IllegalStateException(
String.format("Module %s uses field injection in %s. Prefer constructor injection instead!",

View File

@@ -18,17 +18,17 @@ package org.springframework.modulith.model;
import java.util.Objects;
import java.util.stream.Stream;
import org.springframework.modulith.Module;
import org.springframework.modulith.ApplicationModule;
import org.springframework.modulith.model.Types.JMoleculesTypes;
/**
* Default implementations of {@link ModuleDetectionStrategy}.
* Default implementations of {@link ApplicationModuleDetectionStrategy}.
*
* @author Oliver Drotbohm
* @see ModuleDetectionStrategy#directSubPackage()
* @see ModuleDetectionStrategy#explictlyAnnotated()
* @see ApplicationModuleDetectionStrategy#directSubPackage()
* @see ApplicationModuleDetectionStrategy#explictlyAnnotated()
*/
enum ModuleDetectionStrategies implements ModuleDetectionStrategy {
enum ApplicationModuleDetectionStrategies implements ApplicationModuleDetectionStrategy {
DIRECT_SUB_PACKAGES {
@@ -52,7 +52,7 @@ enum ModuleDetectionStrategies implements ModuleDetectionStrategy {
@Override
public Stream<JavaPackage> getModuleBasePackages(JavaPackage basePackage) {
return Stream.of(Module.class, JMoleculesTypes.getModuleAnnotationTypeIfPresent())
return Stream.of(ApplicationModule.class, JMoleculesTypes.getModuleAnnotationTypeIfPresent())
.filter(Objects::nonNull)
.flatMap(basePackage::getSubPackagesAnnotatedWith);
}

View File

@@ -17,14 +17,14 @@ package org.springframework.modulith.model;
import java.util.stream.Stream;
import org.springframework.modulith.Module;
import org.springframework.modulith.ApplicationModule;
/**
* Strategy interface to customize which packages are considered module base packages.
*
* @author Oliver Drotbohm
*/
public interface ModuleDetectionStrategy {
public interface ApplicationModuleDetectionStrategy {
/**
* Given the {@link JavaPackage} that Moduliths was initialized with, return the base packages for all modules in the
@@ -36,22 +36,22 @@ public interface ModuleDetectionStrategy {
Stream<JavaPackage> getModuleBasePackages(JavaPackage basePackage);
/**
* A {@link ModuleDetectionStrategy} that considers all direct sub-packages of the Moduliths base package to be module
* A {@link ApplicationModuleDetectionStrategy} that considers all direct sub-packages of the Moduliths base package to be module
* base packages.
*
* @return will never be {@literal null}.
*/
static ModuleDetectionStrategy directSubPackage() {
return ModuleDetectionStrategies.DIRECT_SUB_PACKAGES;
static ApplicationModuleDetectionStrategy directSubPackage() {
return ApplicationModuleDetectionStrategies.DIRECT_SUB_PACKAGES;
}
/**
* A {@link ModuleDetectionStrategy} that considers packages explicitly annotated with {@link Module} module base
* A {@link ApplicationModuleDetectionStrategy} that considers packages explicitly annotated with {@link ApplicationModule} module base
* packages.
*
* @return will never be {@literal null}.
*/
static ModuleDetectionStrategy explictlyAnnotated() {
return ModuleDetectionStrategies.EXPLICITLY_ANNOTATED;
static ApplicationModuleDetectionStrategy explictlyAnnotated() {
return ApplicationModuleDetectionStrategies.EXPLICITLY_ANNOTATED;
}
}

View File

@@ -25,7 +25,7 @@ import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.modulith.Module;
import org.springframework.modulith.ApplicationModule;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -35,11 +35,11 @@ import org.springframework.util.StringUtils;
*
* @author Oliver Drotbohm
*/
interface ModuleInformation {
interface ApplicationModuleInformation {
public static ModuleInformation of(JavaPackage javaPackage) {
public static ApplicationModuleInformation of(JavaPackage javaPackage) {
if (ClassUtils.isPresent("org.jmolecules.ddd.annotation.Module", ModuleInformation.class.getClassLoader())
if (ClassUtils.isPresent("org.jmolecules.ddd.annotation.Module", ApplicationModuleInformation.class.getClassLoader())
&& MoleculesModule.supports(javaPackage)) {
return new MoleculesModule(javaPackage);
}
@@ -52,7 +52,7 @@ interface ModuleInformation {
List<String> getAllowedDependencies();
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
static abstract class AbstractModuleInformation implements ModuleInformation {
static abstract class AbstractModuleInformation implements ApplicationModuleInformation {
private final JavaPackage javaPackage;
@@ -109,17 +109,17 @@ interface ModuleInformation {
static class ModulithsModule extends AbstractModuleInformation {
private final Optional<Module> annotation;
private final Optional<ApplicationModule> annotation;
public static boolean supports(JavaPackage javaPackage) {
return javaPackage.getAnnotation(Module.class).isPresent();
return javaPackage.getAnnotation(ApplicationModule.class).isPresent();
}
public ModulithsModule(JavaPackage javaPackage) {
super(javaPackage);
this.annotation = javaPackage.getAnnotation(Module.class);
this.annotation = javaPackage.getAnnotation(ApplicationModule.class);
}
/*
@@ -130,7 +130,7 @@ interface ModuleInformation {
public String getDisplayName() {
return annotation //
.map(Module::displayName) //
.map(ApplicationModule::displayName) //
.filter(StringUtils::hasText) //
.orElseGet(super::getDisplayName);
}

View File

@@ -51,16 +51,16 @@ import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition;
* @author Peter Gafert
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Modules implements Iterable<Module> {
public class ApplicationModules implements Iterable<ApplicationModule> {
private static final Map<CacheKey, Modules> CACHE = new HashMap<>();
private static final Map<CacheKey, ApplicationModules> CACHE = new HashMap<>();
private static final ModuleDetectionStrategy DETECTION_STRATEGY;
private static final ApplicationModuleDetectionStrategy DETECTION_STRATEGY;
static {
List<ModuleDetectionStrategy> loadFactories = SpringFactoriesLoader.loadFactories(ModuleDetectionStrategy.class,
Modules.class.getClassLoader());
List<ApplicationModuleDetectionStrategy> loadFactories = SpringFactoriesLoader.loadFactories(ApplicationModuleDetectionStrategy.class,
ApplicationModules.class.getClassLoader());
if (loadFactories.size() > 1) {
@@ -69,18 +69,18 @@ public class Modules implements Iterable<Module> {
loadFactories));
}
DETECTION_STRATEGY = loadFactories.isEmpty() ? ModuleDetectionStrategies.DIRECT_SUB_PACKAGES : loadFactories.get(0);
DETECTION_STRATEGY = loadFactories.isEmpty() ? ApplicationModuleDetectionStrategies.DIRECT_SUB_PACKAGES : loadFactories.get(0);
}
private final ModulithMetadata metadata;
private final Map<String, Module> modules;
private final Map<String, ApplicationModule> modules;
private final JavaClasses allClasses;
private final List<JavaPackage> rootPackages;
private final @With(AccessLevel.PRIVATE) @Getter Set<Module> sharedModules;
private final @With(AccessLevel.PRIVATE) @Getter Set<ApplicationModule> sharedModules;
private boolean verified;
private Modules(ModulithMetadata metadata, Collection<String> packages, DescribedPredicate<JavaClass> ignored,
private ApplicationModules(ModulithMetadata metadata, Collection<String> packages, DescribedPredicate<JavaClass> ignored,
boolean useFullyQualifiedModuleNames) {
this.metadata = metadata;
@@ -94,8 +94,8 @@ public class Modules implements Iterable<Module> {
this.modules = packages.stream() //
.map(it -> JavaPackage.of(classes, it))
.flatMap(DETECTION_STRATEGY::getModuleBasePackages) //
.map(it -> new Module(it, useFullyQualifiedModuleNames)) //
.collect(toMap(Module::getName, Function.identity()));
.map(it -> new ApplicationModule(it, useFullyQualifiedModuleNames)) //
.collect(toMap(ApplicationModule::getName, Function.identity()));
this.rootPackages = packages.stream() //
.map(it -> JavaPackage.of(classes, it).toSingle()) //
@@ -105,18 +105,18 @@ public class Modules implements Iterable<Module> {
}
/**
* Creates a new {@link Modules} relative to the given modulith type. Will inspect the {@link Modulith} annotation on
* Creates a new {@link ApplicationModules} relative to the given modulith type. Will inspect the {@link Modulith} annotation on
* the class given for advanced customizations of the module setup.
*
* @param modulithType must not be {@literal null}.
* @return
*/
public static Modules of(Class<?> modulithType) {
public static ApplicationModules of(Class<?> modulithType) {
return of(modulithType, alwaysFalse());
}
/**
* Creates a new {@link Modules} relative to the given modulith type, a {@link ModuleDetectionStrategy} and a
* Creates a new {@link ApplicationModules} relative to the given modulith type, a {@link ApplicationModuleDetectionStrategy} and a
* {@link DescribedPredicate} which types and packages to ignore. Will inspect the {@link Modulith} and
* {@link Modulithic} annotations on the class given for advanced customizations of the module setup.
*
@@ -125,7 +125,7 @@ public class Modules implements Iterable<Module> {
* @param ignored must not be {@literal null}.
* @return
*/
public static Modules of(Class<?> modulithType, DescribedPredicate<JavaClass> ignored) {
public static ApplicationModules of(Class<?> modulithType, DescribedPredicate<JavaClass> ignored) {
CacheKey key = TypeKey.of(modulithType, ignored);
@@ -139,25 +139,23 @@ public class Modules implements Iterable<Module> {
}
/**
* Creates a new {@link Modules} instance for the given package name.
* Creates a new {@link ApplicationModules} instance for the given package name.
*
* @param javaPackage must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 1.1
*/
public static Modules of(String javaPackage) {
public static ApplicationModules of(String javaPackage) {
return of(javaPackage, alwaysFalse());
}
/**
* Creates a new {@link Modules} instance for the given package name and ignored classes.
* Creates a new {@link ApplicationModules} instance for the given package name and ignored classes.
*
* @param javaPackage must not be {@literal null} or empty.
* @param ignored must not be {@literal null}.
* @return will never be {@literal null}.
* @since 1.1
*/
public static Modules of(String javaPackage, DescribedPredicate<JavaClass> ignored) {
public static ApplicationModules of(String javaPackage, DescribedPredicate<JavaClass> ignored) {
CacheKey key = PackageKey.of(javaPackage, ignored);
@@ -171,12 +169,12 @@ public class Modules implements Iterable<Module> {
}
/**
* Creates a new {@link Modules} instance for the given {@link CacheKey}.
* Creates a new {@link ApplicationModules} instance for the given {@link CacheKey}.
*
* @param key must not be {@literal null}.
* @return will never be {@literal null}.
*/
private static Modules of(CacheKey key) {
private static ApplicationModules of(CacheKey key) {
Assert.notNull(key, "Cache key must not be null!");
@@ -186,10 +184,10 @@ public class Modules implements Iterable<Module> {
basePackages.add(key.getBasePackage());
basePackages.addAll(metadata.getAdditionalPackages());
Modules modules = new Modules(metadata, basePackages, key.getIgnored(),
ApplicationModules modules = new ApplicationModules(metadata, basePackages, key.getIgnored(),
metadata.useFullyQualifiedModuleNames());
Set<Module> sharedModules = metadata.getSharedModuleNames() //
Set<ApplicationModule> sharedModules = metadata.getSharedModuleNames() //
.map(modules::getRequiredModule) //
.collect(Collectors.toSet());
@@ -201,24 +199,7 @@ public class Modules implements Iterable<Module> {
}
/**
* @return
* @deprecated since 1.1, as a {@link Modules} instance doesn't have to be created from a class in the first place.
* For generic use, use {@link #getModulithSource()} instead.
*/
@Deprecated
public Class<?> getModulithType() {
Object source = getModulithSource();
if (!Class.class.isInstance(source)) {
throw new IllegalStateException(String.format("Moduliths not created from a type but %s!", source));
}
return (Class<?>) source;
}
/**
* Returns whether the given {@link JavaClass} is contained within the {@link Modules}.
* Returns whether the given {@link JavaClass} is contained within the {@link ApplicationModules}.
*
* @param type must not be {@literal null}.
* @return
@@ -246,12 +227,12 @@ public class Modules implements Iterable<Module> {
}
/**
* Returns the {@link Module} with the given name.
* Returns the {@link ApplicationModule} with the given name.
*
* @param name must not be {@literal null} or empty.
* @return
*/
public Optional<Module> getModuleByName(String name) {
public Optional<ApplicationModule> getModuleByName(String name) {
Assert.hasText(name, "Module name must not be null or empty!");
@@ -264,7 +245,7 @@ public class Modules implements Iterable<Module> {
* @param type must not be {@literal null}.
* @return
*/
public Optional<Module> getModuleByType(JavaClass type) {
public Optional<ApplicationModule> getModuleByType(JavaClass type) {
Assert.notNull(type, "Type must not be null!");
@@ -274,13 +255,12 @@ public class Modules implements Iterable<Module> {
}
/**
* Returns the {@link Module} containing the type with the given simple or fully-qualified name.
* Returns the {@link ApplicationModule} containing the type with the given simple or fully-qualified name.
*
* @param candidate must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 1.1
*/
public Optional<Module> getModuleByType(String candidate) {
public Optional<ApplicationModule> getModuleByType(String candidate) {
Assert.hasText(candidate, "Candidate must not be null or empty!");
@@ -289,7 +269,7 @@ public class Modules implements Iterable<Module> {
.findFirst();
}
public Optional<Module> getModuleForPackage(String name) {
public Optional<ApplicationModule> getModuleForPackage(String name) {
return modules.values().stream() //
.filter(it -> name.startsWith(it.getBasePackage().getName())) //
@@ -342,11 +322,11 @@ public class Modules implements Iterable<Module> {
}
/**
* Returns all {@link Module}s.
* Returns all {@link ApplicationModule}s.
*
* @return will never be {@literal null}.
*/
public Stream<Module> stream() {
public Stream<ApplicationModule> stream() {
return modules.values().stream();
}
@@ -364,7 +344,7 @@ public class Modules implements Iterable<Module> {
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<Module> iterator() {
public Iterator<ApplicationModule> iterator() {
return modules.values().iterator();
}
@@ -374,9 +354,9 @@ public class Modules implements Iterable<Module> {
* @param moduleName must not be {@literal null}.
* @return
*/
private Module getRequiredModule(String moduleName) {
private ApplicationModule getRequiredModule(String moduleName) {
Module module = modules.get(moduleName);
ApplicationModule module = modules.get(moduleName);
if (module == null) {
throw new IllegalArgumentException(String.format("Module %s does not exist!", moduleName));

View File

@@ -66,7 +66,6 @@ class DefaultModulithMetadata implements ModulithMetadata {
*
* @param javaPackage must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 1.1
*/
public static ModulithMetadata of(String javaPackage) {

View File

@@ -31,7 +31,6 @@ import com.tngtech.archunit.core.domain.JavaModifier;
* A type that represents an event in a system.
*
* @author Oliver Drotbohm
* @since 1.1
*/
@Value
public class EventType {

View File

@@ -76,7 +76,7 @@ public class FormatableJavaClass {
return abbreviatedName.get();
}
public String getAbbreviatedFullName(@Nullable Module module) {
public String getAbbreviatedFullName(@Nullable ApplicationModule module) {
if (module == null) {
return getAbbreviatedFullName();

View File

@@ -25,7 +25,6 @@ import com.tngtech.archunit.core.domain.JavaCodeUnit;
* A {@link Source} backed by an ArchUnit {@link JavaAccess}.
*
* @author Oliver Drotbohm
* @since 1.1
*/
class JavaAccessSource implements Source {
@@ -56,7 +55,7 @@ class JavaAccessSource implements Source {
* @see org.springframework.modulith.model.Source#toString(org.springframework.modulith.model.Module)
*/
@Override
public String toString(Module module) {
public String toString(ApplicationModule module) {
boolean noParameters = method.getRawParameterTypes().isEmpty();

View File

@@ -55,7 +55,6 @@ interface ModulithMetadata {
*
* @param javaPackage must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 1.1
*/
public static ModulithMetadata of(String javaPackage) {
return DefaultModulithMetadata.of(javaPackage);
@@ -65,7 +64,6 @@ interface ModulithMetadata {
* Returns the source of the Moduliths setup. Either a type or a package.
*
* @return will never be {@literal null}.
* @since 1.1
*/
Object getModulithSource();

View File

@@ -19,7 +19,6 @@ package org.springframework.modulith.model;
* A {@link Source} of some type, bean definition etc. Essentially describes the origin of that bean, event etc.
*
* @author Oliver Drotbohm
* @since 1.1
*/
public interface Source {
@@ -29,5 +28,5 @@ public interface Source {
* @param module must not be {@literal null}.
* @return
*/
String toString(Module module);
String toString(ApplicationModule module);
}

View File

@@ -35,7 +35,7 @@ import com.tngtech.archunit.core.domain.JavaClass;
public class SpringBean {
private final @Getter JavaClass type;
private final Module module;
private final ApplicationModule module;
/**
* Returns the fully-qualified name of the Spring bean type.

View File

@@ -21,7 +21,7 @@ import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.modulith.model.Module.ModuleDependency;
import org.springframework.modulith.model.ApplicationModule.ModuleDependency;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.importer.ClassFileImporter;

View File

@@ -24,7 +24,7 @@ import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
/**
* Unit tests for {@link ModuleDetectionStrategy}.
* Unit tests for {@link ApplicationModuleDetectionStrategy}.
*
* @author Oliver Drotbohm
*/
@@ -33,15 +33,15 @@ class ModuleDetectionStrategyUnitTest {
@Test
void usesExplicitlyAnnotatedConstant() {
assertThat(ModuleDetectionStrategy.explictlyAnnotated())
.isEqualTo(ModuleDetectionStrategies.EXPLICITLY_ANNOTATED);
assertThat(ApplicationModuleDetectionStrategy.explictlyAnnotated())
.isEqualTo(ApplicationModuleDetectionStrategies.EXPLICITLY_ANNOTATED);
}
@Test
void usesDirectSubPackages() {
assertThat(ModuleDetectionStrategy.directSubPackage())
.isEqualTo(ModuleDetectionStrategies.DIRECT_SUB_PACKAGES);
assertThat(ApplicationModuleDetectionStrategy.directSubPackage())
.isEqualTo(ApplicationModuleDetectionStrategies.DIRECT_SUB_PACKAGES);
}
@Test
@@ -53,7 +53,7 @@ class ModuleDetectionStrategyUnitTest {
JavaPackage javaPackage = JavaPackage.of(Classes.of(classes), "jmolecules");
assertThat(ModuleDetectionStrategy.explictlyAnnotated().getModuleBasePackages(javaPackage))
assertThat(ApplicationModuleDetectionStrategy.explictlyAnnotated().getModuleBasePackages(javaPackage))
.containsExactly(javaPackage);
}
}

View File

@@ -32,7 +32,7 @@ import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
/**
* Unit tests for {@link Module}.
* Unit tests for {@link ApplicationModule}.
*
* @author Oliver Drotbohm
*/
@@ -43,7 +43,7 @@ class ModuleUnitTest {
JavaClasses classes = importer.importPackages("com.acme.withatbean"); //
JavaPackage javaPackage = JavaPackage.of(Classes.of(classes), "");
Module module = new Module(javaPackage, false);
ApplicationModule module = new ApplicationModule(javaPackage, false);
@Test
public void considersExternalSpringBeans() {

View File

@@ -36,10 +36,10 @@ import com.tngtech.archunit.thirdparty.com.google.common.base.Suppliers;
class TestUtils {
private static Supplier<JavaClasses> imported = Suppliers.memoize(() -> new ClassFileImporter() //
.importPackagesOf(Modules.class, Repository.class, AggregateRoot.class));
.importPackagesOf(ApplicationModules.class, Repository.class, AggregateRoot.class));
private static DescribedPredicate<JavaClass> IS_MODULE_TYPE = JavaClass.Predicates
.resideInAPackage(Modules.class.getPackage().getName());
.resideInAPackage(ApplicationModules.class.getPackage().getName());
private static Supplier<Classes> classes = Suppliers.memoize(() -> Classes.of(imported.get()).that(IS_MODULE_TYPE));

View File

@@ -31,8 +31,8 @@ import org.springframework.modulith.docs.Documenter.CanvasOptions.Groupings;
import org.springframework.modulith.model.ArchitecturallyEvidentType;
import org.springframework.modulith.model.EventType;
import org.springframework.modulith.model.FormatableJavaClass;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.model.Source;
import org.springframework.modulith.model.SpringBean;
import org.springframework.util.Assert;
@@ -51,11 +51,11 @@ class Asciidoctor {
private static String PLACEHOLDER = "¯\\_(ツ)_/¯";
private static final Pattern JAVADOC_CODE = Pattern.compile("\\{\\@(?>link|code|literal)\\s(.*)\\}");
private final Modules modules;
private final ApplicationModules modules;
private final String javaDocBase;
private final Optional<DocumentationSource> docSource;
private Asciidoctor(Modules modules, String javaDocBase) {
private Asciidoctor(ApplicationModules modules, String javaDocBase) {
Assert.notNull(modules, "Modules must not be null!");
Assert.hasText(javaDocBase, "Javadoc base must not be null or empty!");
@@ -69,23 +69,23 @@ class Asciidoctor {
}
/**
* Creates a new {@link Asciidoctor} instance for the given {@link Modules} and Javadoc base URI.
* Creates a new {@link Asciidoctor} instance for the given {@link ApplicationModules} and Javadoc base URI.
*
* @param modules must not be {@literal null}.
* @param javadocBase can be {@literal null}.
* @return will never be {@literal null}.
*/
public static Asciidoctor withJavadocBase(Modules modules, @Nullable String javadocBase) {
public static Asciidoctor withJavadocBase(ApplicationModules modules, @Nullable String javadocBase) {
return new Asciidoctor(modules, javadocBase == null ? PLACEHOLDER : javadocBase);
}
/**
* Creates a new {@link Asciidoctor} instance for the given {@link Modules}.
* Creates a new {@link Asciidoctor} instance for the given {@link ApplicationModules}.
*
* @param modules must not be {@literal null}.
* @return will never be {@literal null}.
*/
public static Asciidoctor withoutJavadocBase(Modules modules) {
public static Asciidoctor withoutJavadocBase(ApplicationModules modules) {
return new Asciidoctor(modules, PLACEHOLDER);
}
@@ -129,7 +129,7 @@ class Asciidoctor {
return String.format("%s implementing %s", base, interfacesAsString);
}
public String renderSpringBeans(CanvasOptions options, Module module) {
public String renderSpringBeans(CanvasOptions options, ApplicationModule module) {
StringBuilder builder = new StringBuilder();
Groupings groupings = options.groupBeans(module);
@@ -162,7 +162,7 @@ class Asciidoctor {
return builder.length() == 0 ? "None" : builder.toString();
}
public String renderEvents(Module module) {
public String renderEvents(ApplicationModule module) {
List<EventType> events = module.getPublishedEvents();
@@ -194,7 +194,7 @@ class Asciidoctor {
return builder.toString();
}
public String renderConfigurationProperties(Module module, List<ModuleProperty> properties) {
public String renderConfigurationProperties(ApplicationModule module, List<ModuleProperty> properties) {
if (properties.isEmpty()) {
return "none";
@@ -255,7 +255,7 @@ class Asciidoctor {
private String toOptionalLink(JavaClass source, Optional<String> methodSignature) {
Module module = modules.getModuleByType(source).orElse(null);
ApplicationModule module = modules.getModuleByType(source).orElse(null);
String typeAndMethod = toCode(
toTypeAndMethod(FormatableJavaClass.of(source).getAbbreviatedFullName(module), methodSignature));

View File

@@ -26,7 +26,6 @@ import com.tngtech.archunit.core.domain.JavaMethod;
* references
*
* @author Oliver Drotbohm
* @since 1.1
*/
@RequiredArgsConstructor
class CodeReplacingDocumentationSource implements DocumentationSource {

View File

@@ -30,7 +30,7 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.lang.Nullable;
import org.springframework.modulith.docs.ConfigurationProperties.ConfigurationProperty;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -42,7 +42,6 @@ import com.tngtech.archunit.core.domain.JavaType;
* Represents all {@link ConfigurationProperty} instances found for the current project.
*
* @author Oliver Drotbohm
* @since 1.3
*/
class ConfigurationProperties implements Iterable<ConfigurationProperty> {
@@ -71,12 +70,12 @@ class ConfigurationProperties implements Iterable<ConfigurationProperty> {
}
/**
* Returns all {@link ModuleProperty} instances for the given {@link Module}.
* Returns all {@link ModuleProperty} instances for the given {@link ApplicationModule}.
*
* @param module must not be {@literal null}.
* @return
*/
public List<ModuleProperty> getModuleProperties(Module module) {
public List<ModuleProperty> getModuleProperties(ApplicationModule module) {
Assert.notNull(module, "Module must not be null!");
@@ -94,7 +93,7 @@ class ConfigurationProperties implements Iterable<ConfigurationProperty> {
return properties.iterator();
}
private Stream<ModuleProperty> getModuleProperty(Module module,
private Stream<ModuleProperty> getModuleProperty(ApplicationModule module,
ConfigurationProperty property) {
return module.getType(property.getSourceType())

View File

@@ -23,7 +23,6 @@ import com.tngtech.archunit.core.domain.JavaMethod;
* Interface to abstract different ways of looking up documentation for code abstractions.
*
* @author Oliver Drotbohm
* @since 1.1
*/
interface DocumentationSource {

View File

@@ -43,10 +43,10 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.lang.Nullable;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Module.DependencyDepth;
import org.springframework.modulith.model.Module.DependencyType;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModule.DependencyDepth;
import org.springframework.modulith.model.ApplicationModule.DependencyType;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.model.SpringBean;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
@@ -72,7 +72,7 @@ import com.structurizr.view.View;
import com.tngtech.archunit.core.domain.JavaClass;
/**
* API to create documentation for {@link Modules}.
* API to create documentation for {@link ApplicationModules}.
*
* @author Oliver Drotbohm
*/
@@ -88,33 +88,33 @@ public class Documenter {
DEPENDENCY_DESCRIPTIONS.put(DependencyType.DEFAULT, "depends on");
}
private final @Getter Modules modules;
private final @Getter ApplicationModules modules;
private final Workspace workspace;
private final Container container;
private final ConfigurationProperties properties;
private final String outputFolder;
private Map<Module, Component> components;
private Map<ApplicationModule, Component> components;
/**
* Creates a new {@link Documenter} for the {@link Modules} created for the given modulith type.
* Creates a new {@link Documenter} for the {@link ApplicationModules} created for the given modulith type.
*
* @param modulithType must not be {@literal null}.
*/
public Documenter(Class<?> modulithType) {
this(Modules.of(modulithType));
this(ApplicationModules.of(modulithType));
}
/**
* Creates a new {@link Documenter} for the given {@link Modules} instance.
* Creates a new {@link Documenter} for the given {@link ApplicationModules} instance.
*
* @param modules must not be {@literal null}.
*/
public Documenter(Modules modules) {
public Documenter(ApplicationModules modules) {
this(modules, getDefaultOutputDirectory());
}
private Documenter(Modules modules, String outputFolder) {
private Documenter(ApplicationModules modules, String outputFolder) {
Assert.notNull(modules, "Modules must not be null!");
Assert.hasText(outputFolder, "Output folder must not be null or empty!");
@@ -137,7 +137,7 @@ public class Documenter {
this.properties = new ConfigurationProperties();
}
private Map<Module, Component> getComponents(Options options) {
private Map<ApplicationModule, Component> getComponents(Options options) {
if (components == null) {
@@ -174,7 +174,6 @@ public class Documenter {
* @param canvasOptions must not be {@literal null}, use {@link CanvasOptions#defaults()} for default.
* @return the current instance, will never be {@literal null}.
* @throws IOException
* @since 1.1
*/
public Documenter writeDocumentation(Options options, CanvasOptions canvasOptions) throws IOException {
@@ -184,7 +183,7 @@ public class Documenter {
}
/**
* Writes the PlantUML component diagram for all {@link Modules}.
* Writes the PlantUML component diagram for all {@link ApplicationModules}.
*
* @param options must not be {@literal null}.
* @throws IOException
@@ -207,7 +206,6 @@ public class Documenter {
*
* @param options must not be {@literal null}.
* @return the current instance, will never be {@literal null}.
* @since 1.1
*/
public Documenter writeIndividualModulesAsPlantUml(Options options) {
@@ -217,12 +215,12 @@ public class Documenter {
}
/**
* Writes the PlantUML component diagram for the given {@link Module}.
* Writes the PlantUML component diagram for the given {@link ApplicationModule}.
*
* @param module must not be {@literal null}.
* @return the current instance, will never be {@literal null}.
*/
public Documenter writeModuleAsPlantUml(Module module) {
public Documenter writeModuleAsPlantUml(ApplicationModule module) {
Assert.notNull(module, "Module must not be null!");
@@ -230,13 +228,13 @@ public class Documenter {
}
/**
* Writes the PlantUML component diagram for the given {@link Module} with the given rendering {@link Options}.
* Writes the PlantUML component diagram for the given {@link ApplicationModule} with the given rendering {@link Options}.
*
* @param module must not be {@literal null}.
* @param options must not be {@literal null}.
* @return the current instance, will never be {@literal null}.
*/
public Documenter writeModuleAsPlantUml(Module module, Options options) {
public Documenter writeModuleAsPlantUml(ApplicationModule module, Options options) {
Assert.notNull(module, "Module must not be null!");
Assert.notNull(options, "Options must not be null!");
@@ -281,24 +279,15 @@ public class Documenter {
return this;
}
/**
* @param javadocBase
* @deprecated since 1.1, use {@link #writeModuleCanvases(CanvasOptions)} instead.
*/
@Deprecated
public Documenter writeModuleCanvases(String javadocBase) {
return writeModuleCanvases(CanvasOptions.defaults().withApiBase(javadocBase));
}
public String toModuleCanvas(Module module) {
public String toModuleCanvas(ApplicationModule module) {
return toModuleCanvas(module, CanvasOptions.defaults());
}
public String toModuleCanvas(Module module, String apiBase) {
public String toModuleCanvas(ApplicationModule module, String apiBase) {
return toModuleCanvas(module, CanvasOptions.defaults().withApiBase(apiBase));
}
public String toModuleCanvas(Module module, CanvasOptions options) {
public String toModuleCanvas(ApplicationModule module, CanvasOptions options) {
Asciidoctor asciidoctor = Asciidoctor.withJavadocBase(modules, options.getApiBase());
Function<List<JavaClass>, String> mapper = asciidoctor::typesToBulletPoints;
@@ -325,7 +314,7 @@ public class Documenter {
return createPlantUml(Options.defaults());
}
private void addDependencies(Module module, Component component, Options options) {
private void addDependencies(ApplicationModule module, Component component, Options options) {
DEPENDENCY_DESCRIPTIONS.entrySet().stream().forEach(entry -> {
@@ -346,23 +335,23 @@ public class Documenter {
});
}
private void addComponentsToView(Module module, ComponentView view, Options options) {
private void addComponentsToView(ApplicationModule module, ComponentView view, Options options) {
Supplier<Stream<Module>> bootstrapDependencies = () -> module.getBootstrapDependencies(modules,
Supplier<Stream<ApplicationModule>> bootstrapDependencies = () -> module.getBootstrapDependencies(modules,
options.getDependencyDepth());
Supplier<Stream<Module>> otherDependencies = () -> options.getDependencyTypes()
Supplier<Stream<ApplicationModule>> otherDependencies = () -> options.getDependencyTypes()
.flatMap(it -> module.getDependencies(modules, it).stream());
Supplier<Stream<Module>> dependencies = () -> Stream.concat(bootstrapDependencies.get(), otherDependencies.get());
Supplier<Stream<ApplicationModule>> dependencies = () -> Stream.concat(bootstrapDependencies.get(), otherDependencies.get());
addComponentsToView(dependencies, view, options, it -> it.add(getComponents(options).get(module)));
}
private void addComponentsToView(Supplier<Stream<Module>> modules, ComponentView view, Options options,
private void addComponentsToView(Supplier<Stream<ApplicationModule>> modules, ComponentView view, Options options,
Consumer<ComponentView> afterCleanup) {
Styles styles = view.getViewSet().getConfiguration().getStyles();
Map<Module, Component> components = getComponents(options);
Map<ApplicationModule, Component> components = getComponents(options);
modules.get() //
.distinct()
@@ -417,11 +406,11 @@ public class Documenter {
.findFirst().ifPresent(view::remove);
}
private static Component applyBackgroundColor(Module module, Map<Module, Component> components, Options options,
private static Component applyBackgroundColor(ApplicationModule module, Map<ApplicationModule, Component> components, Options options,
Styles styles) {
Component component = components.get(module);
Function<Module, Optional<String>> selector = options.getColorSelector();
Function<ApplicationModule, Optional<String>> selector = options.getColorSelector();
// Apply custom color if configured
selector.apply(module).ifPresent(color -> {
@@ -491,7 +480,7 @@ public class Documenter {
return createComponentView(options, null);
}
private ComponentView createComponentView(Options options, @Nullable Module module) {
private ComponentView createComponentView(Options options, @Nullable ApplicationModule module) {
String prefix = module == null ? "modules-" : module.getName();
@@ -554,7 +543,7 @@ public class Documenter {
/**
* A {@link Predicate} to define the which modules to exclude from the diagram to be created.
*/
private final @With Predicate<Module> exclusions;
private final @With Predicate<ApplicationModule> exclusions;
/**
* A {@link Predicate} to define which Structurizr {@link Component}s to be included in the diagram to be created.
@@ -566,7 +555,7 @@ public class Documenter {
* relationships are going to be hidden from the rendered view. Modules that have no incoming relationships will
* entirely be removed from the view.
*/
private final @With Predicate<Module> targetOnly;
private final @With Predicate<ApplicationModule> targetOnly;
/**
* The target file name to be used for the diagram to be created. For individual module diagrams this needs to
@@ -575,15 +564,15 @@ public class Documenter {
private final @With @Nullable String targetFileName;
/**
* A callback to return a hex-encoded color per {@link Module}.
* A callback to return a hex-encoded color per {@link ApplicationModule}.
*/
private final @With Function<Module, Optional<String>> colorSelector;
private final @With Function<ApplicationModule, Optional<String>> colorSelector;
/**
* A callback to return a default display names for a given {@link Module}. Default implementation just forwards to
* {@link Module#getDisplayName()}.
* A callback to return a default display names for a given {@link ApplicationModule}. Default implementation just forwards to
* {@link ApplicationModule#getDisplayName()}.
*/
private final @With Function<Module, String> defaultDisplayName;
private final @With Function<ApplicationModule, String> defaultDisplayName;
/**
* Which style to render the diagram in. Defaults to {@value DiagramStyle#UML}.
@@ -602,7 +591,7 @@ public class Documenter {
/**
* Creates a new default {@link Options} instance configured to use all dependency types, list immediate
* dependencies for individual module instances, not applying any kind of {@link Module} or {@link Component}
* dependencies for individual module instances, not applying any kind of {@link ApplicationModule} or {@link Component}
* filters and default file names.
*
* @return will never be {@literal null}.
@@ -711,7 +700,7 @@ public class Documenter {
return groupingBy(Grouping.of(name, null, filter));
}
Groupings groupBeans(Module module) {
Groupings groupBeans(ApplicationModule module) {
List<Grouping> sources = new ArrayList<>(groupers);
sources.add(FALLBACK_GROUP);
@@ -741,7 +730,7 @@ public class Documenter {
return Optional.ofNullable(targetFileName);
}
private static List<SpringBean> getMatchingBeans(Module module, Grouping filter, List<SpringBean> alreadyMapped) {
private static List<SpringBean> getMatchingBeans(ApplicationModule module, Grouping filter, List<SpringBean> alreadyMapped) {
return module.getSpringBeans().stream()
.filter(it -> !alreadyMapped.contains(it))

View File

@@ -26,7 +26,6 @@ import com.tngtech.archunit.core.domain.JavaMethod;
* A {@link DocumentationSource} that uses metadata generated by Spring Auto REST Docs' Javadoc Doclet.
*
* @author Oliver Drotbohm
* @since 1.1
*/
class SpringAutoRestDocsDocumentationSource implements DocumentationSource {

View File

@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.importer.ClassFileImporter;
@@ -29,7 +29,7 @@ import com.tngtech.archunit.core.importer.ClassFileImporter;
*/
class AsciidoctorUnitTests {
Asciidoctor asciidoctor = Asciidoctor.withJavadocBase(Modules.of("org.springframework.modulith"), "{javadoc}");
Asciidoctor asciidoctor = Asciidoctor.withJavadocBase(ApplicationModules.of("org.springframework.modulith"), "{javadoc}");
@Test
void formatsInlineCode() {

View File

@@ -27,8 +27,8 @@ import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.docs.Documenter.Options;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Module.DependencyType;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModule.DependencyType;
import com.acme.myproject.Application;
@@ -49,7 +49,7 @@ class DocumenterTest {
@Test
void writesSingleModuleDocumentation() throws IOException {
Module module = documenter.getModules().getModuleByName("moduleB") //
ApplicationModule module = documenter.getModules().getModuleByName("moduleB") //
.orElseThrow(() -> new IllegalArgumentException());
documenter.writeModuleAsPlantUml(module, Options.defaults() //

View File

@@ -143,7 +143,6 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
* implement {@link TransactionalEventListenerMetadata}.
*
* @author Oliver Drotbohm
* @since 1.1
* @see TransactionalEventListener
* @see TransactionalEventListenerMetadata
*/

View File

@@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.*;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.model.SpringBean;
import com.acme.myproject.Application;
@@ -34,7 +34,7 @@ import com.tngtech.archunit.core.domain.JavaClass;
*/
class DocumenterUnitTests {
Modules modules = Modules.of(Application.class);
ApplicationModules modules = ApplicationModules.of(Application.class);
@Test
void groupsSpringBeansByArchitecturallyEvidentType() {

View File

@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.model.Module.DependencyType;
import org.springframework.modulith.model.ApplicationModule.DependencyType;
import com.acme.myproject.Application;
import com.acme.myproject.complex.internal.FirstTypeBasedPort;
@@ -35,7 +35,7 @@ import com.acme.myproject.moduleA.SomeConfigurationA.SomeAtBeanComponentA;
*/
class ModulesIntegrationTest {
Modules modules = Modules.of(Application.class);
ApplicationModules modules = ApplicationModules.of(Application.class);
@Test
void moduleDetectionUsesStrategyDefinedInSpringFactories() {
@@ -45,7 +45,7 @@ class ModulesIntegrationTest {
@Test
void exposesModulesForPrimaryPackages() {
Optional<Module> module = modules.getModuleByName("moduleB");
Optional<ApplicationModule> module = modules.getModuleByName("moduleB");
assertThat(module).hasValueSatisfying(it -> {
assertThat(it.getBootstrapDependencies(modules)).anySatisfy(dep -> {
@@ -57,7 +57,7 @@ class ModulesIntegrationTest {
@Test
public void usesExplicitlyAnnotatedDisplayName() {
Optional<Module> module = modules.getModuleByName("moduleC");
Optional<ApplicationModule> module = modules.getModuleByName("moduleC");
assertThat(module).hasValueSatisfying(it -> {
assertThat(it.getDisplayName()).isEqualTo("MyModule C");
@@ -67,7 +67,7 @@ class ModulesIntegrationTest {
@Test
public void rejectsDependencyIntoInternalPackage() {
Optional<Module> module = modules.getModuleByName("invalid");
Optional<ApplicationModule> module = modules.getModuleByName("invalid");
assertThat(module).hasValueSatisfying(it -> {
assertThatExceptionOfType(Violations.class) //
@@ -78,7 +78,7 @@ class ModulesIntegrationTest {
@Test
public void complexModuleExposesNamedInterfaces() {
Optional<Module> module = modules.getModuleByName("complex");
Optional<ApplicationModule> module = modules.getModuleByName("complex");
assertThat(module).hasValueSatisfying(it -> {
@@ -105,7 +105,7 @@ class ModulesIntegrationTest {
@Test
public void discoversAtBeanComponent() {
Optional<Module> module = modules.getModuleByName("moduleA");
Optional<ApplicationModule> module = modules.getModuleByName("moduleA");
assertThat(module).hasValueSatisfying(it -> {
assertThat(it.getSpringBeansInternal().contains(SomeAtBeanComponentA.class.getName())).isTrue();
@@ -115,8 +115,8 @@ class ModulesIntegrationTest {
@Test
public void moduleBListensToModuleA() {
Optional<Module> module = modules.getModuleByName("moduleB");
Module moduleA = modules.getModuleByName("moduleA").orElseThrow(IllegalStateException::new);
Optional<ApplicationModule> module = modules.getModuleByName("moduleB");
ApplicationModule moduleA = modules.getModuleByName("moduleA").orElseThrow(IllegalStateException::new);
assertThat(module).hasValueSatisfying(it -> {
assertThat(it.getDependencies(modules, DependencyType.EVENT_LISTENER)) //
@@ -127,7 +127,7 @@ class ModulesIntegrationTest {
@Test
public void rejectsNotExplicitlyListedDependency() {
Optional<Module> moduleByName = modules.getModuleByName("invalid2");
Optional<ApplicationModule> moduleByName = modules.getModuleByName("invalid2");
assertThat(moduleByName).hasValueSatisfying(it -> {
@@ -147,9 +147,9 @@ class ModulesIntegrationTest {
@Test
void createsModulesFromJavaPackage() {
Modules fromPackage = Modules.of(Application.class.getPackage().getName());
ApplicationModules fromPackage = ApplicationModules.of(Application.class.getPackage().getName());
assertThat(fromPackage.stream().map(Module::getName)) //
.containsExactlyInAnyOrderElementsOf(modules.stream().map(Module::getName).collect(Collectors.toList()));
assertThat(fromPackage.stream().map(ApplicationModule::getName)) //
.containsExactlyInAnyOrderElementsOf(modules.stream().map(ApplicationModule::getName).collect(Collectors.toList()));
}
}

View File

@@ -20,9 +20,9 @@ import java.util.stream.Stream;
/**
* @author Oliver Drotbohm
*/
class TestModuleDetectionStrategy implements ModuleDetectionStrategy {
class TestModuleDetectionStrategy implements ApplicationModuleDetectionStrategy {
private final ModuleDetectionStrategy delegate = ModuleDetectionStrategy.directSubPackage();
private final ApplicationModuleDetectionStrategy delegate = ApplicationModuleDetectionStrategy.directSubPackage();
static boolean used;

View File

@@ -1,2 +1,2 @@
org.springframework.modulith.model.ModuleDetectionStrategy=\
org.springframework.modulith.model.ApplicationModuleDetectionStrategy=\
org.springframework.modulith.model.TestModuleDetectionStrategy

View File

@@ -25,7 +25,6 @@ import org.jmolecules.event.types.DomainEvent;
* A {@link DomainEvent} published on each day.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@Value(staticConstructor = "of")
public class DayHasPassed implements DomainEvent {

View File

@@ -25,7 +25,6 @@ import org.jmolecules.event.types.DomainEvent;
* A {@link DomainEvent} published on each day.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@Value(staticConstructor = "of")
public class HourHasPassed implements DomainEvent {

View File

@@ -28,7 +28,6 @@ import java.time.MonthDay;
* A logical {@link Quarter} of the year.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public enum Quarter {

View File

@@ -28,7 +28,6 @@ import org.jmolecules.event.types.DomainEvent;
* A {@link DomainEvent} published once a quarter has passed.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@Value(staticConstructor = "of")
public class QuarterHasPassed implements DomainEvent {

View File

@@ -32,7 +32,6 @@ import org.springframework.util.Assert;
* A quarter that can be shifted to start at a configurable {@link Month}.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@Value(staticConstructor = "of")
public class ShiftedQuarter {

View File

@@ -33,7 +33,6 @@ import org.jmolecules.event.types.DomainEvent;
* {@link Locale} provided.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@Value(staticConstructor = "of")
public class WeekHasPassed implements DomainEvent {

View File

@@ -27,7 +27,6 @@ import org.jmolecules.event.types.DomainEvent;
* A {@link DomainEvent} published on the last day of the year.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@Value(staticConstructor = "of")
public class YearHasPassed implements DomainEvent {

View File

@@ -32,7 +32,6 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* Auto-configuration for {@link Moments}.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@EnableScheduling
@EnableConfigurationProperties(MomentsProperties.class)

View File

@@ -41,7 +41,6 @@ import org.springframework.util.Assert;
* Configuration properties for {@link Moments}.
*
* @author Oliver Drotbohm
* @since 1.3
*/
@ConfigurationProperties(prefix = "moduliths.moments")
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)

View File

@@ -27,7 +27,6 @@ import org.springframework.context.ApplicationEventPublisher;
* @author Oliver Drotbohm
* @see #now()
* @see #shiftBy(Duration)
* @since 1.3
*/
public class TimeMachine extends Moments {

View File

@@ -24,8 +24,8 @@ import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.framework.Advised;
import org.springframework.modulith.model.FormatableJavaClass;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.model.SpringBean;
import com.tngtech.archunit.core.domain.JavaClass;
@@ -33,7 +33,7 @@ import com.tngtech.archunit.core.domain.JavaClass;
@RequiredArgsConstructor
class DefaultObservedModule implements ObservedModule {
private final Module module;
private final ApplicationModule module;
/*
* (non-Javadoc)
@@ -106,7 +106,7 @@ class DefaultObservedModule implements ObservedModule {
* @see org.springframework.modulith.observability.ObservedModule#isObservedModule(org.springframework.modulith.model.Module)
*/
@Override
public boolean isObservedModule(Module module) {
public boolean isObservedModule(ApplicationModule module) {
return this.module.equals(module);
}
@@ -114,7 +114,7 @@ class DefaultObservedModule implements ObservedModule {
* (non-Javadoc)
* @see org.springframework.modulith.observability.ObservedModule#getInterceptionConfiguration(java.lang.Class, org.springframework.modulith.model.Modules)
*/
public ObservedModuleType getObservedModuleType(Class<?> type, Modules modules) {
public ObservedModuleType getObservedModuleType(Class<?> type, ApplicationModules modules) {
return module.getSpringBeans().stream()
.filter(it -> it.getFullyQualifiedTypeName().equals(type.getName()))
@@ -125,11 +125,11 @@ class DefaultObservedModule implements ObservedModule {
.orElse(null);
}
private static String toString(Method method, Module module) {
private static String toString(Method method, ApplicationModule module) {
return toString(method.getDeclaringClass(), method, module);
}
private static String toString(Class<?> type, Method method, Module module) {
private static String toString(Class<?> type, Method method, ApplicationModule module) {
String typeName = module.getType(type.getName())
.map(FormatableJavaClass::of)

View File

@@ -24,7 +24,7 @@ import java.util.function.Supplier;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.ApplicationModule;
/**
* @author Oliver Drotbohm
@@ -54,7 +54,7 @@ public class ModuleEventListener implements ApplicationListener<ApplicationEvent
return;
}
Module moduleByType = modules.get()
ApplicationModule moduleByType = modules.get()
.getModuleByType(payloadType.getSimpleName())
.orElse(null);

View File

@@ -31,7 +31,7 @@ import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
/**
* @author Oliver Drotbohm
@@ -65,7 +65,7 @@ public class ModuleTracingBeanPostProcessor extends ModuleTracingSupport impleme
return bean;
}
Modules modules = getModules();
ApplicationModules modules = getModules();
return modules.getModuleByType(type.getName())
.map(DefaultObservedModule::new)

View File

@@ -22,7 +22,7 @@ import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.util.Assert;
/**
@@ -30,7 +30,7 @@ import org.springframework.util.Assert;
*/
class ModuleTracingSupport implements BeanClassLoaderAware {
private final Supplier<Modules> modules;
private final Supplier<ApplicationModules> modules;
private final ApplicationRuntime context;
private ClassLoader classLoader;
@@ -51,7 +51,7 @@ class ModuleTracingSupport implements BeanClassLoaderAware {
this.classLoader = classLoader;
}
protected final Modules getModules() {
protected final ApplicationModules getModules() {
try {
return modules.get();

View File

@@ -23,20 +23,20 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Supplier;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
/**
* Bootstrap type to make sure we only bootstrap the initialization of a {@link Modules} instance per application class
* Bootstrap type to make sure we only bootstrap the initialization of a {@link ApplicationModules} instance per application class
* once.
*
* @author Oliver Drotbohm
*/
@RequiredArgsConstructor
public class ModulesRuntime implements Supplier<Modules> {
public class ModulesRuntime implements Supplier<ApplicationModules> {
private static final Map<String, ModulesRuntime> MODULES = new HashMap<>();
private final Supplier<Modules> modules;
private final Supplier<ApplicationModules> modules;
private final ApplicationRuntime runtime;
/*
@@ -44,7 +44,7 @@ public class ModulesRuntime implements Supplier<Modules> {
* @see java.util.function.Supplier#get()
*/
@Override
public Modules get() {
public ApplicationModules get() {
return modules.get();
}
@@ -57,13 +57,13 @@ public class ModulesRuntime implements Supplier<Modules> {
return MODULES.computeIfAbsent(runtime.getId(), it -> {
Class<?> mainClass = runtime.getMainApplicationClass();
Future<Modules> modules = Executors.newFixedThreadPool(1).submit(() -> Modules.of(mainClass));
Future<ApplicationModules> modules = Executors.newFixedThreadPool(1).submit(() -> ApplicationModules.of(mainClass));
return new ModulesRuntime(toSupplier(modules), runtime);
});
}
private static Supplier<Modules> toSupplier(Future<Modules> modules) {
private static Supplier<ApplicationModules> toSupplier(Future<ApplicationModules> modules) {
return () -> {
try {

View File

@@ -18,8 +18,8 @@ package org.springframework.modulith.observability;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
import com.tngtech.archunit.core.domain.JavaClass;
@@ -48,14 +48,14 @@ interface ObservedModule {
*/
boolean exposes(JavaClass type);
boolean isObservedModule(Module module);
boolean isObservedModule(ApplicationModule module);
/**
* Returns the {@link ObservedModuleType} for the given type and {@link Modules}.
* Returns the {@link ObservedModuleType} for the given type and {@link ApplicationModules}.
*
* @param type
* @param modules
* @return
*/
ObservedModuleType getObservedModuleType(Class<?> type, Modules modules);
ObservedModuleType getObservedModuleType(Class<?> type, ApplicationModules modules);
}

View File

@@ -23,7 +23,7 @@ import java.util.stream.Stream;
import org.springframework.modulith.model.ArchitecturallyEvidentType;
import org.springframework.modulith.model.ArchitecturallyEvidentType.ReferenceMethod;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
/**
* Represents a type in an {@link ObservedModule}.
@@ -33,7 +33,7 @@ import org.springframework.modulith.model.Modules;
@RequiredArgsConstructor
public class ObservedModuleType {
private final Modules modules;
private final ApplicationModules modules;
private final ObservedModule module;
private final ArchitecturallyEvidentType type;

View File

@@ -28,8 +28,8 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.data.rest.webmvc.RootResourceInformation;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
/**
* @author Oliver Drotbohm
@@ -69,7 +69,7 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
@RequiredArgsConstructor
private static class DataRestControllerInterceptor implements MethodInterceptor {
private final Modules modules;
private final ApplicationModules modules;
private final Tracer tracer;
/*
@@ -79,7 +79,7 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Module module = getModuleFrom(invocation.getArguments());
ApplicationModule module = getModuleFrom(invocation.getArguments());
if (module == null) {
return invocation.proceed();
@@ -90,7 +90,7 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
return ModuleEntryInterceptor.of(observed, tracer).invoke(invocation);
}
private Module getModuleFrom(Object[] arguments) {
private ApplicationModule getModuleFrom(Object[] arguments) {
for (Object argument : arguments) {

View File

@@ -1,4 +1,4 @@
@Module(allowedDependencies = "moduleB")
@ApplicationModule(allowedDependencies = "moduleB")
package com.acme.myproject.invalid2;
import org.springframework.modulith.Module;
import org.springframework.modulith.ApplicationModule;

View File

@@ -1,4 +1,4 @@
@Module(displayName = "MyModule C")
@ApplicationModule(displayName = "MyModule C")
package com.acme.myproject.moduleC;
import org.springframework.modulith.Module;
import org.springframework.modulith.ApplicationModule;

View File

@@ -18,8 +18,8 @@ package com.acme.myproject;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.Modules.Filters;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.model.ApplicationModules.Filters;
import org.springframework.modulith.model.Violations;
import com.acme.myproject.invalid.InvalidComponent;
@@ -44,7 +44,7 @@ class ModulithTest {
String componentName = InternalComponentB.class.getSimpleName();
assertThatExceptionOfType(Violations.class) //
.isThrownBy(() -> Modules.of(Application.class, DEFAULT_EXCLUSIONS).verify()) //
.isThrownBy(() -> ApplicationModules.of(Application.class, DEFAULT_EXCLUSIONS).verify()) //
.withMessageContaining(String.format("Module '%s' depends on non-exposed type %s within module 'moduleB'",
"invalid", InternalComponentB.class.getName()))
.withMessageContaining(String.format("%s declares constructor %s(%s)", InvalidComponent.class.getSimpleName(),
@@ -53,14 +53,14 @@ class ModulithTest {
@Test
void verifyModulesWithoutInvalid() {
Modules.of(Application.class, DEFAULT_EXCLUSIONS.or(Filters.withoutModule("invalid"))).verify();
ApplicationModules.of(Application.class, DEFAULT_EXCLUSIONS.or(Filters.withoutModule("invalid"))).verify();
}
@Test
void detectsCycleBetweenModules() {
assertThatExceptionOfType(Violations.class) //
.isThrownBy(() -> Modules.of(Application.class, Filters.withoutModules("invalid", "invalid2")).verify()) //
.isThrownBy(() -> ApplicationModules.of(Application.class, Filters.withoutModules("invalid", "invalid2")).verify()) //
// mentions modules
.withMessageContaining("cycleA") //

View File

@@ -21,17 +21,17 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.modulith.test.ModuleTest;
import org.springframework.modulith.test.ModuleTest.BootstrapMode;
import org.springframework.modulith.test.ApplicationModuleTest;
import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode;
/**
* @author Oliver Drotbohm
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ModuleTest(verifyAutomatically = false)
@ApplicationModuleTest(verifyAutomatically = false)
public @interface NonVerifyingModuleTest {
@AliasFor(annotation = ModuleTest.class, attribute = "mode")
@AliasFor(annotation = ApplicationModuleTest.class, attribute = "mode")
BootstrapMode value() default BootstrapMode.STANDALONE;
}

View File

@@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.test.ModuleTestExecution;
import com.acme.myproject.NonVerifyingModuleTest;
@@ -41,7 +41,7 @@ class FieldInjectedIntegrationTest {
@Test
void rejectsFieldInjection() {
Modules modules = execution.getModules();
ApplicationModules modules = execution.getModules();
assertThat(execution.getModule().detectDependencies(modules)) //
.hasMessageContaining("field injection") //

View File

@@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.modulith.test.ModuleTest.BootstrapMode;
import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode;
import org.springframework.modulith.test.TestUtils;
import com.acme.myproject.NonVerifyingModuleTest;

View File

@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.modulith.test.ModuleTest.BootstrapMode;
import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode;
import org.springframework.modulith.test.TestUtils;
import com.acme.myproject.NonVerifyingModuleTest;

View File

@@ -28,14 +28,14 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.core.annotation.AliasFor;
import org.springframework.modulith.model.Module.DependencyDepth;
import org.springframework.modulith.model.ApplicationModule.DependencyDepth;
import org.springframework.test.context.BootstrapWith;
import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.TestConstructor.AutowireMode;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Bootstraps the module containing the package of the test class annotated with {@link ModuleTest}. Will apply the
* Bootstraps the module containing the package of the test class annotated with {@link ApplicationModuleTest}. Will apply the
* following modifications to the Spring Boot configuration:
* <ul>
* <li>Restricts the component scanning to the module's package.
@@ -54,7 +54,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(PublishedEventsParameterResolver.class)
@TestInstance(Lifecycle.PER_CLASS)
@TestConstructor(autowireMode = AutowireMode.ALL)
public @interface ModuleTest {
public @interface ApplicationModuleTest {
@AliasFor("mode")
BootstrapMode value() default BootstrapMode.STANDALONE;

View File

@@ -28,8 +28,8 @@ import java.util.stream.Stream;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
@@ -48,7 +48,7 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) {
ModuleTest moduleTest = AnnotatedElementUtils.getMergedAnnotation(testClass, ModuleTest.class);
ApplicationModuleTest moduleTest = AnnotatedElementUtils.getMergedAnnotation(testClass, ApplicationModuleTest.class);
return moduleTest == null ? null : new ModuleContextCustomizer(testClass);
}
@@ -86,8 +86,8 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
private static void logModules(ModuleTestExecution execution) {
Module module = execution.getModule();
Modules modules = execution.getModules();
ApplicationModule module = execution.getModule();
ApplicationModules modules = execution.getModules();
String moduleName = module.getDisplayName();
String bootstrapMode = execution.getBootstrapMode().name();
@@ -99,7 +99,7 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
Arrays.stream(module.toString(modules).split("\n")).forEach(LOG::info);
List<Module> extraIncludes = execution.getExtraIncludes();
List<ApplicationModule> extraIncludes = execution.getExtraIncludes();
if (!extraIncludes.isEmpty()) {
@@ -108,7 +108,7 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
extraIncludes.forEach(it -> LOG.info("> ".concat(it.getName())));
}
Set<Module> sharedModules = modules.getSharedModules();
Set<ApplicationModule> sharedModules = modules.getSharedModules();
if (!sharedModules.isEmpty()) {
@@ -117,13 +117,13 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
sharedModules.forEach(it -> LOG.info("> ".concat(it.getName())));
}
List<Module> dependencies = execution.getDependencies();
List<ApplicationModule> dependencies = execution.getDependencies();
if (!dependencies.isEmpty() || !sharedModules.isEmpty()) {
logHeadline("Included dependencies:", message);
Stream<Module> dependenciesPlusMissingSharedOnes = //
Stream<ApplicationModule> dependenciesPlusMissingSharedOnes = //
Stream.concat(dependencies.stream(), sharedModules.stream() //
.filter(it -> !dependencies.contains(it)));

View File

@@ -34,9 +34,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.AnnotatedClassFinder;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.modulith.model.JavaPackage;
import org.springframework.modulith.model.Module;
import org.springframework.modulith.model.Modules;
import org.springframework.modulith.test.ModuleTest.BootstrapMode;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode;
import com.tngtech.archunit.thirdparty.com.google.common.base.Supplier;
import com.tngtech.archunit.thirdparty.com.google.common.base.Suppliers;
@@ -46,7 +46,7 @@ import com.tngtech.archunit.thirdparty.com.google.common.base.Suppliers;
*/
@Slf4j
@EqualsAndHashCode(of = "key")
public class ModuleTestExecution implements Iterable<Module> {
public class ModuleTestExecution implements Iterable<ApplicationModule> {
private static Map<Class<?>, Class<?>> MODULITH_TYPES = new HashMap<>();
private static Map<Key, ModuleTestExecution> EXECUTIONS = new HashMap<>();
@@ -54,14 +54,14 @@ public class ModuleTestExecution implements Iterable<Module> {
private final Key key;
private final @Getter BootstrapMode bootstrapMode;
private final @Getter Module module;
private final @Getter Modules modules;
private final @Getter List<Module> extraIncludes;
private final @Getter ApplicationModule module;
private final @Getter ApplicationModules modules;
private final @Getter List<ApplicationModule> extraIncludes;
private final Supplier<List<JavaPackage>> basePackages;
private final Supplier<List<Module>> dependencies;
private final Supplier<List<ApplicationModule>> dependencies;
private ModuleTestExecution(ModuleTest annotation, Modules modules, Module module) {
private ModuleTestExecution(ApplicationModuleTest annotation, ApplicationModules modules, ApplicationModule module) {
this.key = Key.of(module.getBasePackage().getName(), annotation);
this.modules = modules;
@@ -74,7 +74,7 @@ public class ModuleTestExecution implements Iterable<Module> {
Stream<JavaPackage> moduleBasePackages = module.getBasePackages(modules, bootstrapMode.getDepth());
Stream<JavaPackage> sharedBasePackages = modules.getSharedModules().stream().map(it -> it.getBasePackage());
Stream<JavaPackage> extraPackages = extraIncludes.stream().map(Module::getBasePackage);
Stream<JavaPackage> extraPackages = extraIncludes.stream().map(ApplicationModule::getBasePackage);
Stream<JavaPackage> intermediate = Stream.concat(moduleBasePackages, extraPackages);
@@ -83,7 +83,7 @@ public class ModuleTestExecution implements Iterable<Module> {
this.dependencies = Suppliers.memoize(() -> {
Stream<Module> bootstrapDependencies = module.getBootstrapDependencies(modules, bootstrapMode.getDepth());
Stream<ApplicationModule> bootstrapDependencies = module.getBootstrapDependencies(modules, bootstrapMode.getDepth());
return Stream.concat(bootstrapDependencies, extraIncludes.stream()).collect(Collectors.toList());
});
@@ -96,13 +96,13 @@ public class ModuleTestExecution implements Iterable<Module> {
return () -> {
ModuleTest annotation = AnnotatedElementUtils.findMergedAnnotation(type, ModuleTest.class);
ApplicationModuleTest annotation = AnnotatedElementUtils.findMergedAnnotation(type, ApplicationModuleTest.class);
String packageName = type.getPackage().getName();
Class<?> modulithType = MODULITH_TYPES.computeIfAbsent(type,
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromPackage(packageName));
Modules modules = Modules.of(modulithType);
Module module = modules.getModuleForPackage(packageName) //
ApplicationModules modules = ApplicationModules.of(modulithType);
ApplicationModule module = modules.getModuleForPackage(packageName) //
.orElseThrow(
() -> new IllegalStateException(String.format("Package %s is not part of any module!", packageName)));
@@ -133,11 +133,11 @@ public class ModuleTestExecution implements Iterable<Module> {
}
/**
* Returns all module dependencies, based on the current {@link ModuleTest.BootstrapMode}.
* Returns all module dependencies, based on the current {@link ApplicationModuleTest.BootstrapMode}.
*
* @return
*/
public List<Module> getDependencies() {
public List<ApplicationModule> getDependencies() {
return dependencies.get();
}
@@ -160,11 +160,11 @@ public class ModuleTestExecution implements Iterable<Module> {
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator<Module> iterator() {
public Iterator<ApplicationModule> iterator() {
return modules.iterator();
}
private static Stream<Module> getExtraModules(ModuleTest annotation, Modules modules) {
private static Stream<ApplicationModule> getExtraModules(ApplicationModuleTest annotation, ApplicationModules modules) {
return Arrays.stream(annotation.extraIncludes()) //
.map(modules::getModuleByName) //
@@ -176,6 +176,6 @@ public class ModuleTestExecution implements Iterable<Module> {
private static class Key {
String moduleBasePackage;
ModuleTest annotation;
ApplicationModuleTest annotation;
}
}

View File

@@ -18,7 +18,7 @@ package org.springframework.modulith.test;
import org.junit.jupiter.api.extension.Extension;
/**
* JUnit 5 {@link Extension} for standalone usage without {@link ModuleTest}.
* JUnit 5 {@link Extension} for standalone usage without {@link ApplicationModuleTest}.
*
* @author Oliver Drotbohm
*/