GH-9 - Rename core, public abstractions from Module to ApplicationModule.
Remove obsolete @since tags and deprecations.
This commit is contained in:
@@ -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 "";
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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!",
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.tngtech.archunit.core.domain.JavaMethod;
|
||||
* references
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @since 1.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
class CodeReplacingDocumentationSource implements DocumentationSource {
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() //
|
||||
|
||||
@@ -143,7 +143,6 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
|
||||
* implement {@link TransactionalEventListenerMetadata}.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @since 1.1
|
||||
* @see TransactionalEventListener
|
||||
* @see TransactionalEventListenerMetadata
|
||||
*/
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
org.springframework.modulith.model.ModuleDetectionStrategy=\
|
||||
org.springframework.modulith.model.ApplicationModuleDetectionStrategy=\
|
||||
org.springframework.modulith.model.TestModuleDetectionStrategy
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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") //
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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") //
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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)));
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user