Note
|
This project has been archived and is no longer actively developed. It has been superseded by the jqassistant-jmolecules-plugin |
The jMolecules Plugin provides concepts to map architectural language elements from the jMolecules project (https://github.com/xmolecules/jmolecules) to the graph representation build by jQAssistant in order to gain new insights, create additional concepts and constraints.
Please check the documentation of the jMolecules project to see how architectural concepts can be marked in the source code.
Afterwards, to have jQAssistant consider the annotations and to allow the execution of constraints, following dependency
in the jqassistant-maven-plugin
needs to be defined:
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<version>${jqassistant.version}</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>scan</goal>
<goal>analyze</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency> // (1)
<groupId>org.jqassistant.contrib.plugin</groupId>
<artifactId>jqassistant-jmolecules-plugin</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
</plugin>
-
Definition of the plugin dependency
jMolecules comes with a set of different sub-projects, each providing annotations and marker interfaces for different architectural aspects.
The jqassistant-jmolecules-plugin
provides concepts to map the annotations and interfaces to the graph. For each sub-project, there is a jQAssistant rule group containing all relevant concepts and additional constraints. Following is the mapping between jMolecules and jQAssistant.
jMolecules | jQAssistant |
---|---|
jmolecules-cqrs-architecute |
jmolecules-cqrs:Default |
jmolecules-layered-architecture |
jmolecules-layered:Default |
jmolecules-layered:Strict |
|
jmolecules-onion-architecture (Classical) |
jmolecules-onion-classical:Default |
jmolecules-onion-classical:Strict |
|
jmolecules-onion-architecture (Simplified) |
jmolecules-onion-simplified:Default |
jmolecules-onion-simplified:Strict |
|
jmolecules-ddd |
jmolecules-ddd:Default |
jmolecules-ddd:Strict |
|
jmolecules-event |
jmolecules-event:Default |
In order to make use of the provided concepts, the respective groups need to be added to the plugin configuration as following:
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<version>${jqassistant.version}</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>scan</goal>
<goal>analyze</goal>
</goals>
<configuration>
<groups> // (1)
<group>jmolecules-cqrs:Default</group>
<group>jmolecules-layered:Default</group>
<group>jmolecules-layered:Strict</group>
<group>jmolecules-onion-classical:Default</group>
<group>jmolecules-onion-classical:Strict</group>
<group>jmolecules-onion-simplified:Default</group>
<group>jmolecules-onion-simplified:Strict</group>
<group>jmolecules-ddd:Default</group>
<group>jmolecules-ddd:Strict</group>
<group>jmolecules-event:Default</group>
</groups>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jqassistant.contrib.plugin</groupId>
<artifactId>jqassistant-jmolecules-plugin</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
</plugin>
-
Definition of the rules to be used
-
The concepts mentioned in this section are used for
jmolecules-architecture-layered
-
The concepts mentioned in this section are part of
jmolecules-layered:Default
orjmolecules-layered:Strict
-
jmolecules-layered:Strict
containsjmolecules-layered:Default
-
For each technical layer, a node will be created, to which all types will be associated via a
:CONTAINS
relationship -
Dependencies between types will be aggregated to the level of technical layers using a
:DEPENDS_ON
relation -
When using the strict-group, allowed dependencies between the layers will be added to the graph using a
:DEFINES_DEPENDENCY
relation
Supported Annotations and Types:
-
InterfaceLayer
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Layered:Layer(name: 'Interface')
-
-
ApplicationLayer
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Layered:Layer(name: 'Application')
-
-
DomainLayer
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Layered:Layer(name: 'Domain')
-
-
InfrastructureLayer
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Layered:Layer(name: 'Infrastructure')
-
Additionally, the dependencies between types will be aggregated to the level of Layers including a weight, giving how many dependencies between layers exist.
Constraint:
-
jmolecules-layered:TypeInMultipleLayers
-
Checks that each type is part of only one layer
-
-
jmolecules-layered:IllegalLayerDependency (strict-group)
-
Checks that dependencies between layers only exist where allowed
-
-
The concepts mentioned in this section are used for
jmolecules-architecture-onion
-
The concepts mentioned in this section are part of
jmolecules-onion-classical:Default
orjmolecules-onion-classical:Strict
-
jmolecules-onion-classical:Strict
containsjmolecules-onion-classical:Default
-
For each ring, a node will be created, to which all types will be associated via a
:CONTAINS
relationship -
Dependencies between types will be aggregated to the level of technical rings using a
:DEPENDS_ON
relation -
When using the strict-group, allowed dependencies between the rings will be added to the graph using a
:DEFINES_DEPENDENCY
relation
Supported Annotations and Types:
-
ApplicationServiceRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'ApplicationService')
-
-
DomainServiceRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'DomainService')
-
-
DomainModelRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'DomainModel')
-
-
InfrastructureRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'Infrastructure')
-
Additionally, the dependencies between types will be aggregated to the level of Rings including a weight, giving how many dependencies between rings exist.
Constraint:
-
jmolecules-onion-classical:TypeInMultipleRings
-
Checks that each type is part of only one ring
-
-
jmolecules-onion-classical:IllegalRingDependency (strict-group)
-
Checks that dependencies between rings only exist where allowed
-
-
The concepts mentioned in this section are used for
jmolecules-architecture-onion
-
The concepts mentioned in this section are part of
jmolecules-onion-simplified:Default
-
For each ring, a node will be created, to which all types will be associated via a
:CONTAINS
relationship -
Dependencies between types will be aggregated to the level of technical rings using a
:DEPENDS_ON
relation -
When using the strict-group, allowed dependencies between the rings will be added to the graph using a
:DEFINES_DEPENDENCY
relation
Supported Annotations and Types:
-
ApplicationRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'Application')
-
-
DomainRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'Domain')
-
-
InfrastructureRing
-
Supported as Package- and Type-Annotation
-
Applied Labels:
:JMolecules:Architecture:Onion:Ring(name: 'Infrastructure')
-
Additionally, the dependencies between types will be aggregated to the level of Rings including a weight, giving how many dependencies between rings exist.
Constraint:
-
jmolecules-onion-simplified:TypeInMultipleRings
-
Checks that each type is part of only one ring
-
-
jmolecules-onion-simplified:IllegalRingDependency (strict-group)
-
Checks that dependencies between rings only exist where allowed
-
-
The concepts mentioned in this section are used for
jmolecules-ddd
-
The concepts mentioned in this section are part of
jmolecules-ddd:Default
orjmolecules-ddd:Strict
Supported Annotations and Types:
-
AggregateRoot
-
Supported as Type-Annotation and Interface
-
Applied Labels:
:JMolecules:DDD:Identifiable:Entity:AggregateRoot
-
-
BoundedContext
-
Supported as Package-Annotation
-
Per BoundedContext (unique by id), a node will be created representing the bounded context. Types will be linked via a
:CONTAINS
relationship. -
Applied Labels:
:JMolecules:DDD:BoundedContext
-
The properties
id
,name
, anddescription
are supported -
In case the id is missing, the package name will be used
-
-
Entity
-
Supported as Type-Annotation and Interface
-
Applied Labels:
:JMolecules:DDD:Identifiable:Entity
-
-
Identifier
-
Supported as Interface
-
Applied Labels: `:JMolecules:DDD:Identifier
-
-
Identity
-
Supported as Field- and Method-Annotation and via
Entity
andAggregateRoot
-Interfaces (via thegetId
method) -
Created relations:
:HAS_IDENTITY
towards a :Field- or :Method-node (:Member) -
The relation will be transferred from super- to implementing types in case they don’t override the
getId
method
-
-
Factory
-
Supported as Type-Annotation
-
Applied Labels:
:JMolecules:DDD:Factory
-
-
Module
-
Supported as Package-Annotation
-
Per Module (unique by id), a node will be created representing the module. Types will be linked via a
:CONTAINS
relationship. -
Applied Labels:
:JMolecules:DDD:Modules
-
The properties
id
,name
, anddescription
are supported -
In case the id is missing, the package name will be used
-
-
Repository
-
Supported as Type-Annotation and Interface
-
Applied Labels:
:JMolecules:DDD:Repository
-
-
Service
-
Supported as Type-Annotation
-
Applied Labels:
:JMolecules:DDD:Service
-
-
ValueObject
-
Supported as Type-Annotation and Interface
-
Applied Labels:
:JMolecules:DDD:ValueObject
-
Additionally, the dependencies between types will be aggregated to the level of BoundedContexts and Modules including a weight, giving how many dependencies between BoundedContext or Modules, respectively, exist.
Constraint:
-
jmolecules-ddd:TypeInMultipleBoundedContexts
-
Checks that each type is part of only one bounded context
-
-
jmolecules-ddd:TypeInMultipleModules
-
Checks that each type is part of only one module
-
-
jmolecules-ddd:MutableValueObject
-
Checks that values in ValueObjects are only manipulated via a constructor in the declaring class
-
-
jmolecules-ddd:MutableEntityId
-
Checks that the
:Field
identified by:HAS_IDENTITY
in:Identifiable
nodes is only manipulated via a constructor in the declaring class
-
-
jmolecules-ddd:ValueObjectReferencingEntityOrAggregateRoot
-
Checks that a
:ValueObject
is not referencing a:Entity
or:AggregateRoot
(:Identifiable
)
-
-
jmolecules-ddd:NonFinalFieldInValueObject (strict-group)
-
Checks that values in ValueObjects final
-
-
jmolecules-ddd:NonFinalEntityId (strict-group)
-
Checks that the
:Field
identified by:HAS_IDENTITY
in:Identifiable
nodes is final
-
-
jmolecules-ddd:IllegalDependenciesBetweenBoundedContexts (strict-group)
-
Checks that
:DEPENDS_ON
relations between:BoundedContext
nodes only exist where also:DEFINES_DEPENDENCY
exists -
Note: Allowed dependencies need to be provided using a custom concept which specifies the provided concept:
jmolecules-ddd:AllowedBoundedContextDependency
-
Note: This can also be accomplished by using the jqassistant-context-mapper-plugin
-
-
The concepts mentioned in this section are used for
jmolecules-cqrs
-
The concepts mentioned in this section are part of
jmolecules-cqrs:Default
-
QueryModel
-
Supported as Type-Annotation
-
Applied Labels:
:JMolecules:CQRS:QueryModel
-
-
Command
-
Supported as Type-Annotation
-
Applied Labels:
:JMolecules:CQRS:Command
-
The properties
name
andnamespace
are supported, they’ll be added to the type node ascommandName
andcommandNamespace
, respectively-
Default values for
commandName
: Simple Type Name of the annotated class -
Default values for
commandNamespace
: Fully-qualified name of the package containing the annotated class
-
-
-
CommandHandler
-
Supported as Method-Annotation
-
Applied Labels:
JMolecules:CQRS:CommandHandler
-
The properties
name
andnamespace
are supported to match the handled commands, '*' is allowed as a placeholder to match all -
The relationship
(:CommandHandler)-[:HANDLES]→(:Command)
is established via the specified properties, or, alternatively, via the method parameter-
See the official jMolecules JavaDoc for further details
-
-
-
CommandDispatcher
-
Supported as Method-Annotation
-
Applied Labels:
:JMolecules:CQRS:CommandDispatcher
-
The property
dispatches
is supported to match the published command via '<namespace>.<name>'-
See the official jMolecules JavaDoc for further details
-
-
-
The concepts mentioned in this section are used for
jmolecules-event
-
The concepts mentioned in this section are part of
jmolecules-event:Default
-
DomainEvent
-
Supported as Type-Annotation and Interface
-
Applied Labels:
:JMolecules:Event:DomainEvent
-
The properties
name
andnamespace
are supported, they’ll be added to the type node aseventName
andeventNamespace
, respectively-
Default values for
eventName
: Simple Type Name of the annotated class -
Default values for
eventNamespace
: Fully-qualified name of the package containing the annotated class
-
-
-
DomainEventHandler
-
Supported as Method-Annotation
-
Applied Labels:
JMolecules:Event:DomainEventHandler
-
The properties
name
andnamespace
are supported to match the handled events, '*' is allowed as a placeholder to match all -
The relationship
(:DomainEventHandler)-[:HANDLES]→(:DomainEvent)
is established via the specified properties, or, alternatively, via the method parameter-
See the official jMolecules JavaDoc for further details
-
-
-
DomainEventPublisher
-
Supported as Method-Annotation
-
Applied Labels:
:JMolecules:Event:DomainEventPublisher
-
The property
publishes
is supported to match the published event via '<namespace>.<name>'-
See the official jMolecules JavaDoc for further details
-
-
The property
type
is supported and will be enriched on the:PUBLISHES
relationship
-
The jMolecules plug-in supports visualization of concepts using PlantUML in jQAssistant reports for the following concepts:
-
Bounded Context
-
Module
-
Ring (both for classical and simplified Onion Architecture)
-
Layer (Interface, Application, Domain, Infrastructure)
To use this functionality, define the jQAssistant concept with the following property set:
-
reportType="plantuml-component-diagram"
The jMolecules plug-in works well with the jqassistant-context-mapper-plugin
to visualize Bounded Contexts identified via jMolecules as a context map.
For further details, see the project page.