Skip to content

Commit 21bd2ce

Browse files
committed
GH-587 - ModulithMetadata now exposes all base packages.
Previously, we had a variety of places calculating the overall packages to inspect for types. This is now all consolidated into the ModulithMetadata abstraction exposing them directly.
1 parent 04c1203 commit 21bd2ce

File tree

7 files changed

+146
-180
lines changed

7 files changed

+146
-180
lines changed

spring-modulith-core/src/main/java/org/springframework/modulith/core/AnnotationModulithMetadata.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.modulith.core;
1717

18+
import java.util.ArrayList;
1819
import java.util.Arrays;
1920
import java.util.List;
2021
import java.util.Optional;
@@ -34,6 +35,7 @@ class AnnotationModulithMetadata implements ModulithMetadata {
3435

3536
private final Class<?> modulithType;
3637
private final Modulithic annotation;
38+
private final String basePackage;
3739

3840
/**
3941
* Creates a new {@link AnnotationModulithMetadata} for the given type and annotation.
@@ -48,6 +50,7 @@ private AnnotationModulithMetadata(Class<?> modulithType, Modulithic annotation)
4850

4951
this.modulithType = modulithType;
5052
this.annotation = annotation;
53+
this.basePackage = modulithType.getPackageName();
5154
}
5255

5356
/**
@@ -123,4 +126,17 @@ public Optional<String> getSystemName() {
123126
.filter(StringUtils::hasText) //
124127
.or(() -> Optional.of(modulithType.getSimpleName()));
125128
}
129+
130+
/*
131+
* (non-Javadoc)
132+
* @see org.springframework.modulith.core.ModulithMetadata#getBasePackages()
133+
*/
134+
@Override
135+
public List<String> getBasePackages() {
136+
137+
var result = new ArrayList<>(List.of(basePackage));
138+
result.addAll(List.of(annotation.additionalPackages()));
139+
140+
return result;
141+
}
126142
}

spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModules.java

Lines changed: 85 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,40 @@ private static DescribedPredicate<CanBeAnnotated> getAtGenerated() {
107107

108108
private boolean verified;
109109

110+
/**
111+
* Creates a new {@link ApplicationModules} instance.
112+
*
113+
* @param metadata must not be {@literal null}.
114+
* @param ignored must not be {@literal null}.
115+
* @param useFullyQualifiedModuleNames can be {@literal null}.
116+
* @param option must not be {@literal null}.
117+
*/
118+
protected ApplicationModules(ModulithMetadata metadata,
119+
DescribedPredicate<JavaClass> ignored, boolean useFullyQualifiedModuleNames, ImportOption option) {
120+
this(metadata, metadata.getBasePackages(), ignored, useFullyQualifiedModuleNames, option);
121+
}
122+
123+
/**
124+
* Creates a new {@link ApplicationModules} instance.
125+
*
126+
* @param metadata must not be {@literal null}.
127+
* @param packages must not be {@literal null}.
128+
* @param ignored must not be {@literal null}.
129+
* @param useFullyQualifiedModuleNames can be {@literal null}.
130+
* @param option must not be {@literal null}.
131+
* @deprecated since 1.2, for removal in 1.3. Use {@link ApplicationModules(ModulithMetadata, DescribedPredicate,
132+
* boolean, ImportOption)} instead and set up {@link ModulithMetadata} to contain the packages you want to
133+
* use.
134+
*/
135+
@Deprecated(forRemoval = true)
110136
protected ApplicationModules(ModulithMetadata metadata, Collection<String> packages,
111137
DescribedPredicate<JavaClass> ignored, boolean useFullyQualifiedModuleNames, ImportOption option) {
112138

139+
Assert.notNull(metadata, "ModulithMetadata must not be null!");
140+
Assert.notNull(packages, "Base packages must not be null!");
141+
Assert.notNull(ignored, "Ignores must not be null!");
142+
Assert.notNull(option, "ImportOptions must not be null!");
143+
113144
this.metadata = metadata;
114145
this.allClasses = new ClassFileImporter() //
115146
.withImportOption(option) //
@@ -190,26 +221,33 @@ public static ApplicationModules of(Class<?> modulithType) {
190221
}
191222

192223
/**
193-
* Creates a new {@link ApplicationModules} relative to the given modulith type, a
194-
* {@link ApplicationModuleDetectionStrategy} and a {@link DescribedPredicate} which types and packages to ignore.
195-
* Will inspect the {@link org.springframework.modulith.Modulith} and {@link org.springframework.modulith.Modulithic}
196-
* annotations on the class given for advanced customizations of the module setup.
224+
* Creates a new {@link ApplicationModules} relative to the given modulith type, and a {@link DescribedPredicate}
225+
* which types and packages to ignore. Will inspect the {@link org.springframework.modulith.Modulith} and
226+
* {@link org.springframework.modulith.Modulithic} annotations on the class given for advanced customizations of the
227+
* module setup.
197228
*
198229
* @param modulithType must not be {@literal null}.
199230
* @param ignored must not be {@literal null}.
200231
* @return will never be {@literal null}.
201232
*/
202233
public static ApplicationModules of(Class<?> modulithType, DescribedPredicate<JavaClass> ignored) {
203234

204-
CacheKey key = new TypeKey(modulithType, ignored);
235+
Assert.notNull(modulithType, "Modulith root type must not be null!");
236+
Assert.notNull(ignored, "Predicate to describe ignored types must not be null!");
205237

206-
return CACHE.computeIfAbsent(key, it -> {
207-
208-
Assert.notNull(modulithType, "Modulith root type must not be null!");
209-
Assert.notNull(ignored, "Predicate to describe ignored types must not be null!");
238+
return of(CacheKey.of(modulithType, ignored, IMPORT_OPTION));
239+
}
210240

211-
return of(key);
212-
});
241+
/**
242+
* Creates a new {@link ApplicationModules} instance for the given type and {@link ImportOption}.
243+
*
244+
* @param modulithType must not be {@literal null}.
245+
* @param options must not be {@literal null}.
246+
* @return will never be {@literal null}.
247+
* @since 1.2
248+
*/
249+
public static ApplicationModules of(Class<?> modulithType, ImportOption options) {
250+
return of(CacheKey.of(modulithType, alwaysFalse(), options));
213251
}
214252

215253
/**
@@ -231,15 +269,22 @@ public static ApplicationModules of(String javaPackage) {
231269
*/
232270
public static ApplicationModules of(String javaPackage, DescribedPredicate<JavaClass> ignored) {
233271

234-
CacheKey key = new PackageKey(javaPackage, ignored);
235-
236-
return CACHE.computeIfAbsent(key, it -> {
272+
Assert.hasText(javaPackage, "Base package must not be null or empty!");
273+
Assert.notNull(ignored, "Predicate to describe ignored types must not be null!");
237274

238-
Assert.hasText(javaPackage, "Base package must not be null or empty!");
239-
Assert.notNull(ignored, "Predicate to describe ignored types must not be null!");
275+
return of(CacheKey.of(javaPackage, ignored, IMPORT_OPTION));
276+
}
240277

241-
return of(key);
242-
});
278+
/**
279+
* Creates a new {@link ApplicationModules} instance for the given package and {@link ImportOption}.
280+
*
281+
* @param javaPackage must not be {@literal null}.
282+
* @param options must not be {@literal null}.
283+
* @return will never be {@literal null}.
284+
* @since 1.2
285+
*/
286+
public static ApplicationModules of(String javaPackage, ImportOption options) {
287+
return of(CacheKey.of(javaPackage, alwaysFalse(), options));
243288
}
244289

245290
/**
@@ -571,13 +616,8 @@ private static ApplicationModules of(CacheKey key) {
571616
Assert.notNull(key, "Cache key must not be null!");
572617

573618
var metadata = key.getMetadata();
574-
575-
var basePackages = new HashSet<String>();
576-
basePackages.add(key.getBasePackage());
577-
basePackages.addAll(metadata.getAdditionalPackages());
578-
579-
var modules = new ApplicationModules(metadata, basePackages, key.getIgnored(),
580-
metadata.useFullyQualifiedModuleNames(), IMPORT_OPTION);
619+
var modules = new ApplicationModules(metadata, key.getIgnored(),
620+
metadata.useFullyQualifiedModuleNames(), key.getOptions());
581621

582622
var sharedModules = metadata.getSharedModuleNames() //
583623
.map(modules::getRequiredModule) //
@@ -623,130 +663,37 @@ public static DescribedPredicate<JavaClass> withoutModule(String name) {
623663
}
624664
}
625665

626-
private static interface CacheKey {
666+
private static class CacheKey {
627667

628-
String getBasePackage();
629-
630-
DescribedPredicate<JavaClass> getIgnored();
631-
632-
ModulithMetadata getMetadata();
633-
}
634-
635-
private static final class TypeKey implements CacheKey {
636-
637-
private final Class<?> type;
638668
private final DescribedPredicate<JavaClass> ignored;
669+
private final ImportOption options;
670+
private final Supplier<ModulithMetadata> metadata;
639671

640-
/**
641-
* Creates a new {@link TypeKey} for the given type and {@link DescribedPredicate} of ignored {@link JavaClass}es.
642-
*
643-
* @param type must not be {@literal null}.
644-
* @param ignored must not be {@literal null}.
645-
*/
646-
TypeKey(Class<?> type, DescribedPredicate<JavaClass> ignored) {
672+
public CacheKey(DescribedPredicate<JavaClass> ignored, ImportOption options, Supplier<ModulithMetadata> metadata) {
647673

648-
this.type = type;
649674
this.ignored = ignored;
675+
this.options = options;
676+
this.metadata = SingletonSupplier.of(metadata);
650677
}
651678

652-
/*
653-
* (non-Javadoc)
654-
* @see org.springframework.modulith.model.Modules.CacheKey#getBasePackage()
655-
*/
656-
@Override
657-
public String getBasePackage() {
658-
return type.getPackage().getName();
679+
static CacheKey of(String pkg, DescribedPredicate<JavaClass> ignored, ImportOption options) {
680+
return new CacheKey(ignored, options, () -> ModulithMetadata.of(pkg));
659681
}
660682

661-
/*
662-
* (non-Javadoc)
663-
* @see org.springframework.modulith.model.Modules.CacheKey#getMetadata()
664-
*/
665-
@Override
666-
public ModulithMetadata getMetadata() {
667-
return ModulithMetadata.of(type);
683+
static CacheKey of(Class<?> type, DescribedPredicate<JavaClass> ignored, ImportOption options) {
684+
return new CacheKey(ignored, options, () -> ModulithMetadata.of(type));
668685
}
669686

670-
/*
671-
* (non-Javadoc)
672-
* @see org.springframework.modulith.model.ApplicationModules.CacheKey#getIgnored()
673-
*/
674-
@Override
675-
public DescribedPredicate<JavaClass> getIgnored() {
687+
DescribedPredicate<JavaClass> getIgnored() {
676688
return ignored;
677689
}
678690

679-
/*
680-
* (non-Javadoc)
681-
* @see java.lang.Object#equals(java.lang.Object)
682-
*/
683-
@Override
684-
public boolean equals(Object obj) {
685-
686-
if (this == obj) {
687-
return true;
688-
}
689-
690-
if (!(obj instanceof TypeKey other)) {
691-
return false;
692-
}
693-
694-
return Objects.equals(this.type, other.type) //
695-
&& Objects.equals(this.ignored, other.ignored);
696-
}
697-
698-
/*
699-
* (non-Javadoc)
700-
* @see java.lang.Object#hashCode()
701-
*/
702-
@Override
703-
public int hashCode() {
704-
return Objects.hash(type, ignored);
705-
}
706-
}
707-
708-
private static final class PackageKey implements CacheKey {
709-
710-
private final String basePackage;
711-
private final DescribedPredicate<JavaClass> ignored;
712-
713-
/**
714-
* Creates a new {@link PackageKey} for the given base package and {@link DescribedPredicate} of ignored
715-
* {@link JavaClass}es.
716-
*
717-
* @param basePackage must not be {@literal null}.
718-
* @param ignored must not be {@literal null}.
719-
*/
720-
PackageKey(String basePackage, DescribedPredicate<JavaClass> ignored) {
721-
722-
this.basePackage = basePackage;
723-
this.ignored = ignored;
691+
ModulithMetadata getMetadata() {
692+
return metadata.get();
724693
}
725694

726-
/*
727-
* (non-Javadoc)
728-
* @see org.springframework.modulith.model.ApplicationModules.CacheKey#getBasePackage()
729-
*/
730-
@Override
731-
public String getBasePackage() {
732-
return basePackage;
733-
}
734-
735-
/*
736-
* (non-Javadoc)
737-
* @see org.springframework.modulith.model.ApplicationModules.CacheKey#getIgnored()
738-
*/
739-
public DescribedPredicate<JavaClass> getIgnored() {
740-
return ignored;
741-
}
742-
743-
/*
744-
* (non-Javadoc)
745-
* @see org.springframework.modulith.model.Modules.CacheKey#getMetadata()
746-
*/
747-
@Override
748-
public ModulithMetadata getMetadata() {
749-
return ModulithMetadata.of(basePackage);
695+
ImportOption getOptions() {
696+
return options;
750697
}
751698

752699
/*
@@ -756,25 +703,17 @@ public ModulithMetadata getMetadata() {
756703
@Override
757704
public boolean equals(Object obj) {
758705

759-
if (this == obj) {
706+
if (obj == this) {
760707
return true;
761708
}
762709

763-
if (!(obj instanceof PackageKey that)) {
710+
if (!(obj instanceof CacheKey that)) {
764711
return false;
765712
}
766713

767-
return Objects.equals(this.basePackage, that.basePackage) //
768-
&& Objects.equals(this.ignored, that.ignored);
769-
}
770-
771-
/*
772-
* (non-Javadoc)
773-
* @see java.lang.Object#hashCode()
774-
*/
775-
@Override
776-
public int hashCode() {
777-
return Objects.hash(basePackage, ignored);
714+
return Objects.equals(this.ignored, that.ignored)
715+
&& Objects.equals(this.options, that.options)
716+
&& Objects.equals(this.metadata.get(), that.metadata.get());
778717
}
779718
}
780719

spring-modulith-core/src/main/java/org/springframework/modulith/core/ModulithMetadata.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
import org.springframework.modulith.core.Types.SpringTypes;
2626
import org.springframework.util.Assert;
2727

28+
/**
29+
* Core metadata about the modulithic application.
30+
*
31+
* @author Oliver Drotbohm
32+
*/
2833
public interface ModulithMetadata {
2934

3035
static final String ANNOTATION_MISSING = "Modules can only be retrieved from a root type, but %s is not annotated with either @%s, @%s or @%s!";
@@ -81,7 +86,9 @@ public static ModulithMetadata of(String javaPackage) {
8186
* consider all direct sub-packages modules by default.
8287
*
8388
* @return will never be {@literal null}.
89+
* @deprecated since 1.2, rather use {@link #getBasePackages()} that includes all packages already.
8490
*/
91+
@Deprecated
8592
List<String> getAdditionalPackages();
8693

8794
/**
@@ -105,4 +112,12 @@ public static ModulithMetadata of(String javaPackage) {
105112
* @return will never be {@literal null}.
106113
*/
107114
Optional<String> getSystemName();
115+
116+
/**
117+
* Returns all base packages of the modulith.
118+
*
119+
* @return will never be {@literal null}.
120+
* @since 1.2
121+
*/
122+
List<String> getBasePackages();
108123
}

0 commit comments

Comments
 (0)