Skip to content

Commit

Permalink
Dependency considers annotations #171
Browse files Browse the repository at this point in the history
Dependencies now consider annotations, nested annotations and annotation parameters.

* Dependencies from and to class, field, method and constructor annotations.
* Dependencies from and to annotation parameters. 
* Dependencies from and to nested annotations (and parameters).
  • Loading branch information
codecholeric committed Jan 9, 2020
2 parents 945ba0e + bf0ac80 commit 710a157
Show file tree
Hide file tree
Showing 77 changed files with 2,530 additions and 641 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ public class LayerDependencyRulesTest {
@ArchTest
public static final ArchRule services_should_only_depend_on_persistence_or_other_services =
classes().that().resideInAPackage("..service..")
.should().onlyDependOnClassesThat().resideInAnyPackage("..service..", "..persistence..", "java..");
.should().onlyDependOnClassesThat().resideInAnyPackage("..service..", "..persistence..", "java..", "javax..");

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
Class <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService> implements interface <com.tngtech.archunit.example.layers.service.ServiceInterface> in (DaoCallingService.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> has annotation member of type <com.tngtech.archunit.example.layers.service.ServiceType> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> has annotation member of type <com.tngtech.archunit.example.layers.service.SimpleServiceAnnotation> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> is annotated with <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.impl.ServiceImplementation> implements interface <com.tngtech.archunit.example.layers.service.ServiceInterface> in (ServiceImplementation.java:0)
Constructor <com.tngtech.archunit.example.layers.SomeMediator.<init>(com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules)> has parameter of type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeMediator.java:0)
Field <com.tngtech.archunit.example.layers.SomeMediator.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeMediator.java:0)
Field <com.tngtech.archunit.example.layers.controller.SomeController.otherService> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeController.java:0)
Field <com.tngtech.archunit.example.layers.controller.SomeController.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules> in (SomeController.java:0)
Field <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (DaoCallingService.java:0)
Field <com.tngtech.archunit.example.layers.service.ServiceType.$VALUES> has type <[Lcom.tngtech.archunit.example.layers.service.ServiceType;> in (ServiceType.java:0)
Field <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules.myEntityManager> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules$MyEntityManager> in (ServiceViolatingDaoRules.java:0)
Method <com.tngtech.archunit.example.layers.SomeMediator.violateLayerRulesIndirectly()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules.doSomething()> in (SomeMediator.java:15)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> calls constructor <com.tngtech.archunit.example.layers.service.ServiceHelper.<init>()> in (SomeGuiController.java:7)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> calls constructor <com.tngtech.archunit.example.layers.service.ServiceHelper.<init>(java.lang.String)> in (SomeGuiController.java:8)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> gets field <com.tngtech.archunit.example.layers.service.ServiceHelper.insecure> in (SomeGuiController.java:10)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> gets field <com.tngtech.archunit.example.layers.service.ServiceHelper.properlySecured> in (SomeGuiController.java:11)
Method <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService.violateLayerRules()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules.doSomething()> in (DaoCallingService.java:14)
Method <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation.serviceType()> has return type <com.tngtech.archunit.example.layers.service.ServiceType> in (ComplexServiceAnnotation.java:0)
Method <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation.simpleServiceAnnotation()> has return type <com.tngtech.archunit.example.layers.service.SimpleServiceAnnotation> in (ComplexServiceAnnotation.java:0)
Method <com.tngtech.archunit.example.layers.service.ServiceType.values()> calls method <[Lcom.tngtech.archunit.example.layers.service.ServiceType;.clone()> in (ServiceType.java:3)
Method <com.tngtech.archunit.example.layers.service.ServiceType.values()> has return type <[Lcom.tngtech.archunit.example.layers.service.ServiceType;> in (ServiceType.java:0)
Method <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules.illegallyUseEntityManager()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules$MyEntityManager.persist(java.lang.Object)> in (ServiceViolatingDaoRules.java:27)
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ public class LayerDependencyRulesTest {
@ArchTest
static final ArchRule services_should_only_depend_on_persistence_or_other_services =
classes().that().resideInAPackage("..service..")
.should().onlyDependOnClassesThat().resideInAnyPackage("..service..", "..persistence..", "java..");
.should().onlyDependOnClassesThat().resideInAnyPackage("..service..", "..persistence..", "java..", "javax..");

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
Class <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService> implements interface <com.tngtech.archunit.example.layers.service.ServiceInterface> in (DaoCallingService.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> has annotation member of type <com.tngtech.archunit.example.layers.service.ServiceType> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> has annotation member of type <com.tngtech.archunit.example.layers.service.SimpleServiceAnnotation> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> is annotated with <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.impl.ServiceImplementation> implements interface <com.tngtech.archunit.example.layers.service.ServiceInterface> in (ServiceImplementation.java:0)
Constructor <com.tngtech.archunit.example.layers.SomeMediator.<init>(com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules)> has parameter of type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeMediator.java:0)
Field <com.tngtech.archunit.example.layers.SomeMediator.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeMediator.java:0)
Field <com.tngtech.archunit.example.layers.controller.SomeController.otherService> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeController.java:0)
Field <com.tngtech.archunit.example.layers.controller.SomeController.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules> in (SomeController.java:0)
Field <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (DaoCallingService.java:0)
Field <com.tngtech.archunit.example.layers.service.ServiceType.$VALUES> has type <[Lcom.tngtech.archunit.example.layers.service.ServiceType;> in (ServiceType.java:0)
Field <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules.myEntityManager> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules$MyEntityManager> in (ServiceViolatingDaoRules.java:0)
Method <com.tngtech.archunit.example.layers.SomeMediator.violateLayerRulesIndirectly()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules.doSomething()> in (SomeMediator.java:15)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> calls constructor <com.tngtech.archunit.example.layers.service.ServiceHelper.<init>()> in (SomeGuiController.java:7)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> calls constructor <com.tngtech.archunit.example.layers.service.ServiceHelper.<init>(java.lang.String)> in (SomeGuiController.java:8)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> gets field <com.tngtech.archunit.example.layers.service.ServiceHelper.insecure> in (SomeGuiController.java:10)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> gets field <com.tngtech.archunit.example.layers.service.ServiceHelper.properlySecured> in (SomeGuiController.java:11)
Method <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService.violateLayerRules()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules.doSomething()> in (DaoCallingService.java:14)
Method <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation.serviceType()> has return type <com.tngtech.archunit.example.layers.service.ServiceType> in (ComplexServiceAnnotation.java:0)
Method <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation.simpleServiceAnnotation()> has return type <com.tngtech.archunit.example.layers.service.SimpleServiceAnnotation> in (ComplexServiceAnnotation.java:0)
Method <com.tngtech.archunit.example.layers.service.ServiceType.values()> calls method <[Lcom.tngtech.archunit.example.layers.service.ServiceType;.clone()> in (ServiceType.java:3)
Method <com.tngtech.archunit.example.layers.service.ServiceType.values()> has return type <[Lcom.tngtech.archunit.example.layers.service.ServiceType;> in (ServiceType.java:0)
Method <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules.illegallyUseEntityManager()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules$MyEntityManager.persist(java.lang.Object)> in (ServiceViolatingDaoRules.java:27)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.tngtech.archunit.example.layers.controller;

public @interface ComplexControllerAnnotation {
SimpleControllerAnnotation simpleControllerAnnotation();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tngtech.archunit.example.layers.controller;

public @interface SimpleControllerAnnotation {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.tngtech.archunit.example.layers.service;

import com.tngtech.archunit.example.layers.controller.ComplexControllerAnnotation;
import com.tngtech.archunit.example.layers.controller.one.SomeEnum;

public @interface ComplexServiceAnnotation {
ComplexControllerAnnotation controllerAnnotation();

SimpleServiceAnnotation simpleServiceAnnotation();

SomeEnum controllerEnum();

ServiceType serviceType();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.tngtech.archunit.example.layers.service;

public enum ServiceType {
STANDARD
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.tngtech.archunit.example.layers.service;

import com.tngtech.archunit.example.layers.MyService;
import com.tngtech.archunit.example.layers.controller.ComplexControllerAnnotation;
import com.tngtech.archunit.example.layers.controller.SimpleControllerAnnotation;
import com.tngtech.archunit.example.layers.controller.SomeGuiController;
import com.tngtech.archunit.example.layers.controller.one.SomeEnum;
import com.tngtech.archunit.example.layers.controller.one.UseCaseOneTwoController;
import com.tngtech.archunit.example.layers.controller.two.UseCaseTwoController;
import com.tngtech.archunit.example.layers.security.Secured;

@MyService
@ComplexServiceAnnotation(
controllerAnnotation = @ComplexControllerAnnotation(simpleControllerAnnotation = @SimpleControllerAnnotation),
simpleServiceAnnotation = @SimpleServiceAnnotation,
controllerEnum = SomeEnum.DISPATCH,
serviceType = ServiceType.STANDARD
)
public class ServiceViolatingLayerRules {
public static final String illegalAccessToController = "illegalAccessToController";
public static final String doSomething = "doSomething";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tngtech.archunit.example.layers.service;

public @interface SimpleServiceAnnotation {
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public void services_should_only_be_depended_on_by_controllers_or_other_services
@Test
public void services_should_only_depend_on_persistence_or_other_services() {
classes().that().resideInAPackage("..service..")
.should().onlyDependOnClassesThat().resideInAnyPackage("..service..", "..persistence..", "java..").check(classes);
.should().onlyDependOnClassesThat().resideInAnyPackage("..service..", "..persistence..", "java..", "javax..")
.check(classes);
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
Class <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService> implements interface <com.tngtech.archunit.example.layers.service.ServiceInterface> in (DaoCallingService.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> has annotation member of type <com.tngtech.archunit.example.layers.service.ServiceType> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> has annotation member of type <com.tngtech.archunit.example.layers.service.SimpleServiceAnnotation> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> is annotated with <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation> in (ServiceViolatingLayerRules.java:0)
Class <com.tngtech.archunit.example.layers.service.impl.ServiceImplementation> implements interface <com.tngtech.archunit.example.layers.service.ServiceInterface> in (ServiceImplementation.java:0)
Constructor <com.tngtech.archunit.example.layers.SomeMediator.<init>(com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules)> has parameter of type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeMediator.java:0)
Field <com.tngtech.archunit.example.layers.SomeMediator.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeMediator.java:0)
Field <com.tngtech.archunit.example.layers.controller.SomeController.otherService> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (SomeController.java:0)
Field <com.tngtech.archunit.example.layers.controller.SomeController.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules> in (SomeController.java:0)
Field <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService.service> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules> in (DaoCallingService.java:0)
Field <com.tngtech.archunit.example.layers.service.ServiceType.$VALUES> has type <[Lcom.tngtech.archunit.example.layers.service.ServiceType;> in (ServiceType.java:0)
Field <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules.myEntityManager> has type <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules$MyEntityManager> in (ServiceViolatingDaoRules.java:0)
Method <com.tngtech.archunit.example.layers.SomeMediator.violateLayerRulesIndirectly()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules.doSomething()> in (SomeMediator.java:15)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> calls constructor <com.tngtech.archunit.example.layers.service.ServiceHelper.<init>()> in (SomeGuiController.java:7)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> calls constructor <com.tngtech.archunit.example.layers.service.ServiceHelper.<init>(java.lang.String)> in (SomeGuiController.java:8)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> gets field <com.tngtech.archunit.example.layers.service.ServiceHelper.insecure> in (SomeGuiController.java:10)
Method <com.tngtech.archunit.example.layers.controller.SomeGuiController.callServiceLayer()> gets field <com.tngtech.archunit.example.layers.service.ServiceHelper.properlySecured> in (SomeGuiController.java:11)
Method <com.tngtech.archunit.example.layers.persistence.layerviolation.DaoCallingService.violateLayerRules()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingLayerRules.doSomething()> in (DaoCallingService.java:14)
Method <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation.serviceType()> has return type <com.tngtech.archunit.example.layers.service.ServiceType> in (ComplexServiceAnnotation.java:0)
Method <com.tngtech.archunit.example.layers.service.ComplexServiceAnnotation.simpleServiceAnnotation()> has return type <com.tngtech.archunit.example.layers.service.SimpleServiceAnnotation> in (ComplexServiceAnnotation.java:0)
Method <com.tngtech.archunit.example.layers.service.ServiceType.values()> calls method <[Lcom.tngtech.archunit.example.layers.service.ServiceType;.clone()> in (ServiceType.java:3)
Method <com.tngtech.archunit.example.layers.service.ServiceType.values()> has return type <[Lcom.tngtech.archunit.example.layers.service.ServiceType;> in (ServiceType.java:0)
Method <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules.illegallyUseEntityManager()> calls method <com.tngtech.archunit.example.layers.service.ServiceViolatingDaoRules$MyEntityManager.persist(java.lang.Object)> in (ServiceViolatingDaoRules.java:27)
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ public boolean apply(JavaClass input) {
};
}

private static DescribedPredicate<JavaAnnotation> publicApiForInheritance() {
return new DescribedPredicate<JavaAnnotation>("@%s(usage = %s)", PublicAPI.class.getSimpleName(), INHERITANCE) {
private static DescribedPredicate<JavaAnnotation<?>> publicApiForInheritance() {
return new DescribedPredicate<JavaAnnotation<?>>("@%s(usage = %s)", PublicAPI.class.getSimpleName(), INHERITANCE) {
@Override
public boolean apply(JavaAnnotation input) {
public boolean apply(JavaAnnotation<?> input) {
return input.getRawType().isEquivalentTo(PublicAPI.class) &&
input.as(PublicAPI.class).usage() == INHERITANCE;
}
Expand Down
Loading

0 comments on commit 710a157

Please sign in to comment.