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 720fa58c..e43227a6 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 @@ -72,7 +72,7 @@ public class ApplicationModule { private final boolean useFullyQualifiedModuleNames; private final Supplier springBeans; - private final Supplier entities; + private final Supplier aggregateRoots; private final Supplier> valueTypes; private final Supplier> publishedEvents; @@ -90,7 +90,7 @@ public class ApplicationModule { this.useFullyQualifiedModuleNames = useFullyQualifiedModuleNames; this.springBeans = Suppliers.memoize(() -> filterSpringBeans(basePackage)); - this.entities = Suppliers.memoize(() -> findEntities(basePackage)); + this.aggregateRoots = Suppliers.memoize(() -> findAggregateRoots(basePackage)); this.valueTypes = Suppliers .memoize(() -> findArchitecturallyEvidentType(ArchitecturallyEvidentType::isValueObject)); this.publishedEvents = Suppliers.memoize(() -> findPublishedEvents()); @@ -195,10 +195,7 @@ public class ApplicationModule { */ public List getAggregateRoots() { - return entities.get().stream() // - .map(it -> ArchitecturallyEvidentType.of(it, getSpringBeansInternal())) // - .filter(ArchitecturallyEvidentType::isAggregateRoot) // - .map(ArchitecturallyEvidentType::getType) // + return aggregateRoots.get().stream() // .flatMap(this::resolveModuleSuperTypes) // .distinct() // .toList(); @@ -433,7 +430,7 @@ public class ApplicationModule { } return Objects.equals(this.basePackage, that.basePackage) // - && Objects.equals(this.entities, that.entities) // + && Objects.equals(this.aggregateRoots, that.aggregateRoots) // && Objects.equals(this.information, that.information) // && Objects.equals(this.namedInterfaces, that.namedInterfaces) // && Objects.equals(this.publishedEvents, that.publishedEvents) // @@ -448,7 +445,7 @@ public class ApplicationModule { */ @Override public int hashCode() { - return Objects.hash(basePackage, entities, information, namedInterfaces, publishedEvents, springBeans, + return Objects.hash(basePackage, aggregateRoots, information, namedInterfaces, publishedEvents, springBeans, useFullyQualifiedModuleNames, valueTypes); } @@ -532,12 +529,13 @@ public class ApplicationModule { return modules.contains(dependency) && !contains(dependency); } - private Classes findEntities(JavaPackage source) { + private Classes findAggregateRoots(JavaPackage source) { return source.stream() // .map(it -> ArchitecturallyEvidentType.of(it, getSpringBeansInternal())) - .filter(ArchitecturallyEvidentType::isEntity) // - .map(ArchitecturallyEvidentType::getType).collect(Classes.toClasses()); + .filter(ArchitecturallyEvidentType::isAggregateRoot) // + .map(ArchitecturallyEvidentType::getType) // + .collect(Classes.toClasses()); } private static Classes filterSpringBeans(JavaPackage source) { diff --git a/spring-modulith-core/src/test/java/com/acme/withatbean/SampleAggregate.java b/spring-modulith-core/src/test/java/com/acme/withatbean/SampleAggregate.java new file mode 100644 index 00000000..cee1a693 --- /dev/null +++ b/spring-modulith-core/src/test/java/com/acme/withatbean/SampleAggregate.java @@ -0,0 +1,34 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.acme.withatbean; + +import org.jmolecules.ddd.types.AggregateRoot; +import org.jmolecules.ddd.types.Identifier; + +import com.acme.withatbean.SampleAggregate.SampleIdentifier; + +/** + * @author Oliver Drotbohm + */ +public class SampleAggregate implements AggregateRoot { + + @Override + public SampleIdentifier getId() { + return null; + } + + record SampleIdentifier() implements Identifier {} +} 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 154e8c64..f1ec17a1 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 @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; +import com.acme.withatbean.SampleAggregate; import com.acme.withatbean.TestEvents.JMoleculesAnnotated; import com.acme.withatbean.TestEvents.JMoleculesImplementing; import com.tngtech.archunit.core.domain.JavaClass; @@ -74,4 +75,12 @@ class ModuleUnitTest { void usesCapitalizedNameAsDisplayNameByDefault() { assertThat(module.getDisplayName()).isEqualTo("Withatbean"); } + + @Test // GH-157 + void detectsAggregates() { + + assertThat(module.getAggregateRoots()) + .> extracting(JavaClass::reflect) + .containsExactly(SampleAggregate.class); + } }