This document describes coding rules for the Spring PetClinic.

Note
The rules defined in this and all included documents are for demonstration purposes only and work in progress. For rendering of embedded diagrams Graphviz needs to be installed and available via the system path.
Tip
GraphML reports may be viewed using yEd. After opening a file you should apply a layout, e.g. Layout  Hierarchical.

1. Summary

Table 1. Constraints
Id Description Severity Status

dependency:PackageCycles

There must be no cyclic package dependencies.

MAJOR

SUCCESS

junit4:IgnoreWithoutMessage

All @Ignore annotations must provide a message.

MAJOR

SUCCESS

layer:LayerDependencyViolation

There must be no dependencies between layers that are not explicitly defined.

MAJOR

SUCCESS

model:JpaEntityInModelPackage

All JPA entities must be located in packages named "model".

MAJOR

SUCCESS

spring-component:ControllerDependencies

A controller can only have dependencies to services (e.g. direct usage of repositories is not allowed).

MAJOR

SUCCESS

spring-component:ControllerMustBeLocatedInWebLayer

A controller must be located in the layer named 'web'.

MAJOR

SUCCESS

spring-component:ImplementationDependencies

There must be no direct dependencies between Spring component implementations, i.e. only dependencies to interfaces are allowed.

MAJOR

SUCCESS

spring-component:RepositoryDependencies

A repository can only have dependencies to other repositories.

MAJOR

SUCCESS

spring-component:RepositoryMustBeLocatedInRepositoryLayer

A repository must be located in the layer named 'repository'.

MAJOR

SUCCESS

spring-component:ServiceDependencies

A service can only have dependencies to repositories or other services (e.g. usage of controllers is not allowed).

MAJOR

SUCCESS

spring-component:ServiceMustBeLocatedInServiceLayer

A service must be located in the layer named 'service'.

MAJOR

SUCCESS

test:TestMethodWithoutAssertion

All test methods must perform at least one assertion (within a call hierarchy of max. 3 steps).

MAJOR

SUCCESS

vcs:BranchesMustBeSynchronized

The branches "violations" and "jqa-remote" must include the latest commit (HEAD) of "master" (i.e. merges are required).

MAJOR

SUCCESS

Table 2. Concepts
Id Description Severity Status

assertj:AssertMethod

Mark all assertThat methods of 'org.assertj.core.api.Assertions' with "AssertJ" and "Assert".

MINOR

SUCCESS

business:Subdomain

Creates predefined Subdomain nodes and connects them to all Type nodes via naming conventions.

MINOR

SUCCESS

business:SubdomainDependency

Creates DEPENDS_ON relations between two subdomains if there are Java type dependencies between them.

MINOR

SUCCESS

dependency:Package

Creates a DEPENDS_ON relationship between a packages if there are type dependencies between them.

MINOR

SUCCESS

jpa2:Entity

Labels all types annotated with @javax.persistence.Entity with "Jpa" and "Entity".

MINOR

SUCCESS

junit4:TestMethod

Finds all test methods (i.e. annotated with "@org.junit.Test") and labels them with "Test" and "Junit4".

MINOR

SUCCESS

layer:Layer

Labels all direct sub-packages of the root package as Layer.

MINOR

SUCCESS

layer:LayerDependency

Adds a relation DEPENDS_ON between two layers if there are type dependencies between them.

MINOR

SUCCESS

layer:LayerDependencyDiagram

Creates a diagram about dependencies between layers.

MINOR

SUCCESS

layer:Root

Labels the root package of the main artifact as Root

MINOR

SUCCESS

management:ManagedResources

All managed resources including their attributes and operations.

MINOR

SUCCESS

maven:MainArtifact

Labels all main artifacts created by Maven modules with Main

MINOR

SUCCESS

maven:ProjectArtifactDependencyDiagram

Creates a diagram about project artifact dependencies.

MINOR

SUCCESS

package:DependencyDiagram

Creates a diagram about dependencies between layers.

MINOR

SUCCESS

spring-component:Component

Reports all Spring components.

MINOR

SUCCESS

spring-component:ComponentDependencies

Creates a USES relation between Spring components.

MINOR

SUCCESS

spring-data:AnnotatedRepository

Labels all types annotated with "org.springframework.stereotype.Repository" with "Spring", "Component" and "Repository".

MINOR

SUCCESS

spring-data:ImplementedRepository

Labels all types implementing "org.springframework.data.repository.Repository" with "Spring", "Component" and "Repository".

MINOR

SUCCESS

spring-data:Repository

Returns all repositories.

MINOR

SUCCESS

spring-jmx:ManagedAttribute

Labels all methods annotated with "org.springframework.jmx.export.annotation.ManagedAttribute" with "Spring" and "ManagedAttribute".

MINOR

SUCCESS

spring-jmx:ManagedOperation

Labels all methods annotated with "org.springframework.jmx.export.annotation.ManagedAttribute" with "Spring" and "ManagedOperation".

MINOR

SUCCESS

spring-jmx:ManagedResource

Labels all types annotated with "org.springframework.jmx.export.annotation.ManagedResource" with "Spring" and "ManagedResource".

MINOR

SUCCESS

spring-mvc:Controller

Labels all types annotated with "org.springframework.stereotype.Controller" with "Spring", "Component" and "Controller".

MINOR

SUCCESS

spring-mvc:Service

Labels all types annotated with "org.springframework.stereotype.Service" with "Spring", "Component" and "Service".

MINOR

SUCCESS

spring-test-web:Assert

Mark method "org.springframework.test.web.servlet.ResultActions#andExpect" as "Spring" and "Assert".

MINOR

SUCCESS

vcs:CurrentBranch

Labels the current branch with Current.

MINOR

SUCCESS

2. CI Build

The following rule groups are executed during a build:

3. Maven

This chapter describes the rules related to Maven.

3.1. Concepts

Labels all main artifacts created by Maven modules with Main
MATCH
  (:Maven:Project)-[:CREATES]->(mainArtifact:Artifact)
WHERE
  mainArtifact.type <> "test-jar"
SET
  mainArtifact:Main
RETURN
  mainArtifact as MainArtifact

Status: SUCCESS Severity: MINOR
MainArtifact
org.springframework.samples:spring-petclinic:war:4.2.6-SNAPSHOT

3.2. Reports

Creates a diagram about project artifact dependencies.
MATCH
  (:Maven:Project)-[:CREATES]->(artifact:Artifact)
OPTIONAL MATCH
  (artifact)-[dependsOn:DEPENDS_ON]->(:Artifact)<-[:CREATES]-(:Maven:Project)
RETURN
  *

4. Package

This chapter describes the concepts and constraints related to the package structure. The following constraints are verified:

The following

4.1. Reports

Creates a diagram about dependencies between layers.
MATCH
  (artifact:Artifact)-[:CONTAINS]->(package:Package)-[:CONTAINS]->(:Type)
WHERE
  artifact.type <> "test-jar"
OPTIONAL MATCH
  (package)-[dependsOn:DEPENDS_ON]->(:Package)
RETURN
  {
    role : "graph",
    parent : artifact,
    nodes : collect(package),
    relationships: collect(dependsOn)
  }

5. Layer

This chapter describes the concepts and constraints related to the layered package structure.

5.1. Concepts

The root package of the application is "org.springframework.samples.petclinic".

Labels the root package of the main artifact as Root
MATCH
  (:Main:Artifact)-[:CONTAINS]->(rootPackage:Package)
WHERE
  rootPackage.fqn = "org.springframework.samples.petclinic"
SET
  rootPackage:Root
RETURN
  rootPackage as RootPackage

Status: SUCCESS Severity: MINOR
RootPackage
org.springframework.samples.petclinic

The application has a layered structure. Each layer is represented by a package located directly in the root package:

  • web

  • service

  • repository

  • model

Labels all direct sub-packages of the root package as Layer.
MATCH
  (:Root:Package)-[:CONTAINS]->(layer:Package)
WHERE
  layer.name in [
    "web",
    "service",
    "repository",
    "model"
  ]
SET
  layer:Layer
RETURN
  layer as Layer

Status: SUCCESS Severity: MINOR
Layer
org.springframework.samples.petclinic.repository
org.springframework.samples.petclinic.service
org.springframework.samples.petclinic.web
org.springframework.samples.petclinic.model

A dependency between two layers exists if there are dependencies between Java types in any of the sub-packages.

Adds a relation DEPENDS_ON between two layers if there are type dependencies between them.
MATCH
  (layer1:Layer:Package)-[:CONTAINS*]->(type1:Type),
  (layer2:Layer:Package)-[:CONTAINS*]->(type2:Type),
  (type1)-[d:DEPENDS_ON]->(type2)
WHERE
  layer1 <> layer2
WITH
  layer1, layer2, count(d) as weight
MERGE
  (layer1)-[d:DEPENDS_ON]->(layer2)
SET
  d.weight = weight
RETURN
  layer1 as Dependent, layer2 as Dependency, weight as Weight

Status: SUCCESS Severity: MINOR
Dependent Dependency Weight
org.springframework.samples.petclinic.web org.springframework.samples.petclinic.service 5
org.springframework.samples.petclinic.service org.springframework.samples.petclinic.repository 4
org.springframework.samples.petclinic.service org.springframework.samples.petclinic.model 10
org.springframework.samples.petclinic.repository org.springframework.samples.petclinic.model 27
org.springframework.samples.petclinic.web org.springframework.samples.petclinic.model 9

There are definitions of allowed dependencies between layers.

Adds DEFINES_DEPENDENCY relations between layers for allowed dependencies.
MATCH
  (web:Layer {name:"web"}),
  (service:Layer {name:"service"}),
  (repository:Layer {name:"repository"}),
  (model:Layer {name:"model"})
CREATE UNIQUE
 (web)-[w1:DEFINES_DEPENDENCY]->(service),
 (web)-[w2:DEFINES_DEPENDENCY]->(model),
 (service)-[s1:DEFINES_DEPENDENCY]->(repository),
 (service)-[s2:DEFINES_DEPENDENCY]->(model),
 (repository)-[r1:DEFINES_DEPENDENCY]->(model)
RETURN
  *

Status: Not Available

5.2. Constraints

There must be no dependencies between layers that are not explicitly defined.
MATCH
  (layer1:Layer)-[:DEPENDS_ON]->(layer2:Layer)
WHERE NOT
  (layer1)-[:DEFINES_DEPENDENCY]->(layer2)
WITH
  layer1, layer2
MATCH
  (layer1)-[:CONTAINS*]->(type1:Type),
  (layer2)-[:CONTAINS*]->(type2:Type),
  (type1)-[:DEPENDS_ON]->(type2)
RETURN
  layer1.name as Layer, type1 as Type, layer2.name as LayerDependency, type2 as TypeDependency

Status: SUCCESS Severity: MAJOR
Empty Result

5.3. Reports

Creates a diagram about dependencies between layers.
MATCH
  (layer:Layer)
OPTIONAL MATCH
  (layer)-[dependsOn:DEPENDS_ON]->(:Layer)
RETURN
  *

Creates a GraphML report about dependencies between layers and their contained types.
MATCH
  (layer:Layer:Package)-[:CONTAINS*]->(type:Type)
OPTIONAL MATCH
  (type)-[dependsOn:DEPENDS_ON]->(:Type)
RETURN {
  role : "graph",
  parent : layer,
  nodes : collect(type),
  relationships : collect(dependsOn)
} as TypesPerLayer

Status: Not Available

6. Spring Components

The following constraints are verified:

The following GraphML reports are created:

6.1. Overview

The application consists of the following components:

class diagram
  • UI

    • Controller implementations

  • Logic

    • Service interfaces and implementations

  • Persistence

    • Repository interfaces and implementations

      • Spring Data (interface declaration only)

      • JPA

      • JDBC

6.2. Constraints

The following sections describe restrictions on dependencies between these components.

6.2.1. General

There must be no direct dependencies between Spring component implementations, i.e. only dependencies to interfaces are allowed.
MATCH
  (type:Spring:Component)-[:DECLARES]->(:Method)-[:INVOKES]->(:Method)<-[:DECLARES]-(otherType:Spring:Component)
WHERE
  type <> otherType
  and not otherType:Interface
RETURN DISTINCT
  type as Dependent, otherType as InvalidDependency

Status: SUCCESS Severity: MAJOR
Empty Result

6.2.2. UI

The server side UI implementation is based on Spring MVC controllers:

Example controller
@Controller
@RequestMapping("/resource")
public class MyController {

    private final MyService service;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String get() {
    }
}
A controller can only have dependencies to services (e.g. direct usage of repositories is not allowed).
MATCH
  (type:Spring:Controller)-[:USES]->(otherType:Spring:Component)
WHERE NOT
  otherType:Service
RETURN DISTINCT
  type as InvalidController, otherType as Dependency

Status: SUCCESS Severity: MAJOR
Empty Result

A controller must be located in the layer named 'web'.
MATCH
  (controller:Spring:Controller)
WHERE NOT
  (:Layer{name:"web"})-[:CONTAINS*]->(controller)
RETURN
  controller as Controller

Status: SUCCESS Severity: MAJOR
Empty Result

6.2.3. Logic

The business logic consists of services which are defined by interfaces and implemented by classes annotated with @Service:

Example service interface
public interface MyService {
    Collection<Foo> findFoos() throws DataAccessException;
}
Example service implementation
@Service
public class MyServiceImpl implements MyService {

    private FooRepository fooRepository;

    @Autowired
    public ServiceImpl(FooRepository fooRepository) {
        this.fooRepository = fooRepository;
    }
}
A service can only have dependencies to repositories or other services (e.g. usage of controllers is not allowed).
MATCH
  (type:Spring:Service)-[:USES]->(otherType:Spring:Component)
WHERE NOT (
  otherType:Service
  or otherType:Repository
)
RETURN DISTINCT
  type as InvalidService, otherType as Dependency

Status: SUCCESS Severity: MAJOR
Empty Result

A service must be located in the layer named 'service'.
MATCH
  (service:Spring:Service)
WHERE NOT
  (:Layer{name:"service"})-[:CONTAINS*]->(service)
RETURN
  service as Service

Status: SUCCESS Severity: MAJOR
Empty Result

6.2.4. Persistence

Repositories provide access to the database and are defined by interfaces (one per model element):

Example repository interface
public interface FooRepository {
    Collection<Foo> findFoos() throws DataAccessException;
}

There are three options to provide or implement a repository:

Example Spring Data repository
public interface SpringDataFooRepository extends FooRepository, Repository<Foo, Integer> {

    @Override
    @Query("SELECT foo FROM Foo ORDER BY foo.name")
    List<Foo> findFoos() throws DataAccessException;
}
Example JPA repository
@Repository
public class JpaFooRepositoryImpl implements FooRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    @SuppressWarnings("unchecked")
    public List<Foo> findFoos() {
        return this.em.createQuery("SELECT foo FROM Foo ORDER BY foo.name").getResultList();
    }
Example JDBC repository
@Repository
public class JdbcFooRepositoryImpl implements Repository {

    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    public JdbcRepositoryImpl(DataSource dataSource) {
        this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    @Override
    public List<Foo> findFoos() throws DataAccessException {
        Map<String, Object> params = new HashMap<>();
        return this.namedParameterJdbcTemplate.query(
            "SELECT id, name FROM foo ORDER BY name",
            params,
            BeanPropertyRowMapper.newInstance(Foo.class));
    }
A repository can only have dependencies to other repositories.
MATCH
  (type:Spring:Repository)-[:USES]->(otherType:Spring:Component)
WHERE NOT
  otherType:Repository
RETURN DISTINCT
  type as InvalidRepository, otherType as Dependency

Status: SUCCESS Severity: MAJOR
Empty Result

A repository must be located in the layer named 'repository'.
MATCH
  (repository:Spring:Repository)
WHERE NOT
  (:Layer{name:"repository"})-[:CONTAINS*]->(repository)
RETURN
  repository as Repository

Status: SUCCESS Severity: MAJOR
Empty Result

6.3. Concepts

Reports all Spring components.
MATCH
  (component:Spring:Component)
RETURN
  component as Component

Status: SUCCESS Severity: MINOR
Component
org.springframework.samples.petclinic.repository.jdbc.JdbcOwnerRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcPetRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcVetRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcVisitRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaOwnerRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaPetRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaVetRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaVisitRepositoryImpl
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataOwnerRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataPetRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVetRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVisitRepository
org.springframework.samples.petclinic.service.ClinicServiceImpl
org.springframework.samples.petclinic.web.CrashController
org.springframework.samples.petclinic.web.OwnerController
org.springframework.samples.petclinic.web.PetController
org.springframework.samples.petclinic.web.VetController
org.springframework.samples.petclinic.web.VisitController

Creates a USES relation between Spring components.
MATCH
  (type:Spring:Component)-[:DECLARES]->(:Method)-[:INVOKES]->(:Method)<-[:DECLARES]-(:Type:Interface)<-[:IMPLEMENTS|EXTENDS*]-(otherType:Spring:Component)
WHERE
  type <> otherType
MERGE
  (type)-[:USES]->(otherType)
RETURN
  type as Dependent, collect(distinct otherType.fqn) as Dependencies

Status: SUCCESS Severity: MINOR
Dependent Dependencies
org.springframework.samples.petclinic.web.VisitController org.springframework.samples.petclinic.service.ClinicServiceImpl
org.springframework.samples.petclinic.web.PetController org.springframework.samples.petclinic.service.ClinicServiceImpl
org.springframework.samples.petclinic.web.VetController org.springframework.samples.petclinic.service.ClinicServiceImpl
org.springframework.samples.petclinic.web.OwnerController org.springframework.samples.petclinic.service.ClinicServiceImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcPetRepositoryImpl org.springframework.samples.petclinic.repository.jdbc.JdbcOwnerRepositoryImpl org.springframework.samples.petclinic.repository.jpa.JpaOwnerRepositoryImpl org.springframework.samples.petclinic.repository.springdatajpa.SpringDataOwnerRepository
org.springframework.samples.petclinic.service.ClinicServiceImpl org.springframework.samples.petclinic.repository.jdbc.JdbcOwnerRepositoryImpl org.springframework.samples.petclinic.repository.jpa.JpaOwnerRepositoryImpl org.springframework.samples.petclinic.repository.springdatajpa.SpringDataOwnerRepository org.springframework.samples.petclinic.repository.jdbc.JdbcPetRepositoryImpl org.springframework.samples.petclinic.repository.jpa.JpaPetRepositoryImpl org.springframework.samples.petclinic.repository.springdatajpa.SpringDataPetRepository org.springframework.samples.petclinic.repository.jdbc.JdbcVisitRepositoryImpl org.springframework.samples.petclinic.repository.jpa.JpaVisitRepositoryImpl org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVisitRepository org.springframework.samples.petclinic.repository.jdbc.JdbcVetRepositoryImpl org.springframework.samples.petclinic.repository.jpa.JpaVetRepositoryImpl org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVetRepository

6.4. Reports

Actual usage dependencies between Spring components, i.e. controller, service and repository implementations.
MATCH
  (type:Spring:Component)-[uses:USES]->(otherType:Spring:Component)
RETURN
  type as Dependent,
  uses as Uses,
  otherType as Dependency

Status: Not Available

7. JPA Model

The following constraints are verified:

7.1. Constraints

All JPA entities must be located in packages named "model".
MATCH
  (package:Package)-[:CONTAINS]->(entity:Jpa:Entity)
WHERE
  package.name <> "model"
RETURN
  entity AS EntityInWrongPackage

Status: SUCCESS Severity: MAJOR
Empty Result

8. Business

This section describes the application from the business' perspective.

8.1. Concepts

The Spring PetClinic application consists of several business sub domains that can be identified by naming conventions.

Creates predefined Subdomain nodes and connects them to all Type nodes via naming conventions.
UNWIND [
    { name: "Clinic" },
    { name: "Owner" },
    { name: "Person" },
    { name: "Pet" },
    { name: "Specialty" },
    { name: "Vet" },
    { name: "Visit" }
]
AS properties
MERGE (s:Subdomain{name:properties.name})
WITH s
    MATCH (t:Type)
        WHERE t.name CONTAINS s.name
    MERGE (t)-[:BELONGS_TO]->(s)
RETURN s.name as Subdomain, COUNT(t) as Types

Status: SUCCESS Severity: MINOR
Subdomain Types
Visit 9
Person 1
Specialty 1
Clinic 6
Vet 9
Owner 7
Pet 17

There are dependencies between business sub domains.

Creates DEPENDS_ON relations between two subdomains if there are Java type dependencies between them.
MATCH
  (t1:Type)-[:BELONGS_TO]->(s1:Subdomain),
  (t2:Type)-[:BELONGS_TO]->(s2:Subdomain),
  (t1)-[d:DEPENDS_ON]->(t2)
WHERE
  s1 <> s2
WITH
  s1, s2, count(d) as weight
MERGE
  (s1)-[d:DEPENDS_ON]->(s2)
SET
  d.weight = weight
RETURN
  s1.name as Subdomain, collect(s2.name) as Dependencies
ORDER BY
  Subdomain

Status: SUCCESS Severity: MINOR
Subdomain Dependencies
Clinic Visit Specialty Owner Pet Vet
Owner Clinic Person Visit Pet
Pet Owner Clinic Visit
Vet Specialty Person Clinic
Visit Clinic Pet

9. Management

The following reports are created:

9.1. Reports

All managed resources including their attributes and operations.
MATCH
  (managedResource:Type)-[:DECLARES]->(member)
WHERE
  member:ManagedAttribute
  or member:ManagedOperation
RETURN
  managedResource as ManagedResource, collect(member.name) as Member

Status: SUCCESS Severity: MINOR
ManagedResource Member
org.springframework.samples.petclinic.util.CallMonitoringAspect isEnabled setEnabled reset getCallTime getCallCount

10. Tests

The following test rules apply:

The following reports are created:

10.1. Constraints

All test methods must perform at least one assertion (within a call hierarchy of max. 3 steps).
MATCH
  (testType:Test:Type)-[:DECLARES]->(testMethod:Test:Method)
WHERE
  NOT (testMethod)-[:INVOKES*..3]->(:Method:Assert)
RETURN
  testType AS DeclaringType,
  testMethod AS Method

Status: SUCCESS Severity: MAJOR
Empty Result

11. Version Control System

The rules defined in this document refer to Git.

11.1. Concepts

Labels the current branch with Current.
MATCH
  (repository:Repository)-[:HAS_BRANCH]->(branch:Git:Branch)
WHERE
  branch.name starts with "heads/"
MATCH
  (repository)-[:HAS_HEAD]->(head:Git:Commit),
  (branch)-[:HAS_HEAD]->(branchHead:Git:Commit),
   p=shortestPath((branchHead)-[:HAS_PARENT*0..]->(head))
SET
  branch:Current
RETURN
  branch.name as CurrentBranch, length(p) as Offset

Status: SUCCESS Severity: MINOR
CurrentBranch Offset
heads/master 0

11.2. Constraints

The branches "violations" and "jqa-remote" must include the latest commit (HEAD) of "master" (i.e. merges are required).
MATCH
  (master:Branch),
  (branch:Branch)
WHERE
  master.name = "heads/master"
  and branch.name in [
    "heads/violations",
    "heads/jqa-remote",
    "heads/testimpactanalysis"
  ]
WITH
  master, branch
MATCH
  (master)-[:HAS_HEAD]->(masterHead:Commit),
  (branch)-[:HAS_HEAD]->(branchHead:Commit)
OPTIONAL MATCH
  p=shortestPath((branchHead)-[:HAS_PARENT*]->(masterHead))
WITH
  master, branch, p
WHERE
  p is null
RETURN
  branch.name as OutdatedBranch

Status: SUCCESS Severity: MAJOR
Empty Result

12. Spring MVC Rules

This document defines concepts related to the Spring MVC Framework.

12.1. Concepts

Labels all types annotated with "org.springframework.stereotype.Service" with "Spring", "Component" and "Service".
MATCH
  (service:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.stereotype.Service"
SET
  service:Spring:Component:Service
RETURN
  service as Service

Status: SUCCESS Severity: MINOR
Service
org.springframework.samples.petclinic.service.ClinicServiceImpl

Labels all types annotated with "org.springframework.stereotype.Controller" with "Spring", "Component" and "Controller".
MATCH
  (controller:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.stereotype.Controller"
SET
  controller:Spring:Component:Controller
RETURN
  controller as Controller

Status: SUCCESS Severity: MINOR
Controller
org.springframework.samples.petclinic.web.VetController
org.springframework.samples.petclinic.web.VisitController
org.springframework.samples.petclinic.web.PetController
org.springframework.samples.petclinic.web.CrashController
org.springframework.samples.petclinic.web.OwnerController

13. Spring Data Rules

This document defines concepts related to the Spring Data Framework.

13.1. Concepts

Returns all repositories.
MATCH
  (repository:Spring:Repository)
RETURN
  repository as Repository

Status: SUCCESS Severity: MINOR
Repository
org.springframework.samples.petclinic.repository.jdbc.JdbcOwnerRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcPetRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcVetRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcVisitRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaOwnerRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaPetRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaVetRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaVisitRepositoryImpl
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataOwnerRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataPetRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVetRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVisitRepository

Labels all types annotated with "org.springframework.stereotype.Repository" with "Spring", "Component" and "Repository".
MATCH
  (repository:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.stereotype.Repository"
SET
  repository:Spring:Component:Repository
RETURN
  repository as Repository

Status: SUCCESS Severity: MINOR
Repository
org.springframework.samples.petclinic.repository.jpa.JpaOwnerRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaVetRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaPetRepositoryImpl
org.springframework.samples.petclinic.repository.jpa.JpaVisitRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcVisitRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcVetRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcPetRepositoryImpl
org.springframework.samples.petclinic.repository.jdbc.JdbcOwnerRepositoryImpl

Labels all types implementing "org.springframework.data.repository.Repository" with "Spring", "Component" and "Repository".
MATCH
  (repository:Type)-[:EXTENDS|IMPLEMENTS*]->(superType:Type)
WHERE
  superType.fqn in [
    "org.springframework.data.repository.Repository"
  ]
SET
  repository:Spring:Component:Repository
RETURN
  repository as Repository

Status: SUCCESS Severity: MINOR
Repository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataPetRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVetRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataVisitRepository
org.springframework.samples.petclinic.repository.springdatajpa.SpringDataOwnerRepository

14. Spring JMX Rules

This document defines concepts related to the Spring JMX Framework.

14.1. Concepts

Labels all types annotated with "org.springframework.jmx.export.annotation.ManagedResource" with "Spring" and "ManagedResource".
MATCH
  (managedResource:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.jmx.export.annotation.ManagedResource"
SET
  managedResource:Spring:ManagedResource
RETURN
  managedResource as ManagedResource

Status: SUCCESS Severity: MINOR
ManagedResource
org.springframework.samples.petclinic.util.CallMonitoringAspect

Labels all methods annotated with "org.springframework.jmx.export.annotation.ManagedAttribute" with "Spring" and "ManagedAttribute".
MATCH
  (managedAttribute:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.jmx.export.annotation.ManagedAttribute"
SET
  managedAttribute:Spring:ManagedAttribute
RETURN
  managedAttribute as ManagedAttribute

Status: SUCCESS Severity: MINOR
ManagedAttribute
org.springframework.samples.petclinic.util.CallMonitoringAspect#void setEnabled(boolean)
org.springframework.samples.petclinic.util.CallMonitoringAspect#boolean isEnabled()
org.springframework.samples.petclinic.util.CallMonitoringAspect#long getCallTime()
org.springframework.samples.petclinic.util.CallMonitoringAspect#int getCallCount()

Labels all methods annotated with "org.springframework.jmx.export.annotation.ManagedAttribute" with "Spring" and "ManagedOperation".
MATCH
  (managedOperation:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.jmx.export.annotation.ManagedOperation"
SET
  managedOperation:Spring:ManagedOperation
RETURN
  managedOperation as ManagedOperation

Status: SUCCESS Severity: MINOR
ManagedOperation
org.springframework.samples.petclinic.util.CallMonitoringAspect#void reset()

15. Spring Test Framework

15.1. Concepts

Mark method "org.springframework.test.web.servlet.ResultActions#andExpect" as "Spring" and "Assert".
MATCH
  (assertType:Type)-[:DECLARES]->(assertMethod)
WHERE
  assertType.fqn = 'org.springframework.test.web.servlet.ResultActions'
  and assertMethod.signature =~ '.* andExpect.*'
SET
  assertMethod:Spring:Assert
RETURN
  assertMethod

Status: SUCCESS Severity: MINOR
assertMethod
org.springframework.test.web.servlet.ResultActions#org.springframework.test.web.servlet.ResultActions andExpect(org.springframework.test.web.servlet.ResultMatcher)

16. AssertJ

16.1. Concepts

Mark all assertThat methods of 'org.assertj.core.api.Assertions' with "AssertJ" and "Assert".
MATCH
  (assertType:Type)-[:DECLARES]->(assertMethod)
WHERE
  assertType.fqn = 'org.assertj.core.api.Assertions'
  and assertMethod.signature =~ '.* assertThat.*'
SET
  assertMethod:AssertJ:Assert
RETURN
  assertMethod

Status: SUCCESS Severity: MINOR
assertMethod
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractObjectAssert assertThat(java.lang.Object)
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractBooleanAssert assertThat(boolean)
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractCharSequenceAssert assertThat(java.lang.String)
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractIntegerAssert assertThat(int)
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractComparableAssert assertThat(java.lang.Comparable)
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractIntegerAssert assertThat(java.lang.Integer)
org.assertj.core.api.Assertions#org.assertj.core.api.AbstractLongAssert assertThat(long)

17. Imported Rules

Creates a DEPENDS_ON relationship between a packages if there are type dependencies between them.
MATCH
    (p1:Package)-[:CONTAINS]->(t1:Type)-[:DEPENDS_ON]->(t2:Type)<-[:CONTAINS]-(p2:Package)
WHERE
    p1<>p2
CREATE UNIQUE
    (p1)-[:DEPENDS_ON]->(p2)
RETURN
    p1 AS package, COUNT(DISTINCT p2) AS PackageDependencies

Status: SUCCESS Severity: MINOR
package PackageDependencies
org.springframework.samples.petclinic.repository.springdatajpa 2
org.springframework.samples.petclinic.repository 1
org.springframework.samples.petclinic.util 1
org.springframework.samples.petclinic.service 3
org.springframework.samples.petclinic.model 1
org.springframework.samples.petclinic.repository.jpa 2
org.springframework.samples.petclinic.service 2
org.springframework.samples.petclinic.repository.jdbc 3
org.springframework.samples.petclinic.web 2
org.springframework.samples.petclinic.web 3

There must be no cyclic package dependencies.
MATCH
    (p1:Package)-[:DEPENDS_ON]->(p2:Package),
    path=shortestPath((p2)-[:DEPENDS_ON*]->(p1))
WHERE
    p1<>p2
RETURN
    p1 AS Package, EXTRACT(p IN nodes(path) | p.fqn) AS Cycle
ORDER BY
    Package.fqn

Status: SUCCESS Severity: MAJOR
Empty Result

Labels all types annotated with @javax.persistence.Entity with "Jpa" and "Entity".
MATCH
  (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="javax.persistence.Entity"
SET
  t:Jpa:Entity
RETURN
  t AS JpaEntity

Status: SUCCESS Severity: MINOR
JpaEntity
org.springframework.samples.petclinic.model.Visit
org.springframework.samples.petclinic.model.Pet
org.springframework.samples.petclinic.model.Specialty
org.springframework.samples.petclinic.model.Vet
org.springframework.samples.petclinic.model.PetType
org.springframework.samples.petclinic.model.Owner

All @Ignore annotations must provide a message.
MATCH
  (e)-[:ANNOTATED_BY]->(ignore:Annotation)-[:OF_TYPE]->(ignoreType:Type)
WHERE
  ignoreType.fqn= "org.junit.Ignore"
  AND NOT (ignore)-[:HAS]->(:Value{name:"value"})
RETURN
  e AS IgnoreWithoutMessage

Status: SUCCESS Severity: MAJOR
Empty Result

Finds all test methods (i.e. annotated with "@org.junit.Test") and labels them with "Test" and "Junit4".
MATCH
  (m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.Test"
SET
  m:Test:Junit4
RETURN
  m AS Test

Status: SUCCESS Severity: MINOR
Test
org.springframework.samples.petclinic.web.VisitControllerTests#void testProcessNewVisitFormSuccess()
org.springframework.samples.petclinic.web.VisitControllerTests#void testProcessNewVisitFormHasErrors()
org.springframework.samples.petclinic.web.VisitControllerTests#void testShowVisits()
org.springframework.samples.petclinic.web.VisitControllerTests#void testInitNewVisitForm()
org.springframework.samples.petclinic.web.PetControllerTests#void testProcessUpdateFormHasErrors()
org.springframework.samples.petclinic.web.PetControllerTests#void testProcessUpdateFormSuccess()
org.springframework.samples.petclinic.web.PetControllerTests#void testInitUpdateForm()
org.springframework.samples.petclinic.web.PetControllerTests#void testProcessCreationFormHasErrors()
org.springframework.samples.petclinic.web.PetControllerTests#void testProcessCreationFormSuccess()
org.springframework.samples.petclinic.web.PetControllerTests#void testInitCreationForm()
org.springframework.samples.petclinic.web.VetControllerTests#void testShowVetListHtml()
org.springframework.samples.petclinic.web.VetControllerTests#void testShowResourcesVetList()
org.springframework.samples.petclinic.web.VetControllerTests#void testShowVetListXml()
org.springframework.samples.petclinic.web.PetTypeFormatterTests#void testPrint()
org.springframework.samples.petclinic.web.PetTypeFormatterTests#void shouldParse()
org.springframework.samples.petclinic.web.PetTypeFormatterTests#void shouldThrowParseException()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testInitCreationForm()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessCreationFormHasErrors()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessCreationFormSuccess()
org.springframework.samples.petclinic.web.CrashControllerTests#void testTriggerException()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessUpdateOwnerFormSuccess()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessUpdateOwnerFormHasErrors()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testShowOwner()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testInitFindForm()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessFindFormSuccess()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessFindFormByLastName()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testProcessFindFormNoOwnersFound()
org.springframework.samples.petclinic.web.OwnerControllerTests#void testInitUpdateOwnerForm()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldFindSingleOwnerWithPet()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldFindOwnersByLastName()
org.springframework.samples.petclinic.model.ValidatorTests#void shouldNotValidateWhenFirstNameEmpty()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldFindVisitsByPetId()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldAddNewVisitForPet()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldFindVets()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldUpdatePetName()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldInsertPetIntoDatabaseAndGenerateId()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldFindAllPetTypes()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldFindPetWithCorrectId()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldInsertOwner()
org.springframework.samples.petclinic.service.AbstractClinicServiceTests#void shouldUpdateOwner()