Skip to content

Commit 3c1cefd

Browse files
committed
GH-152 - Introduce @stereotype meta-annotation.
We now ship an @stereotype annotation in a jstereotype artifact that allows marking annotations and types as stereotypes. An API working with that metadata will subsequently be introduced in jMolecules Integrations. The jmolecules-ddd and jmolecules-hexagonal-architecture artifact have been fully enriched with both the annotations and the derived JSON metadata. Other artifacts have been annotated with @stereotype but not yet fully described in terms of stereotype hierarchies.
1 parent 77f606c commit 3c1cefd

File tree

85 files changed

+709
-30
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+709
-30
lines changed

Diff for: etc/schemas/jmolecules-catalog.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"$schema": "https://json.schemastore.org/schema-catalog.json",
3+
"version": 1,
4+
"schemas": [
5+
{
6+
"name": "jMolecules Stereotype Groups Schema",
7+
"description": "Schema to define jMolecules stereotype groups",
8+
"fileMatch": [
9+
"jmolecules-groups.json",
10+
"**/jmolecules-groups.json",
11+
],
12+
"url": "https://schemas.jmolecules.org/jmolecules-groups.schema.json"
13+
},
14+
{
15+
"name": "jMolecules Stereotypes Schema",
16+
"description": "Schema to define jMolecules stereotypes",
17+
"fileMatch": [
18+
"jmolecules-stereotypes.json",
19+
"**/jmolecules-stereotypes.json"
20+
],
21+
"url": "https://schemas.jmolecules.org/jmolecules-stereotypes.schema.json"
22+
}
23+
]
24+
}

Diff for: etc/schemas/jmolecules-groups.schema.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://schemas.jmolecules.org/jmolecules-groups.schema.json",
4+
"type": "object",
5+
"description": "Configuration for jMolecules stereotype groups",
6+
"properties": {
7+
"groups": {
8+
"type": "array",
9+
"description": "List of group definitions that stereotypes can belong to",
10+
"items": {
11+
"type": "object",
12+
"required": ["ids", "displayName"],
13+
"properties": {
14+
"ids": {
15+
"type": "array",
16+
"description": "List of identifiers for this group",
17+
"items": {
18+
"type": "string",
19+
"pattern": "^[\\w.-]+$",
20+
"description": "Group identifier using dot notation"
21+
},
22+
"minItems": 1,
23+
"uniqueItems": true
24+
},
25+
"displayName": {
26+
"type": "string",
27+
"minLength": 1,
28+
"description": "Human-readable name for the group"
29+
},
30+
"priority": {
31+
"type": "integer",
32+
"minimum": 0,
33+
"default": 0,
34+
"description": "Processing priority of the group, defaults to 0"
35+
}
36+
},
37+
"additionalProperties": false
38+
},
39+
"minItems": 1
40+
}
41+
},
42+
"required": ["groups"],
43+
"additionalProperties": false
44+
}

Diff for: etc/schemas/jmolecules-stereotypes.schema.json

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://schemas.jmolecules.org/jmolecules-stereotypes.schema.json",
4+
"type": "object",
5+
"description": "Configuration for jMolecules stereotypes",
6+
"properties": {
7+
"stereotypes": {
8+
"type": "array",
9+
"description": "List of stereotype definitions that can be applied to code elements",
10+
"items": {
11+
"type": "object",
12+
"required": ["id", "assignments"],
13+
"properties": {
14+
"id": {
15+
"type": "string",
16+
"pattern": "^[\\w.-]+$",
17+
"description": "Unique identifier for the stereotype using dot notation"
18+
},
19+
"displayName": {
20+
"type": "string",
21+
"minLength": 1,
22+
"description": "Human-readable name for the stereotype (optional)"
23+
},
24+
"assignments": {
25+
"type": "array",
26+
"description": "List of type or annotation assignments that this stereotype can be applied to",
27+
"items": {
28+
"type": "string",
29+
"pattern": "^@?[\\w.-]+$",
30+
"description": "Type or annotation identifier, optionally prefixed with @ for annotations"
31+
},
32+
"minItems": 1,
33+
"uniqueItems": true
34+
},
35+
"groups": {
36+
"type": "array",
37+
"description": "Groups that this stereotype belongs to",
38+
"items": {
39+
"type": "string",
40+
"pattern": "^[\\w.-]+$",
41+
"description": "Group identifier using dot notation"
42+
},
43+
"minItems": 1,
44+
"uniqueItems": true
45+
},
46+
"priority": {
47+
"type": "integer",
48+
"minimum": 0,
49+
"default": 0,
50+
"description": "Processing priority of the stereotype, defaults to 0"
51+
}
52+
},
53+
"additionalProperties": false
54+
},
55+
"minItems": 1
56+
},
57+
"groups": {
58+
"$ref": "https://schemas.jmolecules.org/jmolecules-groups.schema.json#/properties/groups"
59+
}
60+
},
61+
"required": ["stereotypes"],
62+
"additionalProperties": false
63+
}

Diff for: jmolecules-architecture/jmolecules-cqrs-architecture/pom.xml

+8
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@
1414
<name>jMolecules - CQRS Architecture</name>
1515
<description>Concepts of the cqrs architecture style.</description>
1616

17+
<dependencies>
18+
<dependency>
19+
<groupId>org.jmolecules</groupId>
20+
<artifactId>jstereotype</artifactId>
21+
<version>${project.version}</version>
22+
</dependency>
23+
</dependencies>
24+
1725
</project>

Diff for: jmolecules-architecture/jmolecules-cqrs-architecture/src/main/java/module-info.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@
1717

1818
exports org.jmolecules.architecture.cqrs;
1919
exports org.jmolecules.architecture.cqrs.annotation;
20+
21+
requires org.jmolecules.stereotype;
2022
}

Diff for: jmolecules-architecture/jmolecules-cqrs-architecture/src/main/java/org/jmolecules/architecture/cqrs/Command.java

+14-11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* Identifies a command in the context of CQRS, i.e. a request to the system for the change of data. Commands are always
2628
* in imperative tense and thus, unlike an event, do not state that something has already happened, but something is
@@ -38,18 +40,19 @@
3840
@Documented
3941
@Retention(RetentionPolicy.RUNTIME)
4042
@Target(ElementType.TYPE)
43+
@Stereotype
4144
public @interface Command {
4245

43-
/**
44-
* An identifier for the namespace of the command to group multiple commands and let clients express their interest
45-
* in all commands of a specific namespace. If not set, external tooling may default this to the fully-qualified
46-
* package name of the annotated type.
47-
*/
48-
String namespace() default "";
46+
/**
47+
* An identifier for the namespace of the command to group multiple commands and let clients express their interest in
48+
* all commands of a specific namespace. If not set, external tooling may default this to the fully-qualified package
49+
* name of the annotated type.
50+
*/
51+
String namespace() default "";
4952

50-
/**
51-
* An identifier for the name of the command used to abstract away from the type system and to guard against
52-
* refactorings. If not set, external tooling may default this to the simple class name of the annotated type.
53-
*/
54-
String name() default "";
53+
/**
54+
* An identifier for the name of the command used to abstract away from the type system and to guard against
55+
* refactorings. If not set, external tooling may default this to the simple class name of the annotated type.
56+
*/
57+
String name() default "";
5558
}

Diff for: jmolecules-architecture/jmolecules-cqrs-architecture/src/main/java/org/jmolecules/architecture/cqrs/CommandDispatcher.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* Identifies a command dispatcher in the context of CQRS, i.e. logic to dispatch a {@link Command}.
2628
*
@@ -35,6 +37,7 @@
3537
@Documented
3638
@Retention(RetentionPolicy.RUNTIME)
3739
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
40+
@Stereotype
3841
public @interface CommandDispatcher {
3942

4043
/**

Diff for: jmolecules-architecture/jmolecules-cqrs-architecture/src/main/java/org/jmolecules/architecture/cqrs/CommandHandler.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* Identifies a command handler in the context of CQRS, i.e. logic to process a {@link Command}. The command handler may
2628
* or may not reject the command. In case of processing, the handler takes care of orchestrating the business logic
@@ -37,15 +39,16 @@
3739
@Documented
3840
@Retention(RetentionPolicy.RUNTIME)
3941
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR })
42+
@Stereotype
4043
public @interface CommandHandler {
4144

4245
/**
4346
* Optional identification of the namespace of the command handled by this handler. This information may be used for
4447
* easier linkage between command and handler by external tools and refers to {@link Command#namespace()}. When
4548
* leaving the default value, it is assumed that the method signature makes clear what command is consumed. If the
4649
* handler takes care of all commands of a specific namespace, the value of this field needs to be set to the
47-
* respective namespace and the {@link CommandHandler#name()} needs to be set accordingly. If the handler doesn't
48-
* care about the namespace, the value may be set to the '*' (asterisk) placeholder.
50+
* respective namespace and the {@link CommandHandler#name()} needs to be set accordingly. If the handler doesn't care
51+
* about the namespace, the value may be set to the '*' (asterisk) placeholder.
4952
*/
5053
String namespace() default "";
5154

Diff for: jmolecules-architecture/jmolecules-cqrs-architecture/src/main/java/org/jmolecules/architecture/cqrs/QueryModel.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* Identifies a query model element in the context of CQRS, i.e. a (persistent) object optimized for read-access and
2628
* only only on the Q(uery) part of the architecture. The query model represents the current state or rather
@@ -37,4 +39,5 @@
3739
@Documented
3840
@Retention(RetentionPolicy.RUNTIME)
3941
@Target(ElementType.TYPE)
42+
@Stereotype
4043
public @interface QueryModel {}

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/pom.xml

+10
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,14 @@
1414
<name>jMolecules - Hexagonal Architecture</name>
1515
<description>Concepts of the hexagonal architecture style.</description>
1616

17+
<dependencies>
18+
19+
<dependency>
20+
<groupId>org.jmolecules</groupId>
21+
<artifactId>jstereotype</artifactId>
22+
<version>${project.version}</version>
23+
</dependency>
24+
25+
</dependencies>
26+
1727
</project>

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/module-info.java

+2
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@
1616
open module org.jmolecules.architecture.hexagonal {
1717

1818
exports org.jmolecules.architecture.hexagonal;
19+
20+
requires org.jmolecules.stereotype;
1921
}

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/Adapter.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* {@link Adapter}s contain technology specific implementations to either drive (see {@link PrimaryPort}) or implement
2628
* {@link Port}s (see {@link SecondaryPort}). Adapters must not depend on {@link Application} code other than ports.
@@ -37,6 +39,7 @@
3739
@Retention(RetentionPolicy.RUNTIME)
3840
@Target({ ElementType.PACKAGE, ElementType.TYPE })
3941
@Documented
42+
@Stereotype(priority = 300)
4043
public @interface Adapter {
4144

4245
/**

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/Application.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* An annotation to assign packages and types the role of core application code. That code must not refer to any
2628
* {@link Adapter} code but only either expose or depend on functionality through {@link Port}s connecting the
@@ -36,4 +38,5 @@
3638
@Retention(RetentionPolicy.RUNTIME)
3739
@Target({ ElementType.PACKAGE, ElementType.TYPE })
3840
@Documented
41+
@Stereotype(priority = 400)
3942
public @interface Application {}

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/Port.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* A {@link Port} defines an entry point into the {@link Application} that can either drive it (see {@link PrimaryPort})
2628
* or be driven by the application (see {@link SecondaryPort}). They are the interface with which the application
@@ -39,6 +41,7 @@
3941
@Retention(RetentionPolicy.RUNTIME)
4042
@Target({ ElementType.PACKAGE, ElementType.TYPE })
4143
@Documented
44+
@Stereotype(priority = 300)
4245
public @interface Port {
4346

4447
/**

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/PrimaryAdapter.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* A {@link PrimaryAdapter} connects the outside of an application to an {@link PrimaryPort} exposed by the
2628
* application's core. For example, it could be a component accepting HTTP requests or a listener for a message broker.
@@ -35,6 +37,7 @@
3537
@Retention(RetentionPolicy.RUNTIME)
3638
@Target({ ElementType.PACKAGE, ElementType.TYPE })
3739
@Documented
40+
@Stereotype(priority = 100)
3841
public @interface PrimaryAdapter {
3942

4043
/**

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/PrimaryPort.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* In Hexagonal Architecture an {@link PrimaryPort} describes an interface into an application's core that is exposed to
2628
* the outside to drive the application. A {@link PrimaryAdapter} would refer to those ports in its implementation.
@@ -35,6 +37,7 @@
3537
@Retention(RetentionPolicy.RUNTIME)
3638
@Target({ ElementType.PACKAGE, ElementType.TYPE })
3739
@Documented
40+
@Stereotype(priority = 100)
3841
public @interface PrimaryPort {
3942

4043
/**

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/SecondaryAdapter.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* {@link SecondaryAdapter}s implement {@link SecondaryPort} to ultimately link the applications core to some extrenal
2628
* technology, like a database, message broker, email server or third-party service.
@@ -33,6 +35,7 @@
3335
@Retention(RetentionPolicy.RUNTIME)
3436
@Target({ ElementType.PACKAGE, ElementType.TYPE })
3537
@Documented
38+
@Stereotype(priority = 200)
3639
public @interface SecondaryAdapter {
3740

3841
/**

Diff for: jmolecules-architecture/jmolecules-hexagonal-architecture/src/main/java/org/jmolecules/architecture/hexagonal/SecondaryPort.java

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.RetentionPolicy;
2222
import java.lang.annotation.Target;
2323

24+
import org.jmolecules.stereotype.Stereotype;
25+
2426
/**
2527
* An {@link SecondaryPort} describes abstractions that describes interfaces to the outside that are driven by the
2628
* application's core, like a repository (to interact with a database) or a message publisher. Usually
@@ -36,6 +38,7 @@
3638
@Retention(RetentionPolicy.RUNTIME)
3739
@Target({ ElementType.PACKAGE, ElementType.TYPE })
3840
@Documented
41+
@Stereotype(priority = 200)
3942
public @interface SecondaryPort {
4043

4144
/**

0 commit comments

Comments
 (0)