3232import java .util .Optional ;
3333import java .util .Set ;
3434import java .util .function .Predicate ;
35- import java .util .stream .Collectors ;
3635import java .util .stream .Stream ;
3736
3837import org .springframework .data .repository .core .RepositoryMetadata ;
@@ -81,7 +80,7 @@ public static ArchitecturallyEvidentType of(JavaClass type, Classes beanTypes) {
8180 delegates .add (new SpringDataAwareArchitecturallyEvidentType (type , beanTypes ));
8281 }
8382
84- delegates .add (new SpringAwareArchitecturallyEvidentType (type ));
83+ delegates .add (new SpringAwareArchitecturallyEvidentType (type , beanTypes ));
8584
8685 return DelegatingType .of (type , delegates );
8786 });
@@ -135,6 +134,14 @@ public boolean isConfigurationProperties() {
135134 return false ;
136135 }
137136
137+ public boolean isInjectable () {
138+ return isService () || isController () || isEventListener () || isConfigurationProperties ();
139+ }
140+
141+ public boolean isValueObject () {
142+ return false ;
143+ }
144+
138145 /**
139146 * Returns other types that are interesting in the context of the current {@link ArchitecturallyEvidentType}. For
140147 * example, for an event listener this might be the event types the particular listener is interested in.
@@ -195,8 +202,13 @@ static class SpringAwareArchitecturallyEvidentType extends ArchitecturallyEviden
195202 private static final Predicate <JavaMethod > IS_EVENT_LISTENER = IS_ANNOTATED_EVENT_LISTENER
196203 .or (IS_IMPLEMENTING_EVENT_LISTENER );
197204
198- public SpringAwareArchitecturallyEvidentType (JavaClass type ) {
205+ private final boolean injectable ;
206+
207+ public SpringAwareArchitecturallyEvidentType (JavaClass type , Classes beanTypes ) {
208+
199209 super (type );
210+
211+ this .injectable = beanTypes .contains (type );
200212 }
201213
202214 /*
@@ -253,6 +265,15 @@ public boolean isConfigurationProperties() {
253265 return Types .isAnnotatedWith (SpringTypes .AT_CONFIGURATION_PROPERTIES ).test (getType ());
254266 }
255267
268+ /*
269+ * (non-Javadoc)
270+ * @see org.springframework.modulith.model.ArchitecturallyEvidentType#isInjectable()
271+ */
272+ @ Override
273+ public boolean isInjectable () {
274+ return injectable || SpringTypes .isComponent ().test (getType ()) || super .isInjectable ();
275+ }
276+
256277 /*
257278 * (non-Javadoc)
258279 * @see org.springframework.modulith.model.ArchitecturallyEvidentType#getOtherTypeReferences()
@@ -411,20 +432,35 @@ public boolean isService() {
411432 public boolean isEventListener () {
412433 return getType ().getMethods ().stream ().anyMatch (IS_ANNOTATED_EVENT_LISTENER );
413434 }
435+
436+ /*
437+ * (non-Javadoc)
438+ * @see org.springframework.modulith.model.ArchitecturallyEvidentType#isValueObject()
439+ */
440+ @ Override
441+ public boolean isValueObject () {
442+
443+ JavaClass type = getType ();
444+
445+ return Types .isAnnotatedWith (org .jmolecules .ddd .annotation .ValueObject .class ).test (type )
446+ || type .isAssignableTo (org .jmolecules .ddd .types .ValueObject .class );
447+ }
414448 }
415449
416450 static class DelegatingType extends ArchitecturallyEvidentType {
417451
418452 private final Supplier <Boolean > isAggregateRoot , isRepository , isEntity , isService , isController ,
419- isEventListener ,
420- isConfigurationProperties ;
453+ isEventListener , isConfigurationProperties , isInjectable , isValueObject ;
454+
421455 private final Supplier <Collection <JavaClass >> referenceTypes ;
422456 private final Supplier <Collection <ReferenceMethod >> referenceMethods ;
423457
424458 DelegatingType (JavaClass type , Supplier <Boolean > isAggregateRoot ,
425459 Supplier <Boolean > isRepository , Supplier <Boolean > isEntity , Supplier <Boolean > isService ,
426460 Supplier <Boolean > isController , Supplier <Boolean > isEventListener ,
427461 Supplier <Boolean > isConfigurationProperties ,
462+ Supplier <Boolean > isInjectable ,
463+ Supplier <Boolean > isValueObject ,
428464 Supplier <Collection <JavaClass >> referenceTypes ,
429465 Supplier <Collection <ReferenceMethod >> referenceMethods ) {
430466
@@ -437,43 +473,49 @@ static class DelegatingType extends ArchitecturallyEvidentType {
437473 this .isController = isController ;
438474 this .isEventListener = isEventListener ;
439475 this .isConfigurationProperties = isConfigurationProperties ;
476+ this .isInjectable = isInjectable ;
477+ this .isValueObject = isValueObject ;
440478 this .referenceTypes = referenceTypes ;
441479 this .referenceMethods = referenceMethods ;
442480 }
443481
444482 public static DelegatingType of (JavaClass type , List <ArchitecturallyEvidentType > types ) {
445483
446- Supplier < Boolean > isAggregateRoot = Suppliers
484+ var isAggregateRoot = Suppliers
447485 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isAggregateRoot ));
448486
449- Supplier < Boolean > isRepository = Suppliers
487+ var isRepository = Suppliers
450488 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isRepository ));
451489
452- Supplier < Boolean > isEntity = Suppliers
490+ var isEntity = Suppliers
453491 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isEntity ));
454492
455- Supplier < Boolean > isService = Suppliers
493+ var isService = Suppliers
456494 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isService ));
457495
458- Supplier < Boolean > isController = Suppliers
496+ var isController = Suppliers
459497 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isController ));
460498
461- Supplier < Boolean > isEventListener = Suppliers
499+ var isEventListener = Suppliers
462500 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isEventListener ));
463501
464- Supplier < Boolean > isConfigurationProperties = Suppliers
502+ var isConfigurationProperties = Suppliers
465503 .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isConfigurationProperties ));
466504
505+ var isInjectable = Suppliers .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isInjectable ));
506+
507+ var isValueObject = Suppliers .memoize (() -> types .stream ().anyMatch (ArchitecturallyEvidentType ::isValueObject ));
508+
467509 Supplier <Collection <JavaClass >> referenceTypes = Suppliers .memoize (() -> types .stream () //
468510 .flatMap (ArchitecturallyEvidentType ::getReferenceTypes ) //
469- .collect ( Collectors . toList () ));
511+ .toList ());
470512
471513 Supplier <Collection <ReferenceMethod >> referenceMethods = Suppliers .memoize (() -> types .stream () //
472514 .flatMap (ArchitecturallyEvidentType ::getReferenceMethods ) //
473- .collect ( Collectors . toList () ));
515+ .toList ());
474516
475517 return new DelegatingType (type , isAggregateRoot , isRepository , isEntity , isService , isController ,
476- isEventListener , isConfigurationProperties , referenceTypes , referenceMethods );
518+ isEventListener , isConfigurationProperties , isInjectable , isValueObject , referenceTypes , referenceMethods );
477519 }
478520
479521 /*
@@ -541,6 +583,24 @@ public boolean isConfigurationProperties() {
541583 return isConfigurationProperties .get ();
542584 }
543585
586+ /*
587+ * (non-Javadoc)
588+ * @see org.springframework.modulith.model.ArchitecturallyEvidentType#isInjectable()
589+ */
590+ @ Override
591+ public boolean isInjectable () {
592+ return isInjectable .get ();
593+ }
594+
595+ /*
596+ * (non-Javadoc)
597+ * @see org.springframework.modulith.model.ArchitecturallyEvidentType#isValueObject()
598+ */
599+ @ Override
600+ public boolean isValueObject () {
601+ return isValueObject .get ();
602+ }
603+
544604 /*
545605 * (non-Javadoc)
546606 * @see org.springframework.modulith.model.ArchitecturallyEvidentType#getOtherTypeReferences()
0 commit comments