From cb6d71ba60113f7fc761220d0942e46f4045b787 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Sun, 15 Oct 2023 17:29:27 +0200 Subject: [PATCH] GH-319 - Fix ApplicationModule by package name lookup. Prior to this commit, the lookup for an ApplicationModule would find modules solely depending on the reference string starting with the base package. That means that a module with base package com.acme.foo, a request for com.acme.foobar would've resulted in a positive match, which of course is wrong. We now match against either the module's base package or against the reference starting with the base package followed by a dot. --- .../modulith/core/ApplicationModule.java | 18 ++++++++++++++++++ .../modulith/core/ApplicationModules.java | 8 +++++++- .../modulith/core/ModuleUnitTest.java | 11 +++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModule.java b/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModule.java index df544d3c..0f0f7d5b 100644 --- a/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModule.java +++ b/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModule.java @@ -414,6 +414,24 @@ public class ApplicationModule { return getType(candidate).isPresent(); } + /** + * Returns whether the {@link ApplicationModule} contains the package with the given name, which means the given + * package is either the module's base package or a sub package of it. + * + * @param packageName must not be {@literal null} or empty. + * @return whether the {@link ApplicationModule} contains the package with the given name. + * @since 1.0.2 + */ + boolean containsPackage(String packageName) { + + Assert.hasText(packageName, "Package name must not be null or empty!"); + + var basePackageName = basePackage.getName(); + + return packageName.equals(basePackageName) + || packageName.startsWith(basePackageName + "."); + } + /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) diff --git a/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModules.java b/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModules.java index 6fe2e8b6..3310d107 100644 --- a/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModules.java +++ b/spring-modulith-core/src/main/java/org/springframework/modulith/core/ApplicationModules.java @@ -326,10 +326,16 @@ public class ApplicationModules implements Iterable { return getModuleByType(candidate.getName()); } + /** + * Returns the {@link ApplicationModule} containing the given package. + * + * @param name must not be {@literal null} or empty. + * @return will never be {@literal null}. + */ public Optional getModuleForPackage(String name) { return modules.values().stream() // - .filter(it -> name.startsWith(it.getBasePackage().getName())) // + .filter(it -> it.containsPackage(name)) // .findFirst(); } diff --git a/spring-modulith-core/src/test/java/org/springframework/modulith/core/ModuleUnitTest.java b/spring-modulith-core/src/test/java/org/springframework/modulith/core/ModuleUnitTest.java index f1ec17a1..40c6fc76 100644 --- a/spring-modulith-core/src/test/java/org/springframework/modulith/core/ModuleUnitTest.java +++ b/spring-modulith-core/src/test/java/org/springframework/modulith/core/ModuleUnitTest.java @@ -16,11 +16,13 @@ package org.springframework.modulith.core; import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; import java.util.List; import javax.sql.DataSource; +import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; @@ -83,4 +85,13 @@ class ModuleUnitTest { .> extracting(JavaClass::reflect) .containsExactly(SampleAggregate.class); } + + @Test // GH-319 + void containsPackage() { + + assertThat(module.containsPackage(packageName)).isTrue(); + assertThat(module.containsPackage(packageName + ".foo")).isTrue(); + + assertThat(module.containsPackage(packageName + "foo")).isFalse(); + } }