Skip to content

Commit

Permalink
Ensure Required Annotations Based on Presence of Specified Annotation…
Browse files Browse the repository at this point in the history
… on a Method

Closes gb-102
  • Loading branch information
mnhock authored and mnhock committed Sep 23, 2024
1 parent da0d8c3 commit 5855b33
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
19 changes: 17 additions & 2 deletions docs/USERGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ The default mode is `WITHOUT_TESTS`, which excludes test classes from the import
| General | `fieldsShouldNotBePublic` | Fields should not be `public`, except constants. |
| General | `methodsShouldNotDeclareGenericExceptions` | Methods should not declare generic exceptions, like `Exception` or `RuntimeException`. |
| General | `methodsShouldNotDeclareException` | Methods with names matching a specified pattern should not declare a specified exception type. |
| General | `methodsShouldBeAnnotatedWithAll` | Methods annotated with a specific annotation should be annotated with a specified annotations. |
| General | `noUsageOf` | Disallow usage of specific classes. |
| General | `noUsageOfDeprecatedAPIs` | No usage of deprecated APIs annotated with `@Deprecated`. |
| General | `noUsageOfSystemOutOrErr` | Disallow usage of `System.out` or `System.err`. |
Expand Down Expand Up @@ -268,8 +269,8 @@ Taikai.builder()
Taikai.builder()
.namespace("com.company.project")
.java(java -> java
.classesShouldNotBeAnnotatedWithAll(Modifying.class, List.of(Transactional.class, Query.class))
.classesShouldNotBeAnnotatedWithAll("org.springframework.data.jpa.repository.Modifying", List.of("org.springframework.transaction.annotation.Transactional", "org.springframework.data.jpa.repository.Query"))
.classesShouldBeAnnotatedWithAll(RestController.class, List.of(RequestMapping.class))
.classesShouldBeAnnotatedWithAll("org.springframework.web.bind.annotation.RestController", List.of("org.springframework.web.bind.annotation.RequestMapping"))
.build()
.check();
```
Expand Down Expand Up @@ -333,6 +334,20 @@ Taikai.builder()
.check();
```


- **Methods Annotated with a Specified Annotation Should Be Annotated with Specified Annotations**: Ensure that methods annotated with a specific annotations should be annotated with the specified annotations.

```java
Taikai.builder()
.namespace("com.company.project")
.java(java -> java
.methodsShouldBeAnnotatedWithAll(Modifying.class, List.of(Transactional.class, Query.class))
.methodsShouldBeAnnotatedWithAll("org.springframework.data.jpa.repository.Modifying", List.of("org.springframework.transaction.annotation.Transactional", "org.springframework.data.jpa.repository.Query"))
.build()
.check();
```


- **Utility Classes Should Be Final and Have Private Constructor**: Ensure that utility classes with only `static` methods except `main` should be declared as `final` and have `private` constructors to prevent instantiation.

```java
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/enofex/taikai/java/JavaConfigurer.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ public JavaConfigurer methodsShouldNotDeclareException(String regex, String type
configuration));
}

public JavaConfigurer methodsShouldBeAnnotatedWithAll(Class<? extends Annotation> annotationType,
Collection<Class<? extends Annotation>> requiredAnnotationTypes) {
return methodsShouldBeAnnotatedWithAll(annotationType.getName(),
requiredAnnotationTypes.stream().map(Class::getName).toList(), defaultConfiguration());
}

public JavaConfigurer methodsShouldBeAnnotatedWithAll(String annotationType,
Collection<String> requiredAnnotationTypes) {
return methodsShouldBeAnnotatedWithAll(annotationType, requiredAnnotationTypes,
defaultConfiguration());
}

public JavaConfigurer methodsShouldBeAnnotatedWithAll(String annotationType,
Collection<String> requiredAnnotationTypes, Configuration configuration) {
return addRule(TaikaiRule.of(methods()
.that().areMetaAnnotatedWith(annotationType)
.should(be(annotatedWithAll(requiredAnnotationTypes, true)))
.as("Methods annotated with %s should be annotated with %s".formatted(
annotationType, String.join(", ", requiredAnnotationTypes))),
configuration));
}

public JavaConfigurer noUsageOfDeprecatedAPIs() {
return noUsageOfDeprecatedAPIs(defaultConfiguration());
}
Expand Down

0 comments on commit 5855b33

Please sign in to comment.