jQA logo

Your Software. Your Structures. Your Rules.

This document describes the concepts of jQAssistant and usage information. To download jQAssistant, go to Get Started.

Overview

jQAssistant is a QA tool which allows the definition and validation of project specific rules on a structural level. It is built upon the graph database Neo4j and can easily be plugged into the build process to automate detection of constraint violations and generate reports about user defined concepts and metrics.

Example use cases:

  • Enforce naming conventions, e.g. EJBs, JPA entities, test classes, packages, maven modules etc.

  • Validate dependencies between modules of your project

  • Separate API and implementation packages

  • Detect common problems like cyclic dependencies or tests without assertions

The rules are expressed in Cypher - the easy-to-learn query language of Neo4j:

MATCH
  (t:Test:Method)
WHERE NOT
  (t)-[:INVOKES]->(:Assert:Method)
RETURN
  t AS TestWithoutAssertion

1. License

jQAssistant is contributed under GNU General Public License, v3.

2. Requirements

  • Java Runtime Environment 8 (64 bit recommended) or later (it is still possible to scan & analyze applications which have been compiled with older Java versions)

  • at least 1GB of RAM

Note
Adjusting memory settings can be achieved by setting the environment variables JQASSISTANT_OPTS (command line) or MAVEN_OPTS (Maven), e.g.
Windows
set JQASSISTANT_OPTS=-Xmx1024M
set MAVEN_OPTS=-Xmx1024M
Linux
export JQASSISTANT_OPTS=-Xmx1024M
export MAVEN_OPTS=-Xmx1024M

3. Quickstart

3.1. Command Line

3.1.1. Requirements

  • Java Development Kit 8 or later

  • the environment variable JQASSISTANT_OPTS should be set to adjust memory settings

Windows
set JQASSISTANT_OPTS=-Xmx1024M
Linux
export JQASSISTANT_OPTS=-Xmx1024M

3.1.2. Installation

  • Download and unpack the distribution, a directory jqassistant-commandline-neo4jvx-version will be created.

3.1.3. Scan

Windows
bin\jqassistant.cmd scan -f lib
Linux
bin/jqassistant.sh scan -f lib
  • The JAR files contained in the lib/ folder will be scanned.

3.1.4. Explore

Windows
bin\jqassistant.cmd server
Linux
bin/jqassistant.sh server
  • Open a browser and navigate to http://localhost:7474

  • Enter the following query in the top level area and hit Ctrl-Enter:

MATCH
  (a:Artifact)-[:CONTAINS]->(t:Type)-[:DECLARES]->(m:Method)
RETURN
  a.fileName as Artifact, t.fqn AS Type, count(t) AS DeclaredMethods
ORDER BY
  DeclaredMethods DESC
LIMIT 20

3.2. Maven

3.2.1. Requirements

  • Maven 3.5 or later

  • Java Development Kit 8 or later

  • the environment variable MAVEN_OPTS must be set to adjust memory settings

Windows
set MAVEN_OPTS=-Xmx1024M
Linux
export MAVEN_OPTS=-Xmx1024M

3.2.2. Add the plugin

Add the following lines to the parent pom.xml file of your project:

<build>
    <plugins>
        <plugin>
            <groupId>com.buschmais.jqassistant</groupId>
            <artifactId>jqassistant-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>scan</goal>
                        <goal>analyze</goal>
                    </goals>
                    <configuration>
                        <failOnSeverity>MAJOR</failOnSeverity>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<!-- Only required if a Maven site is generated -->
<reporting>
    <plugins>
        <plugin>
            <groupId>com.buschmais.jqassistant</groupId>
            <artifactId>jqassistant-maven-plugin</artifactId>
            <reportSets>
                <reportSet>
                    <reports>
                        <report>report</report>
                    </reports>
                </reportSet>
            </reportSets>
        </plugin>
    </plugins>
</reporting>

3.2.3. Add a rule

Within your parent module create a directory jqassistant and a an Asciidoc file my-rules.adoc in it:

jqassistant/my-rules.adoc
= My Project

// Include a summary of all executed rules and their status
link:jQA:Summary[]

[[default]]
[role=group,includesConstraints="my-rules:*"]
== Default Rules

[[my-rules:TestClassName]]
[source,cypher,role=constraint,requiresConcepts="junit4:TestClass"]
----
MATCH
    (t:Junit4:Test:Class)
WHERE NOT
    t.name ends with "Test"
RETURN
    t AS InvalidTestClass
----

== Imported Rules

// Include specific rules that have been executed and their results.
link:jQA:Rules[concepts="junit4:*"]

3.2.4. Run the build

Execute the following command from your parent module:

mvn install

The build will fail with the rule’s message if it is violated.

The HTML report generated from the Asciidoc file including all results is available from target/jqassistant/report/asciidoc/index.html.

3.2.5. Explore your application

jQAssistant comes with an integrated Neo4j server, you can run it using

mvn jqassistant:server
  • Open a browser and navigate to http://localhost:7474

  • Enter the follwoing query in the top level area and hit Ctrl-Enter:

MATCH
  (t:Type)-[:DECLARES]->(m:Method)
RETURN
  t.fqn AS Type, count(t) AS DeclaredMethods
ORDER BY
  DeclaredMethods DESC
LIMIT 20

4. Introduction

This chapter provides an introduction to the concepts of jQAssistant.

4.1. How it works

The basic idea behind jQAssistant is to integrate the following steps into the build process of a software system:

  1. Scan the generated artifacts and store structural information about them into a database

  2. Analyze the structures using rules which are represented by queries

  3. Report violations

jQAssistant itself is a plugin based framework. It comes with a pre-defined set of plugins containing scanners, rules and reports but can be easily extended by custom rules or implementations.

As database an embedded instance of Neo4j Community Edition is managed and used by jQAssistant. This means that no setup or configuration of a dedicated server is required. Neo4j has been chosen because:

  • it is a mature open source graph database

  • it allows easy modelling of structural elements of a software and their relations

  • it comes with a very expressive and easy to learn query language (Cypher)

4.2. Scanner

Scanners are used to import software structures into the database. They are provided by plugins and may support several types of artifacts, e.g. Java classes, XML files or database structures. The jQAssistant framework (including the command line or Maven plugin) only provides the infrastructure to run a scan operation on a set of items, e.g. files, directories or URLs. Every active plugin decides itself if it accepts and imports a given item by checking several conditions, e.g. file name extensions or a provided scope. The latter is an extra information which provides specific context information like "java:classpath" for a directory containing Java classes or "maven:repository" for a URL.

4.3. Rules

Rules are expressed as Cypher queries and are specified either in XML or AsciiDoc files:

4.3.1. XML example

my-rules.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <group id="default">
        <includeConstraint refId="my-rules:MyConstraint"/>
    </group>

    <concept id="my-rules:MyConcept">
        <description>A human readable description of the concept.</description>
        <cypher><![CDATA[
            MATCH
              ...
            WHERE
              ...
            MERGE
              ...
            SET
              ...
            RETURN
              ...
        ]]></cypher>
    </concept>

    <constraint id="my-rules:MyConstraint" severity="blocker">
        <requiresConcept refId="my-rules:MyConcept" />
        <description>A human readable description of the constraint.</description>
        <cypher><![CDATA[
            MATCH
                ...
            WHERE
                ...
            RETURN
                ...
        ]]></cypher>
    </constraint>

</jqassistant-rules>

4.3.2. AsciiDoc example

my-rules.adoc
[[my-rules:MyConcept]]
.A human readable description of the concept.
[source,cypher,role=concept]
----
MATCH
  ...
WHERE
  ...
MERGE
  ...
SET
  ...
RETURN
  ...
----

[[my-rules:MyConstraint]]
.A human readable description of the constraint.
[source,cypher,role=constraint,requiresConcepts="my-rules:MyConcept",severity=blocker]
----
MATCH
  ...
WHERE
  ...
RETURN
  ...
----

[[my-rules:MyGroup]]
.A human readable description of the group.
[role=group,includesConstraints="my-rules:MyConstraint(minor)"]
== My Group

Each rule comes with an unique id (e.g. "my-rules:MyConstraint") which can be referenced by other rules. jQAssistant will take care about executing the rules in the correct order. Furthermore a human readable description shall help developers to understand the rationale behind them.

Tip
Despite rules are usually referenced by their id it is also possible to use the wildcards * and ?. This is especially useful for defining groups and include all constraints that match a specific pattern, e.g. my-rules:*.

4.3.3. Groups

A group is a set of rules (i.e. concepts, constraints or other groups) that shall be executed together by including them with the option to overwrite their default severity. This allows to adjust analysis depth for different types of builds, e.g. a Continuous Integration build (CI) can be configured to only execute rules with low costs (i.e. execution times) whereas a report build is allowed to run for a longer time with more expensive checks.

4.3.4. Concepts

The information created by the scanner represents the structure of a software project on a raw level. Concept rules allow enriching the database with higher level information to ease the process of writing queries that check for violations (i.e. constraints) . This typically means adding labels, properties or relations.

jQAssistant comes with language and framework plugins which include general technical concepts, e.g.

  • "jpa2:Entity" provided by the JPA2 plugin adds a label "Entity" to a node if it represents a class which is annotated by "@javax.persistence.Entity".

  • "java:MethodOverrides" provided by the Java plugin adds a relation "OVERRIDES" between a method of a sub class to the super class methods it overrides.

It is recommended to use concepts to enrich the database with information which is specific for the concrete project, e.g. labels can be added to

  • package nodes representing modules of the application ("Module")

  • package nodes that represent technical layers ("UI", "EJB")

  • class nodes representing elements with a specific role ("Controller", "Model")

Note
Even if the primary intention of a concept is to enrich data it still must provide a return clause. If a concept returns an empty result a warning will be generated by jQAssistant. The rationale is that in such case the concept does not match the structure of the application and other rules which depend on it will probably not work as expected.
Tip
The return clause of the concept shall preferably return a node/relation itself instead of an attribute of it. With this, XML and HTML reports can provide additional information about the concept.

4.3.5. Constraints

A Constraint is a query which detects violations, e.g.

  • classes with specific roles (e.g. entity, controller, etc.) that are either located in the wrong packages or have names that do not fit defined conventions

  • invocations of methods which are deprecated and/or forbidden (e.g. constructors of java.util.Date)

  • dependencies to other modules which are not allowed

A constraint can depend on one or more concepts and usually is referenced by one or more groups.

Note
If a constraint returns a result jQAssistant will report an error including the provided description and information about the returned elements. This information shall help the developer to understand and fix the problem.

4.3.6. Explicit And Implicit Rule Dependencies

As shown in the snippets above concepts or constraints may define dependencies to other concepts using the XML attribute requiresConcept or Asciidoc attribute requiresConcepts. jQAssistant will ensure that these rules are executed in the right order.

There are situations where dependencies between rules cannot be specified explicitly. This is especially the case if a constraint is provided by a plugin that relies on the presence of a specific label. A project specific concept can provide this but it would not be possible to add it to the required concepts of the constraint. In this case the concept may be included within a group that also includes the constraint directly or indirectly within another group. jQAssistant will execute the rules within a group in the following order:

  1. Concepts

  2. Groups (including recursively their concepts, groups and constraints)

  3. Constraints

The approach of relying on the described execution order for rules to manage dependencies between them is limited as an explicitly dependency might change this order, e.g.:

  • a project specific group is defined, including

    • a concept that adds a label "Injectable"

    • a group provided by a plugin (e.g. Spring)

  • the referenced plugin group includes a concept "InjectionPoint" that implicitly relies on the label "Bean"

The setup works under the condition that no other concept (e.g. included in the project specific group) explicitly requires "InjectionPoint".

Tip
For the mentioned reason it is recommend to use explicitly required dependencies between rules if possible. If implicit dependencies cannot be avoided then the requiring and providing rules should be included within a single group hierarchy.

4.3.7. Severity Of Rules

A rule may optionally define the severity level. jQAssistant allows to break the build if there are violations in the configured severity level (or higher). For example, if the severity is set to critical, and if there are violated constraints with blocker and/or critical severity; the build will break. This feature allows projects to pay down their technical debt in an iterative manner.

Following severity levels are supported:

  • info

  • minor (default for concepts)

  • major (default for constraints)

  • critical

  • blocker

There is no default severity for groups. If a severity is specified then it is applied to all included elements where no further severity is given, e.g.

my-rules.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <group id="my-rules:MyGroup" severity="blocker">
        <includeConstraint refId="my-rules:MyConstraint1"/>
        <includeConstraint refId="my-rules:MyConstraint2" severity="minor"/>
    </group>

</jqassistant-rules>

or in Asciidoc:

[[my-rules:MyGroup]]
.A human readable description of the group.
[role=group,severity=blocker,requiresConstraints="my-rules:Constraint1,my-rules:Constraint2(minor)"]
== My Group

Thus execution of the group 'my-rules:MyGroup' will report a violation of constraint…​

  • …​'my-rules-Constraint1' with severity 'blocker' (inherited from the group)

  • …​'my-rules-Constraint2' with severity 'minor' (specified within the group)

4.3.8. Script Languages

Instead of cypher scripting languages like JavaScript, Ruby or Groovy may be used for writing concepts or constraints:

my-scripting-rules.xml
<constraint id="xmlExample:JavaScriptConstraint">
    <description>JavaScript example constraint: returns a result containing the number
        of declared methods for each class.</description>
    <script language="JavaScript">
        // Define the columns returned by the constraint
        var columnNames = java.util.Arrays.asList("Type", "MethodsOfType");
        // Define the list of rows returned by the constraint
        var rows = new java.util.ArrayList();
        // Execute a query using the store
        var typeIterator = store.executeQuery("match (t:Type:Class) return t").iterator();
        while(typeIterator.hasNext()) {
            // Get the next row from the query result
            var typeRow = typeIterator.next();
            // Get the column "t" from the row, it represents a type
            // descriptor as defined by the Java plugin
            var type = typeRow.get("t",
                com.buschmais.jqassistant.plugin.java.api.model.TypeDescriptor.class);
            // Get the declared methods of the type and count them
            var methodIterator = type.getDeclaredMethods().iterator();
            var methodsOfType = 0;
            while( methodIterator.hasNext()) {
                methodIterator.next();
                methodsOfType++;
            }
            // Define the row for the result and put the value for each defined column
            var resultRow = new java.util.HashMap();
            resultRow.put("Class", type);
            resultRow.put("MethodsOfType", methodsOfType);
            rows.add(resultRow);
        }
        // Return the result
        var status = com.buschmais.jqassistant.core.analysis.api.Result.Status.SUCCESS;
        new com.buschmais.jqassistant.core.analysis.api.Result(rule, status, severity, columnNames, rows);
    </script>
</constraint>

or in Asciidoc:

[[asciiDocExample:JavaScriptConstraint]]
.JavaScript example constraint: returns a result containing the number of declared methods for each class.
[source,javascript,role=constraint]
----
// Define the columns returned by the constraint
var columnNames = java.util.Arrays.asList("Type", "MethodsOfType");
// Define the list of rows returned by the constraint
var rows = new java.util.ArrayList();
// Execute a query using the store
var typeIterator = store.executeQuery("match (t:Type:Class) return t").iterator();
while(typeIterator.hasNext()) {
    // Get the next row from the query result
    var typeRow = typeIterator.next();
    // Get the column "t" from the row, it represents a type
    // descriptor as defined by the Java plugin
    var type = typeRow.get("t",
        com.buschmais.jqassistant.plugin.java.api.model.TypeDescriptor.class);
    // Get the declared methods of the type and count them
    var methodIterator = type.getDeclaredMethods().iterator();
    var methodsOfType = 0;
    while( methodIterator.hasNext()) {
        methodIterator.next();
        methodsOfType++;
    }
    // Define the row for the result and put the value for each defined column
    var resultRow = new java.util.HashMap();
    resultRow.put("Class", type);
    resultRow.put("MethodsOfType", methodsOfType);
    rows.add(resultRow);
}
// Return the result
var status = com.buschmais.jqassistant.core.analysis.api.Result.Status.SUCCESS;
new com.buschmais.jqassistant.core.analysis.api.Result(rule, status, severity, columnNames, rows);
----

4.3.9. Rule Parameters

Both concepts and constraints may define required parameters:

my-rules.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <concept id="my-rules:ApplicationRootPackage">
        <requiresParameter name="rootPackage" type="String" defaultValue="com.buschmais"/> (1)
        <description>Labels the root package of the application with "Root".</description>
        <cypher><![CDATA[
           MATCH
             (root:Package)
           WHERE
             root.name = {rootPackage} (2)
           SET
             root:Root
           RETURN
             root
        ]]></cypher>
    </concept>

</jqassistant-rules>
  1. Declaration of a required parameter with a default value.

  2. Reference to a parameter in a Cypher query.

or in Asciidoc:

my-rules.adoc
[[my-rules:my-rules:ApplicationRootPackage]]
.Labels the root package of the application with "Root".
[role=group,role=concept,requiresParameters="String rootPackage; int limit"] (1)
----
MATCH
  (root:Package)
WHERE
  root.name = {rootPackage} (2)
SET
  root:Root
RETURN
  root
----
  1. requiresParameters is a list of parameter declarations separated by ;

  2. Reference to a parameter in a Cypher query.

The following parameter types are supported:

  • char

  • byte

  • short

  • int

  • long

  • float

  • double

  • boolean

  • String

The values for the required parameters must be provided by the execution context, e.g. the jQAssistant Maven plugin or the command line utility. A rule may specify a default value which is used if no concrete value is provided for an execution.

Note
Default values are currently not supported for rules in Asciidoc files.

For rules expressed in Cypher the parameters are referenced by {…​} placeholders. For scripts the values are passed as parameters, i.e. they may be used directly in the code.

4.3.10. Result verification

The default strategy (rowCount) verifies a result of a concept or constraint by counting the number of returned rows, i.e.

  • a concept is valid if it returns at least one row

  • a constraint is valid if it returns no row

This behavior can be customized by specifing min and max thresholds:

<constraint id="my-rules:MyConstraint">
    <description>A human readable description of the constraint.</description>
    <cypher><![CDATA[
        MATCH
          (n)
        WHERE
          ...
        RETURN
          n as Element
    ]]></cypher>
    <verify>
        <rowCount max="20"/>
    </verify>
</concept>
[[my-rules:MyConstraint]]
.A human readable description of the constraint.
[source,cypher,role=constraint,rowCountMax=20]
----
MATCH
  (n)
WHERE
  ...
RETURN
  n as Element
----

It is also possible to verify aggregated results reported as numeric values in a column, e.g.

<concept id="my-rules:MyConstraint">
    <description>A human readable description of the constraint.</description>
    <cypher><![CDATA[
        MATCH
          (n)
        WHERE
          ...
        RETURN
          count(n) as Count
    ]]></cypher>
    <verify>
        <aggregation column="Count" max="20"/>
    </verify>
</concept>
[[my-rules:MyConstraint]]
.A human readable description of the constraint.
[source,cypher,role=constraint,verify=aggregation,aggregationMax=20,aggregationColumn="Count"]
----
MATCH
  (n)
WHERE
  ...
SET
  ...
RETURN
  count(n) as Count
----
  • For each returned row the value of the column "Count" will be verified following the same principles as described above

  • The rule fails if at least one returned row does not match the expected result

  • The attribute column/aggregationColumn can be omitted, in this case the first column of the result is evaluated

  • Similar to the row count verification the attributes min/aggregationMin and max/aggregationMax can be specified for individual thresholds

4.3.11. Report

A rule may select a specific report plugin and pass properties to it:

<concept id="my-rules:MyConcept">
    <description>A human readable description of the concept.</description>
    <cypher><![CDATA[
        MATCH
          (m)-[]->(n)
          ...
        RETURN
          m, n
    ]]></cypher>
    <report reportType="myReport">
        <property name="key">value</property>
    </report>
</concept>
[[my-rules:MyConcept]]
.A human readable description of the concept.
[source,cypher,role=concept,reportType="myReport",reportProperties="key1=value1;key2=value2"]
----
    MATCH
      (m)-[]->(n)
      ...
    RETURN
      m, n
----
4.3.11.1. Primary Column

If a rule reports more than one column it might be necessary to specify the column which contains the primary element the rule refers to, e.g. the Java class. The information may be evaluated by reporting tools, e.g. for creating issues in SonarQube:

<concept id="my-rules:MyConcept">
    <description>A human readable description of the concept.</description>
    <cypher><![CDATA[
        MATCH
          (m)-[]->(n)
          ...
        RETURN
          m, n
    ]]></cypher>
    <report primaryColumn="n" />
</concept>
[[my-rules:MyConcept]]
.A human readable description of the concept.
[source,cypher,role=concept,primaryReportColumn="n"]
----
    MATCH
      (m)-[]->(n)
      ...
    RETURN
      m, n
----
Note
The first column will be used automatically if no primary column is explicitly specified.

5. Command Line

Shell scripts are provided for executing jQAssistant from the command line of Microsoft Windows® or Unix compatible systems. They are located in the bin/ directory of the distribution:

  • jqassistant.cmd

  • jqassistant.sh

The command line accepts tasks and their specific options:

jqassistant.sh <task1> <task2> <task3> -<option1> -<option2>

The following example will scan the content of the directories classes/ and test-classes/:

jqassistant.sh scan -f classes,test-classes

5.1. Tasks

5.1.1. scan

5.1.1.1. Description

Scans files or directories and stores the gathered information in database. Files or URLs are accepted and may be specified further by scopes, e.g.

jqassistant.sh scan -f lib/,plugins/
jqassistant.sh scan -f java:classpath::classes/
jqassistant.sh scan -u http://host/artifact.jar
jqassistant.sh scan -u http://user:secret@host/artifact.jar
jqassistant.sh scan -u maven:repository::http://my.maven.repository
5.1.1.2. Options
  • -storeUri <uri>

  • -storeUsername <username>

  • -storePassword <password>

  • -f [<scope>::]<file1>,[<scope>::]<file2> or --files [<scope>::]<file1>,[<scope>::]<file2>

    • specifies a list of files or directories to scan

    • a scope may be used as prefix for each file argument

  • -u [<scope>::]<url1>,[<scope>::]<url2> or --urls [<scope>::]<url1>,[<scope>::]<url2>

    • specifies a list of URLs to scan

    • a scope may be used as prefix for each url argument

  • -reset

    • reset the database before scanning

  • -continueOnError

    • continue scanning even if a plugin fails with an unrecoverable error

Note
Using -continueOnError might create inconsistent data. Any reported errors should be reported to the plugin developer.

5.1.2. available-scopes

5.1.2.1. Description

List all available scopes which may be specified for scanning.

5.1.3. analyze

5.1.3.1. Description

Executes an analysis.

5.1.3.2. Options

5.1.4. available-rules

5.1.4.1. Description

List all available rules.

5.1.5. effective-rules

5.1.5.1. Description

List the rules which would be executed for an analysis and the given concepts, constraints or groups.

5.1.6. report

5.1.6.1. Description

Transforms an XML report into HTML.

5.1.6.2. Options

5.1.7. server

5.1.7.1. Description

Starts the integrated Neo4j web server.

  • -embeddedListenAddress <address>

    • specifies the binding address for the server (default: localhost)

  • -embeddedHttpPort <port>

    • specifies the HTTP binding port for the server (default: 7474)

  • -embeddedBoltPort <port>

    • specifies the BOLT binding port for the server (default: 7687)

  • -daemon

    • terminate the server using <Ctrl-C> instead of waiting for standard input (allows to run the server on a machine as a background process / service)

5.1.8. Common options

5.1.8.1. -s, --storeDirectory <directory>
  • specifies the location of the database to use

  • default: './jqassistant/store'

  • Deprecated: use -storeUri <uri> instead

5.1.8.2. -storeUri <uri>
  • specifies the URI of the database to use, for remote databases 'bolt://localhost:7687'

  • default: 'file:jqassistant/store'

5.1.8.3. -storeUsername <username>
  • specifies the user name for authentication against remote databases

5.1.8.4. -storePassword <password>
  • specifies the password for authentication against remote databases

5.1.8.5. -groups <group1>,<group2>
  • specifies the ids of the groups to be executed

  • default: 'default'

5.1.8.6. -concepts <concept1>,<concept2>
  • specifies the ids of the concepts to be applied

5.1.8.7. -constraints <constraint1>,<constraint2>
  • specifies the ids of the constraints to be validated

5.1.8.8. -defaultConceptSeverity
  • specifies the default severity of concepts without an explicit severity

  • default: 'minor'

5.1.8.9. -defaultConstraintSeverity
  • specifies the default severity of constraints without an explicit severity

  • default: 'major'

5.1.8.10. -defaultGroupSeverity
  • specifies the default severity of groups without an explicit severity

  • default: 'none'

5.1.8.11. -r, --ruleDirectory <directory>
  • specifies the directory where rule files are located

  • default: './jqassistant/rules'

5.1.8.12. -rulesUrl <url>
  • specifies the URL of a file containing rules

  • this option is exclusive, i.e. it will disable loading rules from plugins or rule directories

5.1.8.13. -reportDirectory
  • specifies the directory where reports (XML, HTML) will be stored

  • default: './jqassistant/report'

6. Maven Plugin

jQAssistant provides a plugin for Apache Maven which can be used to provide either fully automated scanning and analysis during the build process or manual execution from a command line.

6.1. Setup

6.1.1. Project Scope

Software projects often consist of several modules which are assembled to executable or deployable artifacts. In a Maven project, these modules are usually organized hierarchically with a common parent module which is referenced directly or indirectly by all sub-modules. For each project, jQAssistant uses a separate database with its own set of rules. Thus if a goal is executed within a Maven structure jQAssistant first determines the project scope, i.e. the root module, by searching within the tree starting from the current module following the parent relation until either a module is found where a directory "jqassistant/" exists or no parent is defined. The determined root module defines the location of

  • the set of rules to apply (from the directory "jqassistant/")

  • the database, default "{project.build.directory}/jqassistant/store"

  • the generated native report, default: "{project.build.directory}/jqassistant/jqassistant-report.xml")

  • and the generated HTML report, default "{project.build.directory}/site/jqassistant.html")

The following examples demonstrate different scenarios, the root modules as detected by jQAssistant are marked using asterisks.

Single project consisting of two modules
root*
   |-pom.xml
   |
   |-jqassistant
   |           |-rules.xml
   |
   |-module1
   |       |-pom.xml
   |
   |-module2
           |-pom.xml
Multiple projects, each consisting of two modules
root
   |-pom.xml
   |
   |-project1*
   |        |-jqassistant
   |        |           |-rules1.xml
   |        |
   |        |-pom.xml
   |        |-module1
   |        |       |-pom.xml
   |        |
   |        |-module2
   |                |-pom.xml
   |
   |-project2*
            |-jqassistant
            |           |-rules2.xml
            |-pom.xml
            |-module1
            |       |-pom.xml
            |
            |-module2
                    |-pom.xml
Note
The described mechanism is designed to work for Maven module structures which are organized in hierarchies with consistent parent relations. For other setups, it is possible to enforce using the module where the mvn goal is invoked as root module by setting the configuration option useExecutionRootAsProjectRoot (-Djqassistant.useExecutionRootAsProjectRoot).

6.1.2. Plugin Configuration

The jQAssistant Maven plugin must be configured in the pom.xml of the root module, it should not be overwritten by sub-modules.

Setup of the jQAssistant Maven plugin including supported configuration options.
<project ...>
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>com.buschmais.jqassistant</groupId>
                <artifactId>jqassistant-maven-plugin</artifactId>
                <version>1.8.0</version>
                <executions>
                    <execution>
                        <!-- The id "cli-default" is used to allow execution of the goals with the given configuration from the command line -->
                        <id>cli-default</id>
                        <goals>
                            <goal>scan</goal>
                            <goal>analyze</goal>
                        </goals>
                        <!--
                        <extensions>false</extensions>
                        -->
                        <configuration>
                        <!-- Store/Database -->
                            <!--
                            <store>
                                <uri>file:target/jqassistant/store</uri>
                                <username></username>
                                <password></password>
                                <embedded>
                                  <listenAddress>localhost</listenAddress>
                                  <httpPort>7474</httpPort>
                                  <boltPort>7474</boltPort>
                                </embedded>
                            </store>
                            <storeLifecycle>REACTOR</storeLifecycle>
                            <resetStore>true</resetStore>
                             -->

                        <!-- Scan -->
                            <!--
                            <scanIncludes>
                                <scanInclude>
                                    <path>config</path>
                                </scanInclude>
                                <scanInclude>
                                    <path>${project.build.directory}/extra-classes</path>
                                    <scope>java:classpath</scope>
                                </scanInclude>
                                <scanInclude>
                                    <url>https://repo1.maven.org/maven2</path>
                                    <scope>maven:repository</scope>
                                </scanInclude>
                            </scanIncludes>
                            <scanProperties>
                                <customScanner.property>value</customScanner.property>
                            </scanProperties>
                            <continueOnError>false</continueOnError>
                            -->

                        <!-- Analysis configuration -->
                            <!--
                            <warnOnSeverity>MINOR</warnOnSeverity>
                            <failOnSeverity>MAJOR</failOnSeverity>
                            <concepts>
                                <concept>junit4:TestClass</concept>
                            </concepts>
                            <constraints>
                                <constraint>junit4:TestMethodWithoutAssertion</constraint>
                            </constraints>
                            <groups>
                                <group>default</group>
                            </groups>
                            <ruleParameter>
                                <myRuleParameter>com.buschmais</myRuleParameter>
                            </ruleParameters>
                            <rule>
                                <defaultConceptSeverity>MINOR</defaultConceptSeverity>
                                <defaultConstraintSeverity>MAJOR</defaultConstraintSeverity>
                                <defaultGroupSeverity></defaultGroupSeverity>
                            </rule>
                            <rulesDirectory>jqassistant</rulesDirectory>
                            <rulesDirectories>
                                <rulesDirectory>${project.build.directory}/generated-rules</rulesDirectory>
                            </rulesDirectories>
                            -->

                        <!-- Report -->
                            <!--
                            <reportProperties>
                                <customReport.fileName>
                                    ${project.build.directory}/customReport.txt
                                </customReport.fileName>
                            </reportProperties>
                            <xmlReportFile>${project.build.directory}/jqassistant/jqassistant-report.xml</xmlReportFile>
                            -->

                        <!-- Misc -->
                            <!--
                            <skip>false</skip>
                            <useExecutionRootAsProjectRoot>false</useExecutionRootAsProjectRoot>
                            -->
                         </configuration>
                    </execution>
                </executions>
                <!-- Plugins are declared as dependencies of the Maven plugin -->
                <!--
                <dependencies>
                    <dependency>
                        <groupId>org.jqassistant.contrib.plugin</groupId>
                        <artifactId>jqassistant-test-impact-analysis-plugin</artifactId>
                        <version>1.0.0</version>
                    </dependency>
                </dependencies>
                -->
            </plugin>
        </plugins>
    </build>

    <!-- The following section is only required if a Maven site shall be generated including a jQAssistant report -->
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>
            <plugin>
                <groupId>com.buschmais.jqassistant</groupId>
                <artifactId>jqassistant-maven-plugin</artifactId>
                <version>1.8.0</version>
                <reportSets>
                    <reportSet>
                        <reports>
                            <report>report</report>
                        </reports>
                    </reportSet>
                </reportSets>
            </plugin>
        </plugins>
    </reporting>
    ...
</project>

6.1.3. Command Line

Goals may also be executed from the command line:

mvn ${project.groupId}:${project.artifactId}:available-rules

Adding the following lines to the file settings.xml (usually located in the $HOME/.m2) eases execution of jQAssistant goals from the command line:

<pluginGroups>
    <pluginGroup>com.buschmais.jqassistant</pluginGroup>
</pluginGroups>

The same goal can now be executed using the following command line statement:

mvn jqassistant:available-rules

6.2. Goals

6.2.1. jqassistant:scan

6.2.1.1. Description

Scans the project directories according to the given configuration (e.g. compiled classes and test classes) and stores the gathered information in the database.

6.2.1.2. Configuration
Warning
Using 'continueOnError' might create inconsistent data. Any reported errors should be reported to the plugin developer.

6.2.2. jqassistant:available-scopes

6.2.2.1. Description

List all available scopes which may be specified for scanInclude properties.

6.2.3. jqassistant:reset

6.2.3.1. Description

Resets the database by deleting all nodes and relationships.

6.2.4. jqassistant:server

6.2.4.1. Description

Starts the integrated Neo4j web server (default address: http://localhost:7474).

6.2.5. jqassistant:analyze

6.2.5.1. Description

Executes an analysis.

6.2.5.2. Configuration

6.2.8. jqassistant:report

6.2.8.1. Description

Transforms the XML report into HTML (i.e. for generating a Maven site).

6.3. Common Configuration Properties

6.3.1. Execution

6.3.1.1. skip (-Djqassistant.skip)
  • skip execution of the plugin

  • default: 'false'

6.3.1.2. useExecutionRootAsProjectRoot (-Djqassistant.useExecutionRootAsProjectRoot)
  • force the module where 'mvn' is being executed to be used as root module

  • default: 'false'

6.3.2. Store

6.3.2.1. store
  • specifies the configuration of the database to use

  • uri

    • URI of the database, supported URI schemes are

    • 'file' for embedded databases, e.g. 'file:target/mystore'

    • 'bolt' (experimental) for connecting to a running Neo4j instance (3.x+), e.g. 'bolt://localhost:7687'

  • username

    • username ('bolt' connections only)

  • password

    • password ('bolt' connections only)

  • default: use embedded database at 'file:{rootModule}/target/jqassistant/store'

  • embedded

6.3.2.2. embedded
  • the configuration of the embedded Neo4j store

  • listenAddress (-Djqassistant.embedded.listenAddress)

    • the listen address to use for opening BOLT/HTTP connections

    • default: localhost

  • httpPort (-Djqassistant.embedded.httpPort)

    • the HTTP port to be used by the Neo4j server

    • default: 7474

  • boltPort (-Djqassistant.embedded.boltPort)

    • the BOLT port to be used by the Neo4j server

    • default: 7687

6.3.2.3. storeDirectory (-Djqassistant.store.directory)
  • specifies the location of the database, either a relative path to the root module directory or an absolute path

  • default: '{rootModule}/target/jqassistant/store'

6.3.2.4. storeLifecycle (-Djqassistant.store.lifecycle)
  • specifies the lifecycle of the data store

    • 'REACTOR': cache the store for the execution time of the reactor for fast execution

    • 'MODULE': open and close the store for each module, slower but required for maven reactors containing extensions

  • default: 'REACTOR'

6.3.3. Analysis And Report

6.3.3.1. concepts (-Djqassistant.concepts)
  • specifies the ids of the concepts to be applied

6.3.3.2. constraints (-Djqassistant.constraints)
  • specifies the ids of the constraints to be validated

6.3.3.3. groups (-Djqassistant.groups)
  • specifies the ids of the groups to be executed

  • default: 'default'

6.3.3.4. rule
  • specifies rule-related settings

  • defaultConceptSeverity

    • the default severity of concepts without an explicit severity

    • default: 'MINOR'

  • defaultConstraintSeverity

    • the default severity of constraints without an explicit severity

    • default: 'MAJOR'

  • defaultGroupSeverity

    • the default severity of groups without an explicit severity

    • default: none

6.3.3.5. rulesDirectory (-Djqassistant.rules.directory)
  • specifies the name of the directory which contains rules

  • this directory is also used to identify the root module of a project, see Project Scope

  • default: 'jqassistant'

6.3.3.6. rulesDirectories (-Djqassistant.rules.directories)
  • specifies a list of directory names relative to the root module containing additional rules

6.3.3.7. rulesUrl <url> (-Djqassistant.rules.url)
  • specifies the URL of a file containing rules

  • this option is exclusive, i.e. it will disable loading rules from plugins or rule directories

6.3.3.8. xmlReportFile (-Djqassistant.report.xml)
  • specifies the target file for writing the XML report

  • default: '{rootModule}/target/jqassistant/jqassistant-report.xml'

7. Plugins

This section provides detailed descriptions of all distributed plugins.

7.1. Asciidoc Report Plugin

Renders Asciidoc files containing rules to HTML reports including results as tables, diagrams or links to external files.

7.1.1. Asciidoc Report

The plugin records the results of executed rules (i.e. concepts and constraints). At the end of the analysis phase Asciidoctor is used for rendering the input documents providing the rules to HTML documents. The listings containing rules are identified and their status and results appended. Furthermore include directives are provided for embedding a summary about executed and imported rules.

By default all rule files with the name index.adoc will be selected for rendering. The report properties asciidoc.report.rule.directory and asciidoc.report.file.include may be used to explicitly select files.

7.1.1.1. Include Directives

The report may be enhanced by jQA include directives:

jQA:Summary[concepts="…​",importedConcepts="…​",constraints="…​",importedConstraints="…​"]

Includes two summary tables containing executed rules, their description, status and severity. The filter attributes are optional, if none is given all results are included. concepts and constraints refer to rules that are defined in the rendered Asciidoc document(s). importedConcepts and importedConstraints refer to rules that are imported from plugins.

jQA:Rules[concepts="…​",constraints="…​"]

Embeds imported rules and their results identified by the specified filters. Both filter attributes are optional but at least one must be specified.

jQA:ImportedRules[]

Deprecated Renders descriptions for all imported rules which have been executed but which are not part of the document itself (i.e. provided by plugins).

Tip
Filter attributes are comma separated lists of id patterns and may contain wildcards, e.g. "layer:*, spring-*:*".
jqassistant/index.adoc
= My Project

This document describes architectural and design rules for My Project.

== Summary

include::jQA:Summary[]

[[default]]
[role=group,includesGroups="..."]
== Project Specific Concepts & Constraints

...
project specific rules
...

== Common Spring Concepts & Constraints

include::jQA:Rules[concepts="spring*:*",constraints="spring*:*"]
7.1.1.2. Configuration

The Asciidoc Report plugin accepts several options that might be passed as report properties to jQAssistant:

Property Description Default

asciidoc.report.directory

Specifies the directory where the HTML files will be written

jqassistant/report/asciidoc

asciidoc.report.rule.directory

Specifies the directory where the Asciidoc files are located (optional)

asciidoc.report.file.include

A comma separated list of filter of Asciidoc files to be included (optional)

asciidoc.report.file.exclude

A comma separated list of filter of Asciidoc files to be excluded (optional)

7.1.2. PlantUML Report

The plugin provides support for generating the following diagrams from rule results:

Note
This feature is based on PlantUML which itself relies on Graphviz. The latter needs to be installed and the dot executable must be present on the system path.
7.1.2.1. Component Diagrams

To activate component diagram rendering the report type must be set to plantuml-component-diagram. The result of the rule simply needs to return all required nodes and their relationships:

jqassistant/index.adoc
[[DependencyDiagram]]
[source,cypher,role=concept,requiresConcepts="dependency:Package",reportType="plantuml-component-diagram"] // (1)
.Creates a diagram about dependencies between packages containing Java types (test artifacts are excluded).
----
MATCH
  (artifact:Main:Artifact)-[:CONTAINS]->(package:Package)-[:CONTAINS]->(:Type)
OPTIONAL MATCH
  (package)-[dependsOn:DEPENDS_ON]->(:Package)
RETURN
  package, dependsOn                                                                                           // (2)
----

(1) The report type is set to plantuml-component-diagram. (2) The packages are returned as nodes and their dependencies (dependsOn) as relationships.

The result might also specify graph-alike structures which will be rendered as PlantUML folders. The following example therefore uses a modified return clause:

jqassistant/index.adoc
[[DependencyPerArtifactDiagram]]
[source,cypher,role=concept,requiresConcepts="dependency:Package",reportType="plantuml-component-diagram"]
.Creates a diagram about dependencies between packages containing Java types (per artifact, test artifacts are excluded).
----
MATCH
  (artifact:Main:Artifact)-[:CONTAINS]->(package:Package)-[:CONTAINS]->(:Type)
OPTIONAL MATCH
  (package)-[dependsOn:DEPENDS_ON]->(:Package)
RETURN
  {                                   // (1)
    role : "graph",                   // (2)
    parent : artifact,                // (3)
    nodes : collect(package),         // (4)
    relationships: collect(dependsOn) // (5)
  }
----
  1. Instead of nodes and relations a map-like structure is returned

  2. role determines that the map shall be interpreted as graph containing nodes and relationships

  3. parent specifies the node that shall be rendered as folder, i.e. the container of nodes

  4. nodes are the nodes to be included in the folder

  5. relationships are the relationships between the nodes, they may reference nodes of other parents/folders

7.1.2.2. Class Diagrams

To activate class diagram rendering the report type must be set to plantuml-class-diagram. The result may contain any of the following elements:

  • Packages (:Java:Package)

  • Types (:Java:Type)

  • Members (:Java:Member, :Java:Field, :Java:Method)

  • Inheritance relations between types (:EXTENDS, :IMPLEMENTS)

  • any other type relations (rendered as associations)

jqassistant/index.adoc
[[ClassDiagram]]
[source,cypher,role=concept,requiresConcepts="java:InnerType",reportType="plantuml-class-diagram"]
.Creates a class diagram.
----
MATCH
  (p:Package)-[:CONTAINS]->(t:Type)-[:DECLARES]->(m:Member) (1)
WHERE NOT
  t:Inner
OPTIONAL MATCH
  (t)-[e:EXTENDS|IMPLEMENTS]->(:Type)                       (2)
OPTIONAL MATCH
  (t)-[d:DEPENDS_ON]->(:Type)                               (3)
RETURN
  *
----
  1. Matches Java packages, types and their declared members

  2. Optionally include super classes and implemented interfaces

  3. Optionally include any dependencies, rendered as associations

7.1.2.3. Sequence Diagrams

To activate sequence diagram rendering the report type must be set to plantuml-sequence-diagram. The result of the rule must return a column sequence containing a path-structure:

jqassistant/index.adoc
[[SequenceDiagram]]
[source,cypher,role=concept,reportType="plantuml-sequence-diagram"]
.Creates a sequence diagram.
----
MATCH
  (type:Type{name:"MyService"})-[:DECLARES]->(root:Method{signature:"void doSomething()"}),
  sequence=(root)-[:INVOKES*]->(:Method)
RETURN
  sequence (1)
----
  1. The sequence to convert to a diagram

Note
The sequence diagram is sensitive to the order of participants and messages. The diagram rendering algorithm therefore relies on a depth-first result structure as provided by the path function. All elements are rendered in the order of their first occurrence.

If a path cannot be returned directly the result may provide the columns participants (nodes) and messages (relationships):

jqassistant/index.adoc
[[SequenceDiagram]]
[source,cypher,role=concept,reportType="plantuml-sequence-diagram"]
.Creates a sequence diagram.
----
MATCH
  (type:Type{name:"MyService"})-[:DECLARES]->(root:Method{signature:"void doSomething()"}),
  sequence=(root)-[:INVOKES*]->(:Method)
RETURN
  nodes(sequence) as participants      (1)
  relationships(sequence) as messages  (2)
----
  1. The list of participants

  2. The list of messages exchanged between the participants

7.1.2.4. Configuration

The PlantUML Report plugin accepts several options that might be passed as report properties to jQAssistant:

Property Description Default

plantuml.report.format

Specifies the output file format of the generated PlantUML-Diagrams (optional)

SVG

plantuml.report.rendermode

Specifies the renderer used for the generated PlantUML-Diagrams, currently supporting GraphViz and Jdot (optional)

GRAPHVIZ

7.2. CDI Plugin

Provides rules for CDI.

7.2.1. Scanner for beans.xml files

Imports bean descriptors from META-INF/beans.xml or WEB-INF/beans.xml files.

7.2.1.1. Nodes labeled with :File:Cdi:Beans

Represents a beans.xml file.

Table 1. Properties of :File:Cdi:Beans
Name Description

fileName

The file name

version

The version of the CDI specification this descriptor represents, e.g. 1.0

beanDiscoveryMode

The bean discovery mode, i.e. all, annotated or none

Table 2. Relations of :File:Cdi:Beans
Name Target label(s) Cardinality Description

HAS_INTERCEPTOR

Nodes labeled with :Java:Type

0..n

References an interceptor type which is activated

HAS_DECORATOR

Nodes labeled with :Java:Type

0..n

References a decorator type which is activated

HAS_ALTERNATIVE

Nodes labeled with :Java:Type

0..n

References an alternative type (class or stereotype annotation) which is activated

7.2.2. Rules provided by the CDI plugin

7.2.2.1. Concepts provided by the CDI plugin
7.2.2.1.1. Concept cdi:Alternative

Labels all types annotated by @javax.enterprise.inject.Alternative with "Cdi" and "Alternative".

MATCH
  (alternative:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(alternativeType:Type)
WHERE
  alternativeType.fqn="javax.enterprise.inject.Alternative"
SET
  alternative:Cdi:Alternative
RETURN
  alternative AS Alternative
7.2.2.1.2. Concept cdi:Any

Labels all elements annotated by "javax.enterprise.inject.Any" with "Cdi" and "Any".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(anyType:Type)
WHERE
  anyType.fqn = "javax.enterprise.inject.Any"
SET
  e:Cdi:Any
RETURN
  e AS Any
7.2.2.1.3. Concept cdi:ApplicationScoped

Labels all beans, fields or methods annotated by @javax.enterprise.context.ApplicationScoped with "Cdi" and "ApplicationScoped".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(scopeType:Type)
WHERE
  (e:Type or e:Method or e:Field)
  and scopeType.fqn="javax.enterprise.context.ApplicationScoped"
SET
  e:Cdi:ApplicationScoped
RETURN
  e AS ApplicationScopedElement
7.2.2.1.4. Concept cdi:ConversationScoped

Labels all beans, fields or methods annotated by @javax.enterprise.context.ConversationScoped with "Cdi" and "ConversationScoped".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(scopeType:Type)
WHERE
  (e:Type or e:Method or e:Field)
  and scopeType.fqn="javax.enterprise.context.ConversationScoped"
SET
  e:Cdi:ConversationScoped
RETURN
  e AS ConversationScopedElement
7.2.2.1.5. Concept cdi:Decorator

Labels all types annotated by @javax.decorator.Decorator with "Cdi" and "Decorator".

MATCH
  (decorator:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(decoratorType:Type)
WHERE
  decoratorType.fqn="javax.decorator.Decorator"
SET
  decorator:Cdi:Decorator
RETURN
  decorator AS Decorator

Required concepts:

7.2.2.1.6. Concept cdi:Default

Labels all elements annotated by "javax.enterprise.inject.Default" with "Cdi" and "Default".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(defaultType:Type)
WHERE
  defaultType.fqn = "javax.enterprise.inject.Default"
SET
  e:Cdi:Default
RETURN
  e AS Default
7.2.2.1.7. Concept cdi:Delegate

Labels all fields annotated annotated by @javax.decorator.Delegate with "Cdi" and "Delegate".

MATCH
  (delegate:Field)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(delegateType:Type)
WHERE
  delegateType.fqn="javax.decorator.Delegate"
SET
  delegate:Cdi:Delegate
RETURN
  delegate AS Delegate
7.2.2.1.8. Concept cdi:Dependent

Labels all beans, fields or methods annotated by @javax.enterprise.context.Dependent with "Cdi" and "Dependent".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(scopeType:Type)
WHERE
  (e:Type or e:Method or e:Field)
  and scopeType.fqn="javax.enterprise.context.Dependent"
SET
  e:Cdi:Dependent
RETURN
  e AS DependentElement
7.2.2.1.9. Concept cdi:Disposes

Creates a relation DISPOSES between a parameter and its type if the parameter is annotated by @javax.enterprise.inject.Disposes.

MATCH
  (:Type)-[:DECLARES]->(disposeMethod:Method)-[:HAS]->(parameter:Parameter),
  (parameter)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(disposesType:Type),
  (parameter)-[:OF_TYPE]->(type)
WHERE
  disposesType.fqn="javax.enterprise.inject.Disposes"
CREATE UNIQUE
  (parameter)-[:DISPOSES]->(type)
RETURN
  disposeMethod AS DisposeMethod
7.2.2.1.10. Concept cdi:EventConsumer

Labels all beans declaring method that has parameter of type "javax.enterprise.event.Observes" with "Cdi" and "EventConsumer".

MATCH
  (a:Type)-[:DECLARES]->(member:Method)-[:HAS]->(param:Parameter),
  (param)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(injectType:Type)
WHERE
  injectType.fqn = "javax.enterprise.event.Observes"
SET
  a:Cdi:EventConsumer
RETURN
  DISTINCT a.fqn AS cdiEventConsumer

Required concepts:

7.2.2.1.11. Concept cdi:EventProducer

Labels all beans declaring "InjectionPoint" of type "javax.enterprise.event.Event" with "Cdi" and "EventProducer".

MATCH
  (a:Type)-[:DECLARES]->(member:Field:Cdi:InjectionPoint),
  (member)-[:OF_TYPE]->(injectType:Type)
WHERE
  injectType.fqn = "javax.enterprise.event.Event"
SET
  a:Cdi:EventProducer
RETURN
  DISTINCT a.fqn AS cdiEventProducers

Required concepts:

7.2.2.1.12. Concept cdi:InjectionPoint

Labels all fields or methods annotated by @javax.inject.Inject with "Cdi" and "InjectionPoint".

MATCH
  (:Type)-[:DECLARES]->(member),
  (member)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(injectType:Type)
WHERE
  (member:Field or member:Method)
  and injectType.fqn="javax.inject.Inject"
SET
  member:Cdi:InjectionPoint
RETURN
  member AS InjectionPoint
7.2.2.1.13. Concept cdi:Named

Labels all types or methods annotated by "javax.inject.Named" with "Cdi" and "Named".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(namedType:Type)
WHERE
  namedType.fqn = "javax.inject.Named"
SET
  e:Cdi:Named
RETURN
  e AS Named
7.2.2.1.14. Concept cdi:New

Labels all elements annotated by "javax.enterprise.inject.New" with "Cdi" and "New".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(newType:Type)
WHERE
  newType.fqn = "javax.enterprise.inject.New"
SET
  e:Cdi:New
RETURN
  e AS New
7.2.2.1.15. Concept cdi:Produces

Creates a relation PRODUCES between a field and its type or a method and its return type if the parameter is annotated by @javax.enterprise.inject.Disposes.

MATCH
  (:Type)-[:DECLARES]->(member),
  (member)-[:OF_TYPE|RETURNS]->(type),
  (member)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(producesType:Type)
WHERE
  (member:Field or member:Method)
  and producesType.fqn="javax.enterprise.inject.Produces"
CREATE UNIQUE
  (member)-[:PRODUCES]->(type)
RETURN
  member AS Producer
7.2.2.1.16. Concept cdi:Qualifier

Labels all annotation types annotated by @javax.inject.Qualifier with "Cdi" and "Qualifier" and adds the labels "Cdi" and "Nonbinding" to all non-binding annotation values (i.e. which are annotated by @javax.enterprise.util.Nonbinding).

MATCH
  (qualifier:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(qualifierType:Type)
WHERE
  qualifierType.fqn = "javax.inject.Qualifier"
SET
  qualifier:Cdi:Qualifier
WITH
  qualifier
MATCH
  (qualifier)-[:DECLARES]->(attribute:Method),
  (attribute)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(nonbindingType:Type)
WHERE
  nonbindingType.fqn = "javax.enterprise.util.Nonbinding"
SET
  attribute:Cdi:Nonbinding
RETURN
  distinct qualifier AS Qualifier
7.2.2.1.17. Concept cdi:RequestScoped

Labels all beans, fields or methods annotated by @javax.enterprise.context.RequestScoped with "Cdi" and "RequestScoped".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(scopeType:Type)
WHERE
  (e:Type or e:Method or e:Field)
  and scopeType.fqn="javax.enterprise.context.RequestScoped"
SET
  e:Cdi:RequestScoped
RETURN
  e AS RequestScopedElement
7.2.2.1.18. Concept cdi:SessionScoped

Labels all beans, fields or methods annotated by @javax.enterprise.context.SessionScoped with "Cdi" and "SessionScoped".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(scopeType:Type)
WHERE
  (e:Type or e:Method or e:Field)
  and scopeType.fqn="javax.enterprise.context.SessionScoped"
SET
  e:Cdi:SessionScoped
RETURN
  e AS SessionScopedElement
7.2.2.1.19. Concept cdi:SingletonScoped

Labels all beans annotated by @javax.inject.Singleton with "Cdi" and "SingletonScoped".

MATCH
  (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn = "javax.inject.Singleton"
SET
  t:Cdi:SingletonScoped
RETURN
  t AS cdiSingleton
7.2.2.1.20. Concept cdi:Specializes

Labels all types and methods annotated by @javax.enterprise.inject.Specializes with "Cdi" and "Specializes".

MATCH
  (specializes)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(specializesType:Type)
WHERE
  (specializes:Type or specializes:Method)
  and specializesType.fqn="javax.enterprise.inject.Specializes"
SET
  specializes:Cdi:Specializes
RETURN
  specializes AS Specialization
7.2.2.1.21. Concept cdi:Stereotype

Labels all annotation types annotated by @javax.enterprise.inject.Stereotype with "Cdi" and "Stereotype".

MATCH
  (stereotype:Type:Annotation)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(stereotypeType:Type)
WHERE
  stereotypeType.fqn="javax.enterprise.inject.Stereotype"
SET
  stereotype:Cdi:Stereotype
RETURN
  stereotype AS Stereotype
7.2.2.1.22. Concept decorator:Decorator

Labels all types annotated by @javax.decorator.Decorator with "Decorator".

MATCH
  (decorator:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(decoratorType:Type)
WHERE
  decoratorType.fqn="javax.decorator.Decorator"
SET
  decorator:Decorator
RETURN
  decorator AS Decorator

Required concepts:

7.2.2.1.23. Concept decorator:Delegate

Labels all fields annotated annotated by @javax.decorator.Delegate with "Decorator" and "Delegate".

MATCH
  (delegate:Field)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(delegateType:Type)
WHERE
  delegateType.fqn="javax.decorator.Delegate"
SET
  delegate:Decorator:Delegate
RETURN
  delegate AS Delegate
7.2.2.1.24. Concept interceptor:Binding

Labels all annotations annotated by "javax.interceptor.InterceptorBinding" with "Interceptor" and "Binding".

MATCH
  (binding:Type:Annotation)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(bindingType:Type)
WHERE
  bindingType.fqn = "javax.interceptor.InterceptorBinding"
SET
  binding:Interceptor:Binding
RETURN
  binding AS InterceptorBinding
7.2.2.1.25. Concept interceptor:Interceptor

Labels all classes annotated by "javax.interceptor.Interceptor" with "Interceptor".

MATCH
  (interceptor:Type:Class)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(interceptorType:Type)
WHERE
  interceptorType.fqn = "javax.interceptor.Interceptor"
SET
  interceptor:Interceptor
RETURN
  interceptor AS Interceptor
7.2.2.2. Constraints provided by the CDI plugin
7.2.2.2.1. Constraint cdi:BeansMustNotUseFieldInjection

CDI beans shall not use field injection (constructor and setter injections are fine.).

MATCH
  (a:Type)-[:DECLARES]->(member:Field:Cdi:InjectionPoint)
RETURN
  DISTINCT a.fqn AS invalidBean

Required concepts:

7.2.2.2.2. Constraint cdi:BeansMustUseConstructorInjection

All CDI beans must use constructor injection.

MATCH
  (a:Type)-[:DECLARES]->(member:Cdi:InjectionPoint)
WHERE
  NOT member:Constructor
RETURN
  DISTINCT a.fqn AS invalidBean

Required concepts:

7.3. EJB3 Plugin

Provides rules for EJB3.

7.3.1. Rules provided by the EJB3 plugin

7.3.1.1. Concepts provided by the EJB3 plugin
7.3.1.1.1. Concept ejb3:Local

Labels all types annotated with @javax.ejb.Local with "Ejb" and "Local".

MATCH (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.Local"
SET t:Ejb:Local
RETURN t AS LocalBean
7.3.1.1.2. Concept ejb3:MessageDrivenBean

Labels all types annotated with @javax.ejb.MessageDriven with "Ejb" and "MessageDriven".

MATCH (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.MessageDriven"
SET t:Ejb:MessageDriven
RETURN t AS MessageDrivenBean
7.3.1.1.3. Concept ejb3:Remote

Labels all types annotated with @javax.ejb.Remote with "Ejb" and "Remote".

MATCH (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.Remote"
SET t:Ejb:Remote
RETURN t AS RemoteBean
7.3.1.1.4. Concept ejb3:Schedule

Labels all methods annotated with @javax.ejb.Schedule with "Schedule".

MATCH (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.Schedule"
SET m:Schedule
RETURN m AS ScheduledMethod
7.3.1.1.5. Concept ejb3:SingletonBean

Labels all classes annotated with @javax.ejb.Singleton with "Ejb" and "Singleton".

MATCH (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.Singleton"
SET t:Ejb:Singleton
RETURN t AS SingletonEjb
7.3.1.1.6. Concept ejb3:StatefulSessionBean

Labels all types annotated with @javax.ejb.Stateful with "Ejb" and "Stateful".

MATCH (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.Stateful"
SET t:Ejb:Stateful
RETURN t AS StatefulEjb
7.3.1.1.7. Concept ejb3:StatelessSessionBean

Labels all types annotated with @javax.ejb.Stateless with "Ejb" and "Stateless".

MATCH (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE a.fqn="javax.ejb.Stateless"
SET t:Ejb:Stateless
RETURN t AS StatelessEjb
7.3.1.2. Constraints provided by the EJB3 plugin
7.3.1.2.1. Constraint ejb3:ScheduleMethodInEjbContext

Check that Schedule methods are only delared in EJB classes.

MATCH (c:Class)-[:DECLARES]->(m:Method:Schedule)
WHERE NOT c:Ejb
RETURN c.fqn AS invalidBean, m.name AS scheduledMethodName

Required concepts:

7.4. GraphML Plugin

Provides a report plugin for generating GraphML files from the results of concepts.

7.4.1. GraphML Report

This plugin generates GraphML XML files for result data of concepts. Those files can be used with several graph rendering and analytics tools like yEd and Gephi.

By default all concepts ending in .graphml will be rendered (e.g. "module:modules.graphml").

7.4.1.1. Configuration
Table 3. Configuration properties
Property Description Default

graphml.report.conceptPattern

Regular expression that describes the concept ids to use for rendering the result as GraphML file.

.*\.graphml$

graphml.report.directory

The directory where the .graphml files will be created

jqassistant/report

graphml.report.yedgraphml

Flag to enable/disable the generation of yEd specific GraphML-Elements for labeling.

true

7.4.1.2. Example

The following concept will return package dependencies (as provided by the concept Concept dependency:Package) as GraphML document:

reports.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <concept id="report:PackageDependencies.graphml">
        <requiresConcept refId="dependency:Package" />
        <description>Reports all package dependencies.</description>
        <cypher><![CDATA[
            MATCH
              (p1:Package)-[d:DEPENDS_ON]->(p2:Package)
            RETURN
              p1, d, p2
        ]]></cypher>
    </concept>

</jqassistant-rules>

The plugin also supports virtual relations, i.e. which are constructed in the return clause of the query. A part of the return clause constructs a JSON-Object with several properties:

role

to identify the type of virtual element (value: relationship)

type

relationship type

startNode

the start node of the relationship

endNode

the end node of the relationship

The following example virtually propagates the dependencies of Java types to the package level without creating a relationship in the store:

reports.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <concept id="report:VirtualPackageDependencies.graphml">
        <description>Reports all package dependencies.</description>
        <cypher><![CDATA[
            MATCH
              (p1:Package)-[:CONTAINS]->(t1:Type),
              (p2:Package)-[:CONTAINS]->(t2:Type),
              (t1)-[:DEPENDS_ON]->(t2)
            RETURN
              p1,
              {
                role: "relationship",
                type: "DEPENDS_ON",
                startNode: p1,
                endNode: p2
              },
              p2
        ]]></cypher>
    </concept>

</jqassistant-rules>

Virtual nodes will be provided in the same way like virtual relationships. These are the properties to use in the JSON-Object:

role

to identify the type of virtual element (value: node)

properties

node properties

labels

a list of labels for this node

The following example virtually aggregates some data without creating a node in the store:

reports.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <concept id="report:VirtualDataNode.graphml">
        <description>Aggregates data in a virtual node.</description>
        <cypher><![CDATA[
            MATCH
              (m:Method)
            RETURN
              {
                role: "node",
                properties: {totalCyclomaticComplexity : sum(m.cyclomaticComplexity)},
                labels: ["Metrics", "CyclomaticComplexity"]
              }
        ]]></cypher>
    </concept>

</jqassistant-rules>

To get a better structured GraphML file subgraphs can be generated. With this pattern it is possible to drill down in the graph. These are the properties to use in the JSON object:

role

to identify the type of virtual element (value: graph)

parent

subgraphs must be nested in a parent node

nodes

all nodes that will be included in the subgraph

relationships

a list of relationships for the nodes. The relationships will be drawn if start- and end-node are part of the GraphML file.

The following example creates a virtual subgraph:

reports.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.8"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.8 https://schema.jqassistant.org/rule/jqassistant-rule-v1.8.xsd">

    <concept id="report:Subgraph.graphml">
        <description>Creates a Subgraph for a better overview.</description>
        <cypher><![CDATA[
            MATCH
              (t:Class)-[:DECLARES]->(m:Method)
            OPTIONAL MATCH
              (m)-[i:INVOKES]->(:Method)
            RETURN
              {
                role: "graph",
                parent: t,
                nodes: collect(m),
                relationships: collect(i)  (1)
              } as subgraph
        ]]></cypher>
    </concept>

</jqassistant-rules>
  1. The relationships can be used overall subgraphs

7.5. Java Plugin

Provides scanner for Java elements (e.g. packages, classes, manifest and property files) and rules for common language concepts (e.g. Deprecation), dependencies and metrics.

7.5.1. Artifact Scanner

7.5.1.1. Nodes labeled with `:Java:Artifact

A directory or archive containing packages, classes and resources.

Table 4. Properties of :Java:Artifact
Name Description

fqn

Fully qualified name, e.g. java.lang

fileName

The file name of the artifact. `

Table 5. Relations of :Java:Artifact
Name Target label(s) Cardinality Description

CONTAINS

[:File]

0..n

References contained files, e.g. packages, classes or resources

REQUIRES

Nodes labeled with :Java:Type

0..n

References a type which is required by a class in this artifact

7.5.1.2. Nodes labeled with :Java:Artifact:Directory

A directory representing a Java artifact.

7.5.1.3. Nodes labeled with :Java:Artifact:Jar:Archive

A JAR file representing a Java artifact.

7.5.2. Package Scanner

Imports Java packages.

7.5.2.1. Nodes labeled with :Java:Package

A Java package, i.e. a directory containing .class files or other directories.

Table 6. Properties of :Java:Package
Name Description

fqn

Fully qualified name, e.g. java.lang

name

The local name, e.g. lang

Table 7. Relations of :Java:Package
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Java:Type

0..n

References a type located in the package

CONTAINS

Nodes labeled with :Java:Package

0..n

References a package located in the package

7.5.3. Class Scanner

Imports Java classes, i.e. all scanned files having a .class suffix. Nodes with following labels will be created:

NOTE Some of these labels may be further qualified with other labels, see the description below.

NOTE The full set of information is only available for class files which have actually been scanned. Types which are only referenced (i.e. from external libraries not included in the scan) are represented by :Type nodes with a property fqn and DECLARES relations to their members. These are :Field or :Method labeled nodes which only provide the property signature.

7.5.3.1. Configuration
Table 8. Configuration properties
Property Description Default

java.class.model.Type.DEPENDS_ON.weight

Enables/disables calculation of the weight attribute for DEPENDS_ON relations between types

true

7.5.3.2. Nodes labeled with :Java:Type

A Java type. Can be qualified by either :Class, :Interface, :Enum or :Annotation

Table 9. Properties of :Java:Type
Name Description

fqn

Fully qualified name, e.g. java.lang.Object

name

The local name, e.g. Object

sourceFileName

The name of the source file, e.g. Object.java (optional).

visibility

optional, the visibility of the type, can be either public, protected, default or private

abstract

optional, true indicates that the type is abstract, e.g. public abstract class …​

static

optional, true indicates that the type has the static modifier, e.g. private static class …​

final

optional, true indicates that the type is final, e.g. public final class…​

synthetic

optional, true indicates that the type is synthetic, i.e. it has been generated

byteCodeVersion

The byte code version of the class file, e.g. 52 for "Java SE 8"

md5

The MD5 hash sum of the class file.

valid

true if the class file could be scanned successfully.

Table 10. Relations of :Java:Type
Name Target label(s) Cardinality Description

DECLARES

Nodes labeled with :Java:Type

0..n

Declares an inner type of the type

DECLARES

:Java:Method

0..n

Declares a method of the type

DECLARES

Nodes labeled with :Java:Field

0..n

Declares a field of the type

EXTENDS

Nodes labeled with :Java:Type

0..1

References a type this type extends from

IMPLEMENTS

Nodes labeled with :Java:Type

0..1

References an "Interface" type this type implements

ANNOTATED_BY

Nodes labeled with :Java:Value:Annotation

0..n

References an annotation which is present on the type

DEPENDS_ON

Nodes labeled with :Java:Type

0..n

References a type which this type depends on (i.e. every reference to another class)

NOTE Types which are referenced by scanned classes but have not been scanned themselves will only provide the property fqn and the relation DECLARES.

NOTE Inheritance between interfaces (i.e. public interface A extends B { …​ }) is represented using IMPLEMENTS relations, i.e. queries must use (a:Type:Interface)-[:IMPLEMENTS]→(b:Type:Interface) for pattern matching.

Table 11. Properties of :DEPENDS_ON
Name Description

weight

The weight of the dependency, i.e. the count of occurrences of the referenced type

Table 12. Properties of :READS, :WRITES and :INVOKES
Name Description

lineNumber

The line number the referenced field or method is read, written or invoked

7.5.3.3. Nodes labeled with :Java:Type:Class

Qualifies a Java type as class.

7.5.3.4. Nodes labeled with :Java:Type:Interface

Qualifies a Java type node as interface.

7.5.3.5. Nodes labeled with :Java:Type:Enum

Qualifies a Java type as enumeration.

7.5.3.6. Nodes labeled with :Java:Type:Annotation

Qualifies a Java type as annotation.

7.5.3.7. Nodes labeled with :Java:Field

A field declared in a Java type.

Table 13. Properties of :Java:Field
Name Description

name

The field name, e.g. id

signature

The raw signature of the field, e.g. int id, java.lang.String toString()

visibility

optional, The visibility of the field, can be either public, protected, default or private

static

optional, true indicates that the field has the static modifier, e.g. static int id;

final

optional, true indicates that the field is final, e.g. final int id;

transient

optional, true indicates that the field is transient, e.g. transient int id;

volatile

optional, true indicates that the field is volatile, e.g. volatile int id;

synthetic

optional, true indicates that the field is synthetic, i.e. it has been generated

Table 14. Relations of :Java:Field
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

References the type of the field

ANNOTATED_BY

Nodes labeled with :Java:Value:Annotation

0..n

References an annotation which is present on the field

HAS

Nodes labeled with :Java:Value

0..1

References the primitive value which is used for initialzing the field

NOTE Fields which are referenced by scanned classes but have not been scanned themselves will only provide the property signature.

7.5.3.8. :Java:Method

A method declared in a Java type.

Table 15. Properties of :Java:Method
Name Description

name

The method name, e.g. getId

signature

The raw signature of the method, e.g. int getId(), java.lang.String concat(java.lang.String,java.lang.String)

visibility

optional, The visibility of the method, can be either public, protected, default or private

abstract

optional, true indicates that the method is abstract, e.g. public abstract void …​

static

optional, true indicates that the method has the static modifier, e.g. static int getId();

final

optional, true indicates that the method is final, e.g. final int getId();

native

optional, true indicates that the method is native, e.g. native int getId();

synthetic

optional, true indicates that the method is synthetic, i.e. it has been generated

firstLineNumber

The first line number of the method body

lastLineNumber

The last line number of the method body

effectiveLineCount

The count of source code lines containing code

cyclomaticComplexity

The cyclomatic complexity of the method

Table 16. Relations of :Java:Method
Name Target label(s) Cardinality Description

HAS

Nodes labeled with :Java:Parameter

0..n

References a parameter of the method

THROWS

Nodes labeled with :Java:Type

0..n

References the exception type thrown by the method

RETURNS

Nodes labeled with :Java:Type

0..n

References the return type of the method

ANNOTATED_BY

Nodes labeled with :Java:Value:Annotation

0..n

References an annotation which is present on the method declaration

READS

Nodes labeled with :Java:Field

0..n

References a field which is read by the method

WRITES

Nodes labeled with :Java:Field

0..n

References a field which is written by the method

INVOKES

:Java:Method

0..n

References a method which is invoked by the method

DECLARES

Nodes labeled with :Java:Variable

0..n

References a variable method which is declared by the method

NOTE Methods which are referenced by scanned classes but have not been scanned themselves will only provide the property signature

7.5.3.9. Nodes labeled with :Java:Method:Constructor

Qualifies a method as constructor.

7.5.3.10. Nodes labeled with :Java:Parameter

A method parameter.

Table 17. Properties of :Java:Parameter
Name Description

index

The index of the parameter according to the method signature (starting with 0)

Table 18. Properties of :Java:Parameter
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

References the type of the parameter

ANNOTATED_BY

Nodes labeled with :Java:Value:Annotation

0..n

References an annotation which is present on the parameter

7.5.3.11. Nodes labeled with :Java:Variable

A variable declared in a method.

Table 19. Properties of :Java:Variable
Name Description

name

The variable name, e.g. i

signature

The raw signature of the variable, e.g. int i, java.lang.String name

7.5.3.12. Nodes labeled with :Java:Value

A value, can be qualified by either :Primitive, :Annotation, :Class, :Enum or :Array.

Table 20. Properties of :Java:Value
Name Description

name

The method name, e.g. value

7.5.3.13. Nodes labeled with :Value:Primitive

A primitive value.

Table 21. Properties of :Java:Value:Primitive
Name Description

value

The value

7.5.3.14. Nodes labeled with :Java:Value:Annotation

Represents a annotation on a Java element, e.g. @Entity public class …​

Table 22. Relations of :Java:Value:Annotation:
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

References the type of the annotation

HAS

Nodes labeled with :Java:Value

0..n

References an attribute of the annotation, e.g. @Entity(name="MyEntity")

7.5.3.15. Nodes labeled with :Java:Value:Class

Represents a class instance, e.g. as specified by annotation attribute.

Table 23. Relations of `:Java:Value:Class:
Name Target label(s) Cardinality Description

IS

Nodes labeled with :Java:Type

1

References the type

7.5.3.16. Nodes labeled with :Java:Value:Enum

Represents an enum value.

Table 24. Relations of :Java:Value:Enum:
Name Target label(s) Cardinality Description

IS

Nodes labeled with :Java:Field

1

References the field representing the enumeration value

7.5.3.17. Nodes labeled with :Java:Value:Array

Represents an array value, i.e. a node referencing value nodes.

Table 25. Relations of :Java:Value:Array:
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Java:Value

0..n

References a value contained in the array

7.5.4. Manifest File Scanner

Imports manifest descriptors from META-INF/MANIFEST.MF files.

7.5.4.1. Nodes labeled with :File:Java:Manifest

A MANIFEST.MF file containing sections.

Table 26. Properties of :File:Java:Manifest
Name Description

fileName

The file name

Table 27. Relations of :File:Java:Manifest
Name Target label(s) Cardinality Description

DECLARES

Nodes labeled with :Java:ManifestSection

0..n

References a manifest section

7.5.4.2. Nodes labeled with :Java:ManifestSection

A manifest section.

Table 28. Relations of :Java:ManifestSection
Name Target label(s) Cardinality Description

HAS

Nodes labeled with :Java:Value:ManifestEntry

0..n

References a manifest entry in the section

7.5.4.3. Nodes labeled with :Java:Value:ManifestEntry

A manifest entry.

Table 29. Properties of :Java:Value:ManifestEntry
Name Description

name

The name of the entry, e.g. Main-Class

value

The value of the entry, e.g. com.buschmais.jqassistant.scm.cli.Main

7.5.5. Property File Scanner

Imports text-based property files and XML-based property files, i.e. all files having a suffix .properties or .xml with the doctype <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">.

7.5.5.1. Nodes labeled with :File:Properties or :File:Properties:Xml

A property file containing key/value pairs. A node with the labels :File:Properties can represent a text based property file (*.properties) or a XML based property file (*.xml).

Table 30. Properties of :File:Java:Properties and :File:Java:Properties:Xml
Name Description

fileName

The file name

Table 31. Relations of :File:Java:Properties and :File:Java:Properties:Xml
Name Target label(s) Cardinality Description

HAS

Nodes labeled with :Java:Value:Property

0..n

References a property value

7.5.5.2. Nodes labeled with :Java:Value:Property

A key value/pair.

Table 32. Properties of :Java:Value:Property
Name Description

name

The name of the property

value

The value of the property

7.5.6. Service Loader File Scanner

Imports service loader descriptors from META-INF/services directories.

7.5.6.1. Nodes labeled with :File:Java:ServiceLoader

A file containing the implementation class names for a service interface

Table 33. Properties of :File:Java:ServiceLoader
Name Description

fileName

The file name

Table 34. Relations of :File:Java:ServiceLoader
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

The type representing the service interface

CONTAINS

Nodes labeled with :Java:Type

0..n

References a type which implements the service interface

7.5.7. @jQASuppress

The annotation com.buschmais.jqassistant.plugin.java.api.annotation.jQASuppress may be used for suppressing results of specific rules. It works in a similar way like java.lang.SuppressWarnings provided by Java.

For using it the jQAssistant Java plugin must be declared as compile-time dependency for your project, e.g. in case of Maven:

pom.xml
<dependency>
  <groupId>{projectGroupId}</groupId>
  <artifactId>{projectArtifactId}</artifactId>
  <version>{projectVersion}</version>
  <scope>provided</scope>
</dependency>

The annotation can now be used to suppress annotated elements like classes, fields or methods from rule results.

In the following example the class will not be reported by the constraint with the id my-rules:MyConstraint:

ClassViolatingMyConstraint
@jQASuppress("my-rules:MyConstraint")
public class ClassViolatingMyConstraint {

  //...

}
Note
Suppression only applies to the primary column of a rule result. If not explicitly specified this is the first column specified in the return clause of a concept or constraint.

7.5.8. Rules provided by the Java plugin

7.5.8.1. Concepts provided by the Java plugin
7.5.8.1.1. Concept classpath:Resolve

Includes all concepts for resolving a Java classpath and returns the number of resolved elements.

MATCH
  ()-[r:RESOLVES_TO]->()
RETURN
  count(r) as ResolvedElements

Required concepts:

7.5.8.1.2. Concept classpath:ResolveAnnotationType

Propagates "OF_TYPE" relations between annotation and types to their resolved types with a property "resolved:true".

MATCH
  (a:Annotation)-[ofType:OF_TYPE]->(:Type)-[:RESOLVES_TO]->(t:Type)
MERGE
  (a)-[ofType1:OF_TYPE]->(t)
SET
  ofType1=ofType,
  ofType1.resolved=true
RETURN
  count(ofType1) as ResolvedAnnotationTypes

Required concepts:

7.5.8.1.3. Concept classpath:ResolveDependency

The rule is deprecated: This concept has been replaced by "classpath:ResolveDependsOn".

Propagates "DEPENDS_ON" relations between types to their resolved types with a property "resolved:true".

MATCH
  (t1:Type)-[:DEPENDS_ON{resolved:true}]->(t2:Type)
RETURN
  count(*) as ResolvedDependencies

Required concepts:

7.5.8.1.4. Concept classpath:ResolveDependsOn

Propagates "DEPENDS_ON" relations between types to their resolved types with a property "resolved:true".

MATCH
  (t:Type)-[dependsOn:DEPENDS_ON]->(t1:Type)-[:RESOLVES_TO]->(t2:Type)
MERGE
  (t)-[dependsOn1:DEPENDS_ON]->(t2)
SET
  dependsOn1=dependsOn,
  dependsOn1.resolved=true
RETURN
  count(dependsOn1) as ResolvedDependencies

Required concepts:

7.5.8.1.5. Concept classpath:ResolveExtends

Propagates "EXTENDS" relations between types to their resolved types with a property "resolved:true".

MATCH
  (t:Type)-[extends:EXTENDS]->(t1:Type)-[:RESOLVES_TO]->(t2:Type)
MERGE
  (t)-[extends1:EXTENDS]->(t2)
SET
  extends1=extends,
  extends1.resolved=true
RETURN
  count(extends1) as ResolvedSuperClass

Required concepts:

7.5.8.1.6. Concept classpath:ResolveFieldType

Propagates "OF_TYPE" relations between fields and types to their resolved types with a property "resolved:true".

MATCH
  (f:Field)-[ofType:OF_TYPE]->(:Type)-[:RESOLVES_TO]->(t:Type)
MERGE
  (f)-[ofType1:OF_TYPE]->(t)
SET
  ofType1=ofType,
  ofType1.resolved=true
RETURN
  count(ofType1) as ResolvedFieldTypes

Required concepts:

7.5.8.1.7. Concept classpath:ResolveImplements

Propagates "IMPLEMENTS" relations between types to their resolved types with a property "resolved:true".

MATCH
  (t:Type)-[implements:IMPLEMENTS]->(t1:Type)-[:RESOLVES_TO]->(t2:Type)
MERGE
  (t)-[implements1:IMPLEMENTS]->(t2)
SET
  implements1=implements,
  implements1.resolved=true
RETURN
  count(implements1) as ResolvedInterfaces

Required concepts:

7.5.8.1.8. Concept classpath:ResolveInvokes

Propagates "INVOKES" relations between methods to their resolved methods with a property "resolved:true".

MATCH
  (m:Method)-[invokes:INVOKES]->(m1:Method)-[:RESOLVES_TO]->(m2:Method)
MERGE
  (m)-[invokes1:INVOKES {relationId : id(invokes)}]->(m2)
SET
  invokes1=invokes,
  invokes1.resolved=true
REMOVE
  invokes1.relationId
RETURN
  count(invokes1) as ResolvedInvocations

Required concepts:

7.5.8.1.9. Concept classpath:ResolveMember

Adds a relation "RESOLVES_TO" from a member (i.e. field or method) of a type to a member of another type if there is a relation "RESOLVES_TO" between the two types and the members have the same signature.

MATCH
  (t1:Type)-[:RESOLVES_TO]->(t2:Type),
  (t1)-[:DECLARES]->(m1),
  (t2)-[:DECLARES]->(m2)
WHERE
  (m1:Field or m1:Method)
  and m1.signature = m2.signature
MERGE
  (m1)-[r:RESOLVES_TO]->(m2)
RETURN
  count(r) as ResolvedMembers

Required concepts:

7.5.8.1.10. Concept classpath:ResolveParameterType

Propagates "OF_TYPE" relations between method parameters and types to their resolved types with a property "resolved:true".

MATCH
  (m:Parameter)-[ofType:OF_TYPE]->(:Type)-[:RESOLVES_TO]->(t:Type)
MERGE
  (m)-[ofType1:OF_TYPE]->(t)
SET
  ofType1=ofType,
  ofType1.resolved=true
RETURN
  count(ofType1) as ResolvedParameterTypes

Required concepts:

7.5.8.1.11. Concept classpath:ResolveReads

Propagates "READS" relations between methods and fields to their resolved fields with a property "resolved:true".

MATCH
  (m:Method)-[reads:READS]->(f1:Field)-[:RESOLVES_TO]->(f2:Field)
MERGE
  (m)-[reads1:READS {relationId: id(reads)}]->(f2)
SET
  reads1=reads,
  reads1.resolved=true
REMOVE
  reads1.relationId
RETURN
  count(reads1) as ResolvedReads

Required concepts:

7.5.8.1.12. Concept classpath:ResolveReturns

Propagates "RETURNS" relations between methods and types to their resolved types with a property "resolved:true".

MATCH
  (m:Method)-[returns:RETURNS]->(:Type)-[:RESOLVES_TO]->(t:Type)
MERGE
  (m)-[returns1:RETURNS]->(t)
SET
  returns1=returns,
  returns1.resolved=true
RETURN
  count(returns1) as ResolvedReturnTypes

Required concepts:

7.5.8.1.13. Concept classpath:ResolveThrows

Propagates "THROWS" relations between methods and types to their resolved types with a property "resolved:true".

MATCH
  (m:Method)-[throws:THROWS]->(:Type)-[:RESOLVES_TO]->(t:Type)
MERGE
  (m)-[throws1:THROWS]->(t)
SET
  throws1=throws,
  throws1.resolved=true
RETURN
  count(throws1) as ResolvedExceptionTypes

Required concepts:

7.5.8.1.14. Concept classpath:ResolveType

Adds a relation "RESOLVES_TO" from a type required by an artifact to a type contained in another artifact if their fully qualified names match.

MATCH
  (a1:Artifact)-[:REQUIRES]->(t1:Type)
WITH
  a1, t1, t1.fqn as fqn
MATCH
  (a2:Artifact)-[:CONTAINS]->(t2:Type)
WHERE
  t2.fqn=t1.fqn
MERGE
  (t1)-[r:RESOLVES_TO]->(t2)
RETURN
  count(r) as ResolvedTypes
7.5.8.1.15. Concept classpath:ResolveValue

Propagates "IS" relations between values and types to their resolved types with a property "resolved:true".

MATCH
  (v:Value)-[is:IS]->(e)-[:RESOLVES_TO]->(e2)
MERGE
  (v)-[is1:IS]->(e2)
SET
  is1=is,
  is1.resolved=true
RETURN
  count(is1) as ResolvedValueTypes

Required concepts:

7.5.8.1.16. Concept classpath:ResolveWrites

Propagates "WRITES" relations between methods and fields to their resolved fields with a property "resolved:true".

MATCH
  (m:Method)-[writes:WRITES]->(f1:Field)-[:RESOLVES_TO]->(f2:Field)
MERGE
  (m)-[writes1:WRITES {relationId: id(writes)}]->(f2)
SET
  writes1=writes,
  writes1.resolved=true
REMOVE
  writes1.relationId
RETURN
  count(writes1) as ResolvedWrites

Required concepts:

7.5.8.1.17. Concept dependency:Artifact

Creates a new DEPENDS_ON relationship between artifacts or updates an existing one with a 'used' property if there are type dependencies between them, i.e. if an artifact contains a type with a fully qualified name which a type from another artifact requires.

MATCH
  (a1:Artifact)-[:CONTAINS]->(:Type)-[:DEPENDS_ON]->(type:Type)
WITH
  a1,type.fqn as fqn
MATCH
  (a2:Artifact)-[:CONTAINS]->(t2:Type)
WHERE
  a1 <> a2
  and t2.fqn = fqn
MERGE
  (a1)-[d:DEPENDS_ON]->(a2)
SET
  d.used=true
RETURN
  a1 AS Artifact, COLLECT(DISTINCT a2.fqn) AS Dependencies
7.5.8.1.18. Concept dependency:Package

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
7.5.8.1.19. Concept java:AnonymousInnerType

Sets a label "Anonymous" on anonymous inner types, i.e. types without a name.

MATCH
  (innerType:Inner:Type)
WHERE
  innerType.name =~ ".*\\$[0-9]*"
SET
  innerType:Anonymous
RETURN
  innerType AS AnonymousInnerType

Required concepts:

7.5.8.1.20. Concept java:DefaultMethod

Labels default methods of interfaces with Default.

MATCH
  (type:Type:Java:Interface)-[:DECLARES]->(defaultMethod:Java:Method)
WHERE NOT
  exists(defaultMethod.abstract)
SET
  defaultMethod:Default
RETURN
  defaultMethod AS DefaultMethod, type AS Interface
7.5.8.1.21. Concept java:Deprecated

Labels all nodes representing deprecated elements (types, fields, methods, packages or parameters) with "Deprecated".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(dt:Type)
WHERE
  dt.fqn='java.lang.Deprecated'
SET
  e:Deprecated
RETURN
  e AS DeprecatedElement
7.5.8.1.22. Concept java:Error

Labels types deriving from java.lang.Error as "Error".

MATCH
  (throwable)-[:EXTENDS*]->(t:Type)
WHERE
  t.fqn = 'java.lang.Error'
SET
  throwable:Error
RETURN
  throwable AS Error
7.5.8.1.23. Concept java:Exception

Labels types deriving from java.lang.Exception as "Exception".

MATCH
  (exception)-[:EXTENDS*]->(t:Type)
WHERE
  t.fqn = 'java.lang.Exception'
SET
  exception:Exception
RETURN
  exception AS Exception
7.5.8.1.24. Concept java:FunctionalInterface

Labels functional interfaces (i.e. to be used as lambda expressions) with FunctionalInterface.

MATCH
    (i:Java:Interface)-[:DECLARES]->(m:Member:Java:Method {abstract: true})
WITH
    i, count(m) AS methods
WHERE
    methods = 1
SET
    i:FunctionalInterface
RETURN
    i AS FunctionInterface
7.5.8.1.25. Concept java:InnerType

Sets a label "Inner" on inner types.

MATCH
  (:Type)-[:DECLARES]->(innerType:Type)
SET
  innerType:Inner
RETURN
  innerType AS InnerType
7.5.8.1.26. Concept java:InvokesOverriddenMethod

The rule is deprecated: To avoid ambiguities between INVOKES relations this concept has been replaced by "java:VirtualInvokes".

Propagates INVOKES relationships to methods which implement or override the invoked method.

MATCH
  (method:Method)-[invocation:INVOKES]->(invokedMethod:Method),
  (overridingMethod:Method)-[:OVERRIDES]->(invokedMethod)
MERGE
  (method)-[r:INVOKES{lineNumber:invocation.lineNumber}]->(overridingMethod)
RETURN count(r) AS OverridingInvocations

Required concepts:

7.5.8.1.27. Concept java:JavaVersion

Set a human readable property "javaVersion" on a class file based on its byte code version.

MATCH
  (:Artifact)-[:CONTAINS]->(type:Java:Type)
SET
  type.javaVersion=
  CASE type.byteCodeVersion
    WHEN 57 THEN "Java 13"
    WHEN 56 THEN "Java 12"
    WHEN 55 THEN "Java 11"
    WHEN 54 THEN "Java 10"
    WHEN 53 THEN "Java 9"
    WHEN 52 THEN "Java 8"
    WHEN 51 THEN "Java 7"
    WHEN 50 THEN "Java 6"
    WHEN 49 THEN "Java 5"
    WHEN 48 THEN "Java 1.4"
    WHEN 47 THEN "Java 1.3"
    WHEN 46 THEN "Java 1.2"
    WHEN 45 THEN "Java 1.1/1.0"
  END
RETURN
  count(type) as Types
7.5.8.1.28. Concept java:LambdaMethod

Labels lambda methods with Lambda and creates a relation DECLARES from the declaring method.

MATCH
  (type:Java:Type)-[:DECLARES]->(lambda:Method)
WHERE
  exists(lambda.synthetic)
  and exists(lambda.static)
  and lambda.name starts with("lambda$")
SET
  lambda:Lambda
WITH
  type, lambda
MATCH
  (type)-[:DECLARES]->(method:Method)
WHERE
  method <> lambda
  and method.firstLineNumber <= lambda.firstLineNumber
  and method.lastLineNumber >= lambda.lastLineNumber
MERGE
  (method)-[:DECLARES_LAMBDA]->(lambda)
RETURN
  method, collect(lambda)
7.5.8.1.29. Concept java:MethodOverloads

Creates a relationship OVERLOADS between two "Method" labeled nodes if one method overloads another one from the same type (i.e. the methods have the same name but not the same signature).

MATCH
  (type:Type)-[:DECLARES]->(method:Method),
  (type)-[:DECLARES]->(otherMethod:Method)
WHERE
  method <> otherMethod
  AND method.name = otherMethod.name
  AND method.signature <> otherMethod.signature
MERGE
  (method)-[:OVERLOADS]->(otherMethod)
RETURN method AS OverloadedMethod, type AS DeclaringType
7.5.8.1.30. Concept java:MethodOverrides

Creates a relationship OVERRIDES between two "Method" labeled nodes if one method overrides another one from a super type (i.e. the methods have the same signature).

MATCH
  (type:Type)-[:DECLARES]->(method:Method),
  (superType:Type)-[:DECLARES]->(otherMethod:Method),
  (type)-[:EXTENDS|IMPLEMENTS*]->(superType)
WHERE
  method.name = otherMethod.name
  AND method.signature = otherMethod.signature
  AND method.visibility <> 'private'
MERGE
  (method)-[:OVERRIDES]->(otherMethod)
RETURN method AS OverriddenMethod, type AS DeclaringType, superType AS SuperType
7.5.8.1.31. Concept java:RuntimeException

Labels types deriving from java.lang.RuntimeException as "RuntimeException".

MATCH
  (runtimeException)-[:EXTENDS*]->(t:Type)
WHERE
  t.fqn = 'java.lang.RuntimeException'
SET
  runtimeException:RuntimeException
RETURN
  runtimeException AS RuntimeException
7.5.8.1.32. Concept java:Throwable

Labels types deriving from java.lang.Throwable as "Throwable".

MATCH
  (throwable)-[:EXTENDS*]->(t:Type)
WHERE
  t.fqn = 'java.lang.Throwable'
SET
  throwable:Throwable
RETURN
  throwable AS Throwable
7.5.8.1.33. Concept java:TypeAssignableFrom

Creates a relationship ASSIGNABLE_FROM between two "Type" labeled nodes if one type is assignable from the other (i.e. a super class or interface).

MATCH
  (type:Type)
MERGE
  (type)-[:ASSIGNABLE_FROM]->(type)
WITH
  type
MATCH
  (type)-[:IMPLEMENTS|EXTENDS*]->(superType:Type)
MERGE
  (superType)-[:ASSIGNABLE_FROM]->(type)
RETURN type AS AssignableType, superType AS AssignableFrom
7.5.8.1.34. Concept java:VirtualDependsOn

Propagates DEPENDS_ON relationships as VIRTUAL_DEPENDS_ON to types that extend or implement the referenced type.

MATCH
  (type:Type)-[:EXTENDS|IMPLEMENTS*]->(superType:Type),
  (dependent:Type)-[:DEPENDS_ON]->(superType)
WHERE NOT (
  (dependent)-[:EXTENDS|IMPLEMENTS*]->(superType) // exclude types sharing the same super classes/interfaces
  or superType.fqn = "java.lang.Object"
)
MERGE
  (dependent)-[virtualDependsOn:VIRTUAL_DEPENDS_ON]->(type)
RETURN
  count(virtualDependsOn) AS VirtualDependsOn
7.5.8.1.35. Concept java:VirtualInvokes

Propagates INVOKES relationships as VIRTUAL_INVOKES to methods which implement or override the invoked method.

MATCH
  (method:Method)-[invokes:INVOKES]->(invokedMethod:Method),
  (overridingMethod:Method)-[:OVERRIDES]->(invokedMethod)
MERGE
  (method)-[virtualInvokes:VIRTUAL_INVOKES{lineNumber:invokes.lineNumber}]->(overridingMethod)
RETURN
  count(virtualInvokes) AS VirtualInvokes

Required concepts:

7.5.8.2. Constraints provided by the Java plugin
7.5.8.2.1. Constraint dependency:ArtifactCycles

There must be no cyclic artifact dependencies.

MATCH
    (a1:Artifact)-[:DEPENDS_ON]->(a2:Artifact),
    path=shortestPath((a2)-[:DEPENDS_ON*]->(a1))
WHERE
    a1<>a2
RETURN
    a1 AS Artifact, EXTRACT(a IN nodes(path) | a.fqn) AS Cycle
ORDER BY
    Artifact.fqn

Required concepts:

7.5.8.2.2. Constraint dependency:PackageCycles

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

Required concepts:

7.6. Java 8 (Deprecated) Plugin

Provides Java 8 specific rules, e.g. concepts for functional interfaces and default methods (deprecated, moved into Java plugin).

7.6.1. Rules provided by the Java 8 (Deprecated) plugin

7.6.1.1. Concepts provided by the Java 8 (Deprecated) plugin
7.6.1.1.1. Concept java8:DefaultMethod

The rule is deprecated: This concept has been replaced by "java:DefaultMethod".

Labels default methods of interfaces with Default.

MATCH
  (type:Type:Java:Interface)-[:DECLARES]->(defaultMethod:Java:Method)
WHERE NOT
  exists(defaultMethod.abstract)
SET
  defaultMethod:Default
RETURN
  defaultMethod AS DefaultMethod, type AS Interface
7.6.1.1.2. Concept java8:FunctionalInterface

The rule is deprecated: This concept has been replaced by "java:FunctionalInterface".

Labels functional interfaces (i.e. to be used as lambda expressions) with FunctionalInterface.

MATCH
    (i:Java:Interface)-[:DECLARES]->(m:Member:Java:Method {abstract: true})
WITH
    i, count(m) AS methods
WHERE
    methods = 1
SET
    i:FunctionalInterface
RETURN
    i AS FunctionInterface
7.6.1.1.3. Concept java8:LambdaMethod

The rule is deprecated: This concept has been replaced by "java:LambdaMethod".

Labels lambda methods with Lambda and creates a relation DECLARES from the declaring method.

MATCH
  (type:Java:Type)-[:DECLARES]->(lambda:Method)
WHERE
  exists(lambda.synthetic)
  and exists(lambda.static)
  and lambda.name starts with("lambda$")
SET
  lambda:Lambda
WITH
  type, lambda
MATCH
  (type)-[:DECLARES]->(method:Method)
WHERE
  method <> lambda
  and method.firstLineNumber <= lambda.firstLineNumber
  and method.lastLineNumber >= lambda.lastLineNumber
MERGE
  (method)-[:DECLARES_LAMBDA]->(lambda)
RETURN
  method, collect(lambda)

7.7. Java EE 6 Plugin

Aggregates plugins providing scanners and rules for Java EE 6 technologies (e.g. JPA2, EJB3).

7.7.1. Scanner for EAR files

Imports EAR (Enterprise ARchive) files.

7.7.1.1. Nodes labeled with :File:Enterprise:Application:Archive

A file representing an EAR file.

Table 35. Properties of :File:Enterprise:Application:Archive
Name Description

fileName

The file name

Table 36. Relations of :File:Enterprise:Application:Archive
Name Target label(s) Cardinality Description

CONTAINS

[:File]

0..n

References the files contained in the archive.

7.7.1.2. Nodes labeled with :File:Enterprise:Application:Xml

Represents a Java EE application.xml descriptor.

Table 37. Properties of :File:Enterprise:Application:Xml
Name Description

fileName

The file name

initializeInOrder

If initialize-in-order is true, modules must be initialized in the order they’re listed in the deployment descriptor

libraryDirectory

The path to the library directory.

Table 38. Relations of :File:Enterprise:Application:Xml
Name Target label(s) Cardinality Description

HAS_DESCRIPTION

Nodes labeled with :Description

0..n

References a description of this descriptor.

HAS_DISPLAY_NAME

Nodes labeled with :DisplayName

0..n

References a display name of this descriptor.

HAS_ICON

Nodes labeled with :Icon

0..n

References an icon of this descriptor.

HAS_MODULE

Nodes labeled with :Enterprise:Application:Module

1..n

References a module specified by this descriptor.

HAS_SECURITY_ROLE

Nodes labeled with :SecurityRole

0..n

References a security role defined by this descriptor.

7.7.1.3. Nodes labeled with :Enterprise:Application:Module

Represents a declared module of a Java EE Java application. Can be qualified by either :Ejb, :Web, :Connector or :JavaClient.

Table 39. Properties of :Enterprise:Application:Module
Name Description

path

The path to the module archive within the enterprise application archive.

7.7.1.4. Nodes labeled with :Enterprise:Application:Module:Web

Represents a declared web module of a Java EE Java application.

Table 40. Properties of :Enterprise:Application:Module:Web
Name Description

contextRoot

The context root path to use for the web module.

7.7.2. Scanner for WAR files

Imports WAR (Web Application Archive) files.

7.7.2.1. Nodes labeled with :File:Web:Application:Archive

A file representing WAR file.

Table 41. Properties of :File:Web:Application:Archive
Name Description

fileName

The file name

Table 42. Relations of :File:Web:Application:Archive
Name Target label(s) Cardinality Description

CONTAINS

[:File]

0..n

References the files contained in the archive.

7.7.2.2. Nodes labeled with :File:Web:Xml

Represents a web application descriptor.

Table 43. Relations of :File:Web:Xml
Name Target label(s) Cardinality Description

HAS_SESSION_CONFIG

Nodes labeled with :SessionConfig

0..1

References the session configuration.

HAS_SERVLET

Nodes labeled with :Servlet

0..n

References a servlet declaration.

HAS_SERVLET_MAPPING

ServletMapping

0..n

References a servlet mapping declaration.

HAS_FILTER

Filter

0..n

References a filter declaration.

HAS_FILTER_MAPPING

FilterMapping

0..n

References a filter mapping declaration.

HAS_LISTENER

Listener

0..n

References a listener declaration.

HAS_CONTEXT_PARAM

[.ParamValue]

0..n

References a context parameter declaration.

HAS_ERROR_PAGE

ErrorPage

0..n

References an error page declaration.

HAS_SECURITY_CONSTRAINT

SecurityConstraint

0..n

References a security constraint declaration.

HAS_SECURITY_ROLE

Nodes labeled with :SecurityRole

0..n

References a security role declaration.

HAS_LOGIN_CONFIG

LoginConfig

0..n

References a login configuration.

7.7.2.3. Nodes labeled with :SessionConfig

Represents a session configuration.

Table 44. Properties of :SessionConfig
Name Description

sessionTimeout

The session timeout.

7.7.2.4. Nodes labeled with :Servlet

Represents a servlet declaration.

Table 45. Properties of :Servlet
Name Description

enabled

Indicates if this servlet is enabled.

jspFile

The JSP file representing the servlet.

loadOnStartup

Indicates whether the servlet will be loaded on startup.

Table 46. Relations of :Servlet
Name Target label(s) Cardinality Description

HAS_DESCRIPTION

Nodes labeled with :Description

0..n

References a description of this descriptor.

HAS_DISPLAY_NAME

Nodes labeled with :DisplayName

0..n

References a display name of this descriptor.

HAS_ICON

Nodes labeled with :Icon

0..n

References an icon of this descriptor.

HAS_INIT_PARAM

[:ParamValue]

0..n

References a init parameter.

7.7.3. Scanner for JSF-template files

Imports JSF template files (e.g. *.jspx) and builds references between them (template/includes).

7.7.3.1. Configuration
Table 47. Configuration properties
Property Description Default

facelet.file.pattern

Regular expression that describes scanable JSF template files.

.*\\.jspx

7.7.3.2. Nodes labeled with :File:Jsf:Facelet

A JSF template file.

Table 48. Properties of :File:Jsf:Facelet
Name Description

fileName

The file name

Table 49. Relations of :File:Jsf:Facelet
Name Target label(s) Cardinality Description

INCLUDES

[:File:Jsf:Facelet]

0..n

References a included JSF template file (e.g. <ui:include src="include.jspx"/>)

WITH_TEMPLATE

[:File:Jsf:Facelet]

0..1

References a used JSF template file (e.g. <ui:composition template="template.jspx" …​>)

7.7.3.3. Nodes labeled with :Description

Represents an internationalized description.

Table 50. Properties of :Description
Name Description

lang

The language, e.g. en

value

The description.

7.7.3.4. Nodes labeled with :DisplayName

Represents an internationalized display name.

Table 51. Properties of :DisplayName
Name Description

lang

The language, e.g. en

value

The description.

7.7.3.5. Nodes labeled with :Icon

Represents an icon.

Table 52. Properties of :Icon
Name Description

smallIcon

The file name of the small icon, e.g. smallIcon.png.

largeIcon

The file name of the large icon, e.g. largeIcon.png.

7.7.3.6. Nodes labeled with :SecurityRole

Represents a security role.

Table 53. Relations of :SecurityRole
Name Target label(s) Cardinality Description

HAS_DESCRIPTION

Nodes labeled with :Description

0..n

References a description of this security role.

HAS_ROLE_NAME

Nodes labeled with :Description

1

References the role name.

7.7.3.7. Nodes labeled with :RoleName

Represents a role name.

Table 54. Properties of :RoleName

Name

Description

name

The name of the role.

7.8. JAX-RS Plugin

Provides rules for JAX-RS.

7.8.1. Rules provided by the JAX-RS plugin

7.8.1.1. Concepts provided by the JAX-RS plugin
7.8.1.1.1. Concept jaxrs:ContextProvider

Finds classes that implement "javax.ws.rs.ext.ContextResolver" and labels them with 'JaxRS' and 'ContextProvider'

MATCH
  (c:Type:Class)-[:IMPLEMENTS]->(a:Type)
WHERE
  a.fqn = "javax.ws.rs.ext.ContextResolver"
SET
  c:JaxRS:ContextProvider
RETURN
  DISTINCT c AS ContextProvider
7.8.1.1.2. Concept jaxrs:DeleteResourceMethod

Finds resource methods annotated with "@javax.ws.rs.DELETE" and labels them with 'DeleteResourceMethod'.

MATCH
  (m:JaxRS:ResourceMethod)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
WHERE
  a.fqn = "javax.ws.rs.DELETE"
SET
  m:DeleteResourceMethod
RETURN
  m AS DeleteMethod

Required concepts:

7.8.1.1.3. Concept jaxrs:EntityProvider

Finds classes that implement "javax.ws.rs.ext.MessageBodyReader" or "javax.ws.rs.ext.MessageBodyWriter" and labels them with 'JaxRS' and 'EntityProvider'

MATCH
  (c:Type:Class)-[:IMPLEMENTS]->(a:Type)
WHERE
  a.fqn IN ["javax.ws.rs.ext.MessageBodyReader", "javax.ws.rs.ext.MessageBodyWriter"]
SET
  c:JaxRS:EntityProvider
RETURN
  DISTINCT c AS EntityProvider
7.8.1.1.4. Concept jaxrs:ExceptionMappingProvider

Finds classes that implement "javax.ws.rs.ext.ExceptionMapper" and labels them with 'JaxRS' and 'ExceptionMappingProvider'

MATCH
  (c:Type:Class)-[:IMPLEMENTS]->(a:Type)
WHERE
  a.fqn = "javax.ws.rs.ext.ExceptionMapper"
SET
  c:JaxRS:ExceptionMappingProvider
RETURN
  DISTINCT c AS ExceptionMappingProvider
7.8.1.1.5. Concept jaxrs:GetResourceMethod

Finds resource methods annotated with "@javax.ws.rs.GET" and labels them with 'GetResourceMethod'.

MATCH
  (m:JaxRS:ResourceMethod)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
WHERE
  a.fqn = "javax.ws.rs.GET"
SET
  m:GetResourceMethod
RETURN
  m AS GetMethod

Required concepts:

7.8.1.1.6. Concept jaxrs:HeadResourceMethod

Finds resource methods annotated with "@javax.ws.rs.HEAD" and labels them with 'HeadResourceMethod'.

MATCH
  (m:JaxRS:ResourceMethod)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
WHERE
  a.fqn = "javax.ws.rs.HEAD"
SET
  m:HeadResourceMethod
RETURN
  m AS HeadMethod

Required concepts:

7.8.1.1.7. Concept jaxrs:OptionsResourceMethod

Finds resource methods annotated with "@javax.ws.rs.OPTIONS" and labels them with 'OptionsResourceMethod'.

MATCH
  (m:JaxRS:ResourceMethod)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
WHERE
  a.fqn = "javax.ws.rs.OPTIONS"
SET
  m:OptionsResourceMethod
RETURN
  m AS OptionsMethod

Required concepts:

7.8.1.1.8. Concept jaxrs:PostResourceMethod

Finds resource methods annotated with "@javax.ws.rs.POST" and labels them with 'PostResourceMethod'.

MATCH
  (m:JaxRS:ResourceMethod)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
WHERE
  a.fqn = "javax.ws.rs.POST"
SET
  m:PostResourceMethod
RETURN
  m AS PostMethod

Required concepts:

7.8.1.1.9. Concept jaxrs:PutResourceMethod

Finds resource methods annotated with "@javax.ws.rs.PUT" and labels them with 'PutResourceMethod'.

MATCH
  (m:JaxRS:ResourceMethod)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
WHERE
  a.fqn = "javax.ws.rs.PUT"
SET
  m:PutResourceMethod
RETURN
  m AS PutMethod

Required concepts:

7.8.1.1.10. Concept jaxrs:RequestMethodDesignator

Finds request method designator annotations (i.e. @GET, @POST, @PUT, @DELETE, @HEAD, @OPTIONS) and labels them with 'JaxRS' and 'RequestMethodDesignator'

MATCH
  (a:Type)
WHERE
  a.fqn IN ["javax.ws.rs.GET", "javax.ws.rs.POST", "javax.ws.rs.PUT", "javax.ws.rs.DELETE", "javax.ws.rs.HEAD", "javax.ws.rs.OPTIONS"]
SET
  a:JaxRS:RequestMethodDesignator
RETURN
  a AS RequestMethodDesignator
7.8.1.1.11. Concept jaxrs:Resource

Finds classes or interfaces with atleast one method annotated with "@javax.ws.rs.Path" or with request method designator (i.e. @GET, @POST, @PUT, @DELETE, @HEAD, @OPTIONS) and labels them with 'JaxRS' and 'Resource'.

MATCH
  (t:Type)-[:DECLARES]->(m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  (a:JaxRS:RequestMethodDesignator OR a.fqn="javax.ws.rs.Path")
AND
  (t:Class OR t:Interface)
SET
  t:JaxRS:Resource
RETURN
  DISTINCT t AS RestResource

Required concepts:

7.8.1.1.12. Concept jaxrs:ResourceMethod

Finds methods that belong to resource class or interface and annotated with request method designator (i.e. @GET, @POST, @PUT, @DELETE, @HEAD, @OPTIONS) and labels them with 'JaxRS' and 'ResourceMethod'.

MATCH
  (c:JaxRS:Resource)-[:DECLARES]->(m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:JaxRS:RequestMethodDesignator)
SET
  m:JaxRS:ResourceMethod
RETURN
  m AS ResourceMethod

Required concepts:

7.8.1.1.13. Concept jaxrs:SubResourceLocator

Finds classes or interfaces with method annotated with "@javax.ws.rs.Path" but no request method designator and no entity parameters and labels the methods with 'JaxRS' and 'SubResourceLocator'.

MATCH
  (t:Type)-[:DECLARES]->(m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn = "javax.ws.rs.Path"
AND
  (t:Class OR t:Interface)
AND
  NOT (m)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(:JaxRS:RequestMethodDesignator)
AND
  (m)-[:HAS]->(:Parameter)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(:Type)
SET
  m:JaxRS:SubResourceLocator
RETURN
  DISTINCT m AS RestSubResourceLocator

Required concepts:

7.9. JPA 2 Plugin

Provides a scanner for persistence.xml descriptors and rules for JPA2 specific elements (e.g. entities).

7.9.1. Scanner for persistence.xml files

Imports persistence descriptors from META-INF/persistence.xml or WEB-INF/persistence.xml files.

7.9.1.1. :File:Jpa:Persistence

A persistence.xml file containing persistence units.

Table 55. Properties of :File:Jpa:Persistence
Name Description

fileName

The file name

version

The version of the JPA specification this descriptor represents, e.g. 2.0

Table 56. Relations of :File:Jpa:Persistence
Name Target label(s) Cardinality Description

CONTAINS

:Jpa:PersistenceUnit

0..n

References a contained persistence unit

7.9.1.2. :Jpa:PersistenceUnit

A persistence unit.

Table 57. Properties of :Jpa:PersistenceUnit
Name Description

description

The description of the persistence unit.

excludeUnlistedClasses

If the persistence unit should only contain listed classes or all entities.

transactionType

The transaction type, can be RESOURCE_LOCAL or JTA

provider

The class name of the JPA provider.

jtaDatasource

The JNDI name of the transactional datasource

nonJtaDatasource

The JNDI name of the non-transactional datasource

validationMode

The validation mode, can be NONE, CALLBACK or AUTO

sharedCacheMode

The shared cache mode, e.g. NONE

Table 58. Relations of :Jpa:PersistenceUnit
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Java:Type

0..n

References a persistent type (entity) contained in the persistence unit

HAS

[:Value:Property]

0..n

References a property of the persistence unit

7.9.2. Rules provided by the JPA 2 plugin

7.9.2.1. Concepts provided by the JPA 2 plugin
7.9.2.1.1. Concept jpa2:Embeddable

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

MATCH
  (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="javax.persistence.Embeddable"
SET
  t:Jpa:Embeddable
RETURN
  t AS JpaEmbeddable
7.9.2.1.2. Concept jpa2:Embedded

Labels all fields or methods annotated with @javax.persistence.Embedded with "Jpa" and "Embedded".

MATCH
  (t:Type)-[:DECLARES]->(member),
  (member)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  (member:Field or member:Method)
  and a.fqn="javax.persistence.Embedded"
SET
  member:Jpa:Embedded
RETURN
  member AS JpaEmbedded
7.9.2.1.3. Concept jpa2:EmbeddedId

Labels all fields or methods annotated with @javax.persistence.EmbeddedId with "Jpa" and "Embedded".

MATCH
  (t:Type)-[:DECLARES]->(member),
  (member)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  (member:Field or member:Method)
  and a.fqn="javax.persistence.EmbeddedId"
SET
  member:Jpa:EmbeddedId
RETURN
  member AS EmbeddedId
7.9.2.1.4. Concept jpa2:Entity

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
7.9.2.1.5. Concept jpa2:NamedQuery

Creates a node labeled with "Jpa" and "NamedQuery" for each @NamedQuery defined for an entity. Furthermore a relation DEFINES is created between the entity and the named query.

MATCH
  (entity:Jpa:Entity),
  (entity)-[:ANNOTATED_BY]->(namedQueries:Annotation)-[:OF_TYPE]-(:Type{fqn:'javax.persistence.NamedQueries'}),
  (namedQueries)-[:HAS]->(:Value:Array)-[:CONTAINS]->(namedQuery),
  (namedQuery)-[:OF_TYPE]->(:Type{fqn:'javax.persistence.NamedQuery'}),
  (namedQuery)-[:HAS]->(nameAttribute:Value{name:'name'}),
  (namedQuery)-[:HAS]->(queryAttribute:Value{name:'query'})
MERGE
  (entity)-[:DEFINES]->(n:Jpa:NamedQuery {name:nameAttribute.value})
SET
  n.query=queryAttribute.value
RETURN
  entity as Entity, n.name as Name, n.query as Query
UNION ALL
MATCH
  (entity)-[:ANNOTATED_BY]->(namedQuery:Annotation),
  (namedQuery)-[:OF_TYPE]->(:Type{fqn:'javax.persistence.NamedQuery'}),
  (namedQuery)-[:HAS]->(nameAttribute:Value{name:'name'}),
  (namedQuery)-[:HAS]->(queryAttribute:Value{name:'query'})
MERGE
  (entity)-[:DEFINES]->(n:Jpa:NamedQuery {name:nameAttribute.value})
SET
  n.query=queryAttribute.value
RETURN
  entity as Entity, n.name as Name, n.query as Query

Required concepts:

7.9.2.2. Constraints provided by the JPA 2 plugin
7.9.2.2.1. Constraint jpa2:ValidationModeMustBeExplicitlySpecified

The validation mode of all persistence units must be explicitly specified and either set to CALLBACK or NONE.

MATCH
  (pu:PersistenceUnit)
WHERE
  not exists(pu.validationMode)
  OR NOT (
    pu.validationMode='CALLBACK'
    OR pu.validationMode='NONE'
  )
RETURN
  pu AS PersistenceUnit

7.10. JSON Plugin

Provides a scanner for JSON files

7.10.1. Scanner for JSON Files

Scanner to scan RFC 7159 compliant JSON files.

Note
The tests of our JSON plugin use the JSON files provided by the JSON Parsing Test Suite by Nicolas Serot. The suite hase been created as an appendix to the article Parsing JSON is a Minefield.
7.10.1.1. Limitations

The JSON scanner is able to process the majority of valid and invalid JSON documents. However it can have problems with invalid JSON documents with invalid Unicode characters.

7.10.1.2. Configuration
Table 59. Configuration properties
Property Description

json.file.include

A comma separated list of file name patterns, wildcards (?,\*) are allowed, e.g. /data/town.json.tmpl.

json.file.exclude

A comma separated list of file name patterns, wildcards (?,\*) are allowed, e.g. /data/data.json.

7.10.1.3. Nodes labeled with :Json:File
Table 60. Properties of :Json:File
Name Description

fileName

The file of the JSON document.

valid

Flag to indicate if the JSON document is valid according to RFC 7159.

Table 61. Relations of :Json:File
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Json:Object, Nodes labeled with :Json:Array or Nodes labeled with :Json:Scalar

1

References the contained JSON value.

7.10.1.4. Nodes labeled with :Json:Array
Table 62. Properties of :Json:Array
Name Description

None

Table 63. Relations of :Json:Array
Name Target label(s) Cardinality Description

CONTAINS_VALUE

Nodes labeled with :Json:Object, Nodes labeled with :Json:Array or Nodes labeled with :Json:Scalar

0..n

References a value contained in the array.

7.10.1.5. Nodes labeled with :Json:Key
Table 64. Properties of :Json:Key
Name Description

name

The literal name of the key.

Table 65. Relations of :Json:Key
Name Target label(s) Cardinality Description

HAS_VALUE

Nodes labeled with :Json:Object, Nodes labeled with :Json:Array or Nodes labeled with :Json:Scalar

1

The value associated with the key.

7.10.1.6. Nodes labeled with :Json:Object
Table 66. Properties of :Json:Object
Name Description

None

Table 67. Relations of :Json:Object
Name Target label(s) Cardinality Description

HAS_KEY

Nodes labeled with :Json:Key

0..n

The key of a key value pair in an JSON object.

7.10.1.7. Nodes labeled with :Json:Scalar
Table 68. Properties of :Json:Scalar
Name Description

value

The value itself. The JSON spezification allows to have null values. Therefore the might be no value.

Table 69. Relations of :Json:Scalar
Name Target label(s) Cardinality Description

None

7.10.1.8. Nodes labeled with :Json:Value

The label :Value is only a marker label without any own properties or relationships. It marks only an element of an JSON structure as value associated with an other JSON element.

For example:

  • The elements of an JSON array are labeled as Value.

  • The value of an key value pair is labeled as Value.

Table 70. Properties of :Json:Value
Name Description

None

Table 71. Relations of :Json:Value
Name Target label(s) Cardinality Description

None

7.10.1.9. Examples

This section provides some examples how a JSON document is mapped to a graph structure by the JSON plugin of jQAssistant.

7.10.1.9.1. Object with Array Value
An JSON object with a single key with an array as value
{
  "A": [ "B", "C" ]
}
example 01
Figure 1. Graph structure created out of the source document
7.10.1.9.2. Empty JSON Array
An empty JSON array
[
]
example 02
Figure 2. Graph struture created out of the source document
7.10.1.9.3. Object with an empty Object as Value
An JSON object with an empty Object as Value
{
  "A": { }
}
example 03
Figure 3. Graph struture created out of the source document
7.10.1.9.4. JSON Object with Objects as Value
An JSON object objects as value
{
  "A": {
    "B" : "C",
    "D" : { }
  }
}
example 04
Figure 4. Graph struture created out of the source document

7.11. JUnit Plugin

Provides scanner for JUnit test reports and rules (e.g. for test classes/methods and ignored tests).

7.11.1. Scanner for JUnit4 test suite results

Imports results from JUnit 4 and JUnit 5 test suites written by Maven Surefire and Maven Failsave matching the file name TEST-.xml.

7.11.1.1. Nodes labeled with :File:Junit:TestSuite

A file containing results of a JUnit 4 or JUnit 5 test suite.

Table 72. Properties of :File:JUnit:TestSuite
Name Description

fileName

The file name

name

The name of the test suite, e.g. the name of the class defining the suite

tests

The number of executed tests

failures

The number of failed tests

errors

The number of tests in error

skipped

The number of skipped tests

time

The time it took to run the suite

Table 73. Relations of :File:JUnit:TestSuite
Name Target label(s) Cardinality Description

CONTAINS

[:JUnit::TestCase]

0..n

References test cases

7.11.1.2. :JUnit:TestCase

A test case.

Table 74. Properties of :JUnit::TestCase
Name Description

name

The name of the test, e.g. the name of the test method

className

The name of the class containing the test

time

The time it took to run the test

result

The result of the test, either SUCCESS, FAILURE, ERROR or SKIPPED

Table 75. Relations of :JUnit:TestCase
Name Target label(s) Cardinality Description

HAS_FAILURE

:JUnit:Failure

0..1

References failure details

HAS_ERROR

:JUnit:Error

0..1

References error details

7.11.1.3. :JUnit:Failure

Provides detail information about a test case with result FAILURE.

Table 76. Properties of :JUnit:Failure
Name Description

type

The failure type, e.g. java.lang.AssertionError

details

Detail information, e.g. the stack trace.

7.11.1.4. :JUnit:Error

Provides detail information about a test case with result ERROR.

Table 77. Properties of :JUnit:Error
Name Description

type

The error type, e.g. "java.lang.RuntimeException"

details

Detail information, e.g. the stack trace.

7.11.2. Rules provided by the JUnit plugin

7.11.2.1. Concepts provided by the JUnit plugin
7.11.2.1.1. Concept junit:TestCaseDefinedByClass

Creates a relation DEFINED_BY between all test cases from test reports and the class which defined it.

MATCH
  (testcase:TestCase)
WITH
  testcase
MATCH
  (testclass:Type)
WHERE
  testclass.fqn = testcase.className
MERGE
  (testcase)-[:DEFINED_BY]->(testclass)
RETURN
  testcase.name AS TestCase, testclass AS TestClass
7.11.2.1.2. Concept junit:TestCaseImplementedByMethod

Creates a relation IMPLEMENTED_BY between all test cases from test reports and their implementing methods.

MATCH
  (testcase:TestCase)-[:DEFINED_BY]->(testclass:Type),
  (testclass)-[:EXTENDS*0..]->(:Type)-[:DECLARES]->(testmethod:Method)
WHERE
  testmethod.name = testcase.name
MERGE
  (testcase)-[:IMPLEMENTED_BY]->(testmethod)
RETURN
  testcase.name AS TestCase, testmethod as TestMethod

Required concepts:

7.11.2.1.3. Concept junit3:SetUpMethod

Labels all setUp methods declared by a test class with "SetUp" and "Junit3".

MATCH
  (c:Class:Test:Junit3)-[:DECLARES]->(m:Method)
WHERE
  m.signature = "void setUp()"
SET
  m:SetUp:Junit3
RETURN
  m AS SetUpMethod, c AS TestClass

Required concepts:

7.11.2.1.4. Concept junit3:TearDownMethod

Labels all tearDown methods declared by a test class with "TearDown" and "Junit3".

MATCH
  (c:Class:Test:Junit3)-[:DECLARES]->(m:Method)
WHERE
  m.signature = "void tearDown()"
SET
  m:TearDown:Junit3
RETURN
  m AS TearDownMethod, c AS TestClass

Required concepts:

7.11.2.1.5. Concept junit3:TestClass

Labels all non-abstract classes extending from junit.framework.TestCase "Test" and "Junit3".

MATCH
  (c:Type:Class)-[:EXTENDS*]->(testCaseType:Type)
WHERE
  testCaseType.fqn = "junit.framework.TestCase"
SET
  c:Test:Junit3
RETURN
  c AS TestClass
7.11.2.1.6. Concept junit3:TestMethod

Labels all test methods declared by a test class with "Test" and "Junit3".

MATCH
  (c:Class:Test:Junit3)-[:DECLARES]->(m:Method)
WHERE
  m.signature =~ "void test.*\\(.*\\)"
SET
  m:Test:Junit3
RETURN
  m AS Test, c AS TestClass

Required concepts:

7.11.2.1.7. Concept junit4:AfterClassMethod

Labels all methods annotated by "@org.junit.AfterClass" with "Junit4" and "AfterClass".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.AfterClass"
SET
  m:Junit4:AfterClass
RETURN
  m AS AfterClassMethod, c AS TestClass
7.11.2.1.8. Concept junit4:AfterMethod

Labels all methods annotated by "@org.junit.After" with "Junit4" and "After".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.After"
SET
  m:Junit4:After
RETURN
  m AS AfterMethod, c AS TestClass
7.11.2.1.9. Concept junit4:AssertMethod

Labels all assertion methods declared by org.junit.Assert with "Junit4" and "Assert".

MATCH
  (assertType:Type)-[:DECLARES]->(assertMethod)
WHERE
  assertType.fqn = 'org.junit.Assert'
  and assertMethod.signature =~ 'void assert.*'
SET
  assertMethod:Junit4:Assert
RETURN
  assertMethod
7.11.2.1.10. Concept junit4:BeforeClassMethod

Labels all methods annotated by "@org.junit.BeforeClass" with "Junit4" and "BeforeClass".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.BeforeClass"
SET
  m:Junit4:BeforeClass
RETURN
  m AS BeforeClassMethod, c AS TestClass
7.11.2.1.11. Concept junit4:BeforeMethod

Labels all methods annotated by "@org.junit.Before" with "Junit4" and "Before".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.Before"
SET
  m:Junit4:Before
RETURN
  m AS BeforeMethod, c AS TestClass
7.11.2.1.12. Concept junit4:IgnoreTestClassOrMethod

Labels all classes or methods annotated with "@org.junit.Ignore" with "Junit4" and "Ignore".

MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.Ignore"
SET
  e:Junit4:Ignore
RETURN
  e AS IgnoredElement
7.11.2.1.13. Concept junit4:SuiteClass

Labels all classes annotated by "@org.junit.runners.Suite.SuiteClasses" with "Junit4" and "Suite" and creates a relation "CONTAINS_TESTCLASS" to all referenced classes.

MATCH
  (suite:Type)-[:ANNOTATED_BY]->(suiteClasses)-[:OF_TYPE]->(suiteClassesType:Type)
WHERE
  suiteClassesType.fqn = "org.junit.runners.Suite$SuiteClasses"
SET
  suite:Junit4:Suite
WITH
  suite, suiteClasses
MATCH
  (suiteClasses)-[:HAS]->(:Array:Value)-[:CONTAINS]->(Class:Value)-[:IS]->(testClass:Type)
CREATE UNIQUE
  (suite)-[c:CONTAINS_TESTCLASS]->(testClass)
RETURN
  suite, collect(testClass)
7.11.2.1.14. Concept junit4:TestClass

Labels all classes containing test methods with "Test" and "Junit4".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method:Junit4:Test)
SET
  c:Test:Junit4
RETURN
  c AS TestClass, COLLECT(m) AS TestMethods

Required concepts:

7.11.2.1.15. Concept junit4:TestClassOrMethod

The rule is deprecated: This concept has been replaced by "junit4:TestMethod" and "junit4:TestClass".

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

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method:Junit4:Test)
RETURN
  c AS TestClass, COLLECT(m) AS TestMethods

Required concepts:

7.11.2.1.16. Concept junit4:TestMethod

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
7.11.2.1.17. Concept junit5:AfterAll
Labels all methods annotated by "@org.junit.jupiter.api.AfterAll"
with "Junit5" and "AfterClass".
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.AfterAll"
SET
  m:Junit5:AfterAll
RETURN
  m AS AfterClassMethod, c AS TestClass
7.11.2.1.18. Concept junit5:AfterEach
Labels all methods annotated by "@org.junit.jupiter.api.AfterEach"
with "Junit5" and "After".
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.AfterEach"
SET
  m:Junit5:AfterEach
RETURN
  m AS AfterEachMethod, c AS TestClass
7.11.2.1.19. Concept junit5:AssertMethod
Labels all assertion methods declared by "org.junit.jupiter.api.Assertions" with "Junit5"
and "Assert".
MATCH
  (assertType:Type)-[:DECLARES]->(assertMethod)
WHERE
  assertType.fqn = 'org.junit.jupiter.api.Assertions'
  and assertMethod.signature =~ 'void assert.*'
SET
  assertMethod:Junit5:Assert
RETURN
  assertMethod
7.11.2.1.20. Concept junit5:BeforeAll
Labels all methods annotated by "@org.junit.jupiter.api.BeforeAll"
with "Junit5" and "BeforeClass".
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.BeforeAll"
SET
  m:Junit5:BeforeAll
RETURN
  m AS BeforeClassMethod, c AS TestClass
7.11.2.1.21. Concept junit5:BeforeEach
Labels all methods annotated by "@org.junit.jupiter.api.BeforeEach"
with "Junit5" and "Before".
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.BeforeEach"
SET
  m:Junit5:BeforeEach
RETURN
  m AS BeforeMethod, c AS TestClass
7.11.2.1.22. Concept junit5:DisabledTestClassOrMethod
Labels all classes or methods annotated with "@org.junit.jupiter.api.Disabled"
with "Junit5" and "Ignore".
MATCH
  (e)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.Disabled"
SET
  e:Junit5:Disabled
RETURN
  e AS IgnoredElement
7.11.2.1.23. Concept junit5:NestedTestClass

Labels all nested test classes annotated with "@org.junit.jupiter.api.Nested", independently from the number of tests contained in the method, with "Junit5" and "Nested".

MATCH
  (c:Type:Class)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(n:Type)
WHERE
  n.fqn = "org.junit.jupiter.api.Nested"
SET
  c:Junit5:Nested
RETURN
  c
7.11.2.1.24. Concept junit5:ParameterizedTestMethod
Finds all test methods (i.e. annotated with "@org.junit.jupiter.api.ParameterizedTest") and
labels them with "Test", "Parameterized", and "Junit5".
MATCH
  (m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.params.ParameterizedTest"
SET
  m:Parameterized:Test:Junit5
RETURN
  m AS Test
7.11.2.1.25. Concept junit5:RepeatedTestMethod
Finds all test methods (i.e. annotated with "@org.junit.jupiter.api.Test") and
labels them with "Test", "Repeated", and "Junit5".
MATCH
  (m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.RepeatedTest"
SET
  m:Repeated:Test:Junit5
RETURN
  m AS Test
7.11.2.1.26. Concept junit5:TaggedClass
Labels all methods annotated by "@org.junit.jupiter.api.Tag"
with "Junit5", and "Tag".
MATCH
  (c:Type:Class)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.Tag"
SET
  c:Junit5:Tag
RETURN
  c AS TestClass
UNION
MATCH
  (c:Type:Class)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(tags:Type),
  (a)-[:HAS]->(v:Array:Value)-[:CONTAINS]->(b:Annotation:Value)-[:OF_TYPE]->(tag:Type)
SET
  c:Junit5:Tag
RETURN
  c AS TestClass

Required concepts:

7.11.2.1.27. Concept junit5:TaggedClassTags
Collects all tags of classes annotated with
"@org.junit.jupiter.api.Tag" and containing test methods (":Test:Method:Junit5")
and stores them in an array property of the class descriptor.
MATCH
  (c:Type:Class)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(tag:Type),
  (c:Type:Class)-[:DECLARES]->(m:Method:Junit5:Test),
  // (m:Method)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(tag:Type),
  (a)-[:HAS]->(tagValue:Value)
WHERE
  tag.fqn="org.junit.jupiter.api.Tag"
WITH
  collect(distinct tagValue.value) AS tagValues, c
SET
  c.tags = tagValues, c:Test:Junit5
RETURN
  c
UNION
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method:Test:Junit5),
  (c:Type:Class)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(tags:Type),
  (a)-[:HAS]->(v:Array:Value)-[:CONTAINS]->(b:Annotation:Value)-[:OF_TYPE]->(tag:Type),
  (b)-[:HAS]->(tagValue:Value)
WHERE
  tags.fqn="org.junit.jupiter.api.Tags"
  AND tag.fqn="org.junit.jupiter.api.Tag"
WITH
  collect(distinct tagValue.value) AS tagValues, c
SET
  c.tags = tagValues, c:Test:Junit5
RETURN
  c
7.11.2.1.28. Concept junit5:TaggedClassWithMetaAnnotation
Labels all classes annotated by an Junit meta annotation
with "Junit5", and "Tag".
MATCH
  (c:Java:Type)-[:ANNOTATED_BY]->(a:Annotation)
  -[:OF_TYPE]->(metaAnn:Java:Type:Annotation)
  -[:ANNOTATED_BY]->(tagAnn:Java:Annotation)
  -[:OF_TYPE]->(tagAnnType:Java:Type { name: 'Tag'})
SET
  c:Tag:Junit5
RETURN
  c AS TaggedClass

UNION

MATCH
   (c:Java:Type)
   -[:ANNOTATED_BY]->(a:Annotation)
   -[:OF_TYPE]->(metaAnn:Annotation)
   -[:ANNOTATED_BY]->(tags:Annotation)
   -[:OF_TYPE]->(tagsType { fqn: 'org.junit.jupiter.api.Tags' }),

   (tags)-[:HAS]->(v:Array:Value)
   -[:CONTAINS]->(b:Annotation:Value)
   -[:OF_TYPE]->(tag:Type { fqn: 'org.junit.jupiter.api.Tag' })
SET
   c:Tag:Junit5
RETURN
   c AS TaggedClass

Required concepts:

7.11.2.1.29. Concept junit5:TaggedMethod
Labels all methods annotated by "@org.junit.jupiter.api.Tag"
with "Junit5", "Test" and "Tag".
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method:Junit5:Test)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.Tag"
SET
  m:Junit5:Test:Tag
RETURN
  m AS TestMethod, c AS TestClass
UNION
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method:Test:Junit5)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(tags:Type),
  (a)-[:HAS]->(v:Array:Value)-[:CONTAINS]->(b:Annotation:Value)-[:OF_TYPE]->(tag:Type)
WHERE
  tags.fqn="org.junit.jupiter.api.Tags"
  AND tag.fqn="org.junit.jupiter.api.Tag"
SET
  m:Junit5:Test:Tag
RETURN
  m AS TestMethod, c AS TestClass

Required concepts:

7.11.2.1.30. Concept junit5:TaggedMethodTags

Collects all tags of methods annotated with "@org.junit.jupiter.api.Tag" and "@org.junit.jupiter.api.Test" and stores them in an array property of the method descriptor.

MATCH
    (c:Type:Class)-[:DECLARES]->(m:Method),
    (m:Method)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(tags:Type),
    (a)-[:HAS]->(v:Array:Value)-[:CONTAINS]->(b:Annotation:Value)-[:OF_TYPE]->(tag:Type),
    (b)-[:HAS]->(tagValue:Value)

WHERE
    tags.fqn="org.junit.jupiter.api.Tags"
    AND tag.fqn="org.junit.jupiter.api.Tag"

WITH
    collect(distinct tagValue.value) AS tagValues, m

SET
    m.tags = tagValues

RETURN
    m

UNION

MATCH
    (c:Type:Class)-[:DECLARES]->(m:Method),
    (m:Method)-[:ANNOTATED_BY]->(a:Annotation)-[:OF_TYPE]->(t:Type),
    (a:Annotation)-[:HAS]->(v:Value)

WHERE
    t.fqn="org.junit.jupiter.api.Tag"

WITH
    collect(distinct v.value) as tagValues, m

SET
    m.tags = tagValues

RETURN
    m
7.11.2.1.31. Concept junit5:TaggedMethodWithMetaAnnotation
Labels all methods annotated by an Junit meta annotation
with "Junit5", "Test" and "Tag".
MATCH
  (meth:Java:Method:Junit5:Test)-[:ANNOTATED_BY]->(a:Annotation)
  -[:OF_TYPE]->(metaAnn:Java:Type:Annotation)
  -[:ANNOTATED_BY]->(tagAnn:Java:Annotation)
  -[:OF_TYPE]->(tagAnnType:Java:Type { name: 'Tag'})
SET
  meth:Tag
RETURN
  meth AS TestMethod

UNION

MATCH
   (meth:Java:Method:Junit5:Test)
    -[:ANNOTATED_BY]->(a:Annotation)
   -[:OF_TYPE]->(metaAnn:Annotation)
   -[:ANNOTATED_BY]->(tags:Annotation)
   -[:OF_TYPE]->(tagsType { fqn: 'org.junit.jupiter.api.Tags' }),

   (tags)-[:HAS]->(v:Array:Value)
   -[:CONTAINS]->(b:Annotation:Value)
   -[:OF_TYPE]->(tag:Type { fqn: 'org.junit.jupiter.api.Tag' })
SET
   meth:Tag
RETURN
   meth AS TestMethod

Required concepts:

7.11.2.1.32. Concept junit5:TestClass

Labels all classes containing test methods with "Test" and "Junit5".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method:Junit5:Test)
SET
  c:Test:Junit5
RETURN
  c AS TestClass, COLLECT(m) AS TestMethods

Required concepts:

7.11.2.1.33. Concept junit5:TestMethod
Finds all test methods (i.e. annotated with "@org.junit.jupiter.api.Test") and
labels them with "Test" and "Junit5".
MATCH
  (m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.Test"
SET
  m:Test:Junit5
RETURN
  m AS Test
7.11.2.1.34. Concept junit5:TestTemplateMethod
Labels all methods annotated by "@org.junit.jupiter.api.TestTemplate"
with "Junit5", "Test" and "Template".
MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.junit.jupiter.api.TestTemplate"
SET
  m:Junit5:Test:Template
RETURN
  m AS AfterClassMethod, c AS TestClass
7.11.2.2. Constraints provided by the JUnit plugin
7.11.2.2.1. Constraint junit:AssertionMustProvideMessage

All assertions must provide a message.

MATCH
  (testType:Type)-[:DECLARES]->(testMethod:Method),
  (testMethod)-[invocation:INVOKES]->(assertMethod:Assert:Method)
WHERE
  NOT assertMethod.signature =~ 'void assert.*\\(java.lang.String,.*\\)'
RETURN
  invocation AS Invocation,
  testType AS DeclaringType,
  testMethod AS Method

Required concepts:

7.11.2.2.2. Constraint junit:IgnoreWithoutMessage

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
UNION
MATCH
  (e)-[:ANNOTATED_BY]->(disabled:Annotation)-[:OF_TYPE]->(disabledType:Type)
WHERE
  disabledType.fqn = "org.junit.jupiter.api.Disabled"
  AND NOT (disabled)-[:HAS]->(:Value{name:"value"})
RETURN
  e AS IgnoreWithoutMessage
7.11.2.2.3. Constraint junit:TestMethodWithoutAssertion

All test methods must perform assertions (within a call hierarchy of max. 3 steps).

MATCH
  (testType:Type)-[:DECLARES]->(testMethod:Test:Method)
WHERE
  NOT (testMethod)-[:INVOKES*..3]->(:Method:Assert)
RETURN
  testType AS DeclaringType,
  testMethod AS Method

Required concepts:

7.12. Maven 2 Repository Plugin

Provides a scanner for maven repositories.

7.12.1. Scanner for remote Maven repositories

Downloads the repository index and retrieves all available new artifacts for scanning.

This plugin should be triggered on the command line by providing an URL and a specific scope:

Examples:

>jqassistant.cmd scan -u maven:repository::http://[<user>:<password>@]<repository url>
>jqassistant.cmd scan -u maven:repository::http://foo:bar@example.com/m2repo
Tip
The plugin supports incremental runs on a maven repository. In this case only new artifacts will be downloaded and scanned. For incremental scanning it is necessary that the exactly the same URL is provided on sub-sequent scans.
7.12.1.1. Configuration
Table 78. Configuration properties
Property Description Default

m2repo.directory

The directory for locally storing the downloaded artifacts (i.e. a local Maven repository).

m2repo.filter.includes

A comma separated list of artifact patterns to include in the scan

include all artifacts

m2repo.filter.excludes

A comma separated list of artifact patterns to exclude from the scan

exclude no artifacts

m2repo.artifacts.scan

A boolean value. If true then the content of the artifacts is scanned, otherwise only the model.

false

m2repo.artifacts.keep

A boolean value. If false then all downloaded artifacts are deleted after scanning.

true

Tip
The artifact patterns follow the Maven syntax, i.e. [groupId]:[artifactId]:[type]:[version] or [groupId]:[artifactId]:[type]:[classifier]:[version] and allow using wildcards.
7.12.1.2. Nodes labeled with :Maven:Repository

A remote Maven repository.

Table 79. Properties of :Maven:Repository
Name Description

url

the remote URL

lastUpdate

timestamp of the last scan

Table 80. Relations of :Maven:Repository
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Maven:GroupId

0..n

The artifact groups contained in the repository

CONTAINS_POM

[:Maven:Pom:Xml]

0..n

References the POMs in the repository

CONTAINS_ARTIFACT

Nodes labeled with :Maven:Artifact

0..n

References the artifacts in the repository

7.12.1.3. Nodes labeled with :Maven:Release

Qualifies Nodes labeled with :Maven:Pom and Nodes labeled with :Maven:Artifact nodes as released Maven versions.

Table 81. Properties of :Release
Name Description

fqn

The fully qualified name of the artifact.

lastModifed

Timestamp of the last modification that is reported for the artifact.

7.12.1.4. Nodes labeled with :Maven:Snapshot

Qualifies Nodes labeled with :Maven:Pom and Nodes labeled with :Maven:Artifact nodes as Maven snapshot versions.

Table 82. Properties of :Snapshot
Name Description

fqn

The fully qualified name of the artifact.

lastModifed

timestamp of the last modification that is reported for the artifact

7.12.1.5. Nodes labeled with :Maven:GroupId

Represents a group coordinate within Nodes labeled with :Maven:Repository.

Table 83. Properties of :GroupId
Name Description

name

The group name

Table 84. Relations of :Maven:GroupId
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Maven:ArtifactId

0..n

The contained artifacts

7.12.1.6. Nodes labeled with :Maven:ArtifactId

Represents artifact coordinate within Nodes labeled with :Maven:GroupId.

Table 85. Properties of :ArtifactId
Name Description

name

The artifact name

Table 86. Relations of :Maven:ArtifactId
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Maven:Version

0..n

The contained artifact versions

7.12.1.7. Nodes labeled with :Maven:Version

Represents a version coordinate within Nodes labeled with :Maven:ArtifactId.

Table 87. Properties of :Version
Name Description

name

The version

Table 88. Relations of :Maven:Version
Name Target label(s) Cardinality Description

CONTAINS

Nodes labeled with :Maven:Artifact

0..n

The contained artifacts

7.13. Maven 3 Plugin

Provides a scanner for Maven 3 modules.

7.13.1. Scanner for Maven projects

Imports information from Maven projects.

7.13.1.1. Configuration
Table 89. Configuration properties
Property Description Default

maven.dependencies.scan

If set to true the declared dependencies will be scanned.

false

maven.dependencies.includes

A comma separated list of artifact patterns to include in the dependency scan

include all artifacts

maven.dependencies.excludes

A comma separated list of artifact patterns to exclude from the dependeny scan

exclude no artifacts

Tip
The dependency tree is available as (project:Maven:Project)-[:CREATES]→(:Artifact)-[:DEPENDS_ON*]→(dependency:Artifact). If scanning of dependencies is enabled the included artifacts can be controlled using the includes and excludes filter. They follow the Maven syntax, i.e. [groupId]:[artifactId]:[type]:[version] or [groupId]:[artifactId]:[type]:[classifier]:[version] and allow using wildcards.
7.13.1.2. Nodes labeled with :Maven:Project:File:Directory

A pom.xml file describing a single Maven project.

Table 90. Properties of :Maven:Project:File:Directory
Name Description

fileName

The directory of the project.

name

The name

groupId

The group id

artifactId

The artifact id

packaging

The packaging type, e.g. jar

version

The version

Table 91. Relations of :Maven:Project:File:Directory
Name Target label(s) Cardinality Description

CREATES

Nodes labeled with :Maven:Artifact

0..n

References an artifact created by the project

HAS_MODEL

Nodes labeled with :Maven:Pom

1

References the POM model of the project

HAS_EFFECTIVE_MODEL

Nodes labeled with :Maven:Pom

1

References the effective POM model of the project

HAS_PARENT

Nodes labeled with :Maven:Project:File:Directory

0..1

References the parent project (optional)

HAS_MODULE

Nodes labeled with :Maven:Project:File:Directory

0..n

References modules of this project (optional)

7.13.1.3. Nodes labeled with :Maven:Artifact

Represents an artifact, e.g. a JAR-File.

Note
The artifact is further labeled with :Main representing the main artifact and :Test representing the test artifact.
Table 92. Properties of :Maven:Artifact
Name Description

group

The group name

name

The artifact name

type

The type, e.g. jar

classifier

The classifier

version

The version

Table 93. Relations of :Maven:Artifact
Name Target label(s) Cardinality Description

CONTAINS

:File

0..n

References a file contained in the artifact

DEPENDS_ON

Nodes labeled with :Maven:Artifact

0..n

References an artifact which is a declared dependency

Table 94. Properties of :DEPENDS_ON
Name Description

scope

The declared scope, e.g. compile

optional

true indicates that this dependency is optional.

7.13.2. Scanner for Maven POMs

Imports information from Maven POMs (e.g. pom.xml) files.

7.13.2.1. Nodes labeled with :Maven:Scm
Table 95. Properties of :Maven:Scm

Name

Description

connection

The read-only URL to access the repository.

developerConnection

The URL to access the repository for reading and writing.

tag

The tag that this project lives under.

url

The publicly browsable URL of the repository

7.13.2.2. Nodes labeled with :Maven:Pom

A POM describing a Maven project.

Table 96. Properties of :Maven:Pom
Name Description

group

The group id

name

The artifact id

type

The type, e.g. jar

classifier

The classifier (optional)

url

The URL of the project home

version

The version

Table 97. Relations of :Maven:Pom
Name Target label(s) Cardinality Description

HAS_SCM

Nodes labeled with :Maven:Scm

0..1

References the Source Control Management information of the POM

HAS_PARENT

Nodes labeled with :Maven:Pom

0..1

References a parent artifact

HAS_PROPERTY

:Value:Property

0..n

References a property

HAS_PROFILE

Nodes labeled with :Maven:Profile

0..n

References defined profiles

USES_LICENSE

Nodes labeled with :Maven:License

0..n

References used licenses

MANAGES_DEPENDENCY

Nodes labeled with :Maven:Dependency

0..n

References a managed dependency

DECLARES_DEPENDENCY

Nodes labeled with :Maven:Dependency

0..n

References a declared dependency

HAS_MODULE

Nodes labeled with :Maven:Module

0..n

References a sub module

MANAGES_PLUGIN

Nodes labeled with :Maven:Plugin

0..n

References a managed plugin

USES_PLUGIN

Nodes labeled with :Maven:Plugin

0..n

References a plugin that is used during maven lifecycle

HAS_CONTRIBUTOR

:Maven:Contributor

0..n

References a contributor

HAS_DEVELOPER

:Maven:Developer

0..n

References a developer

HAS_ORGANIZATION

:Maven:Organization

0..1

References the organization behind the project

HAS_REPOSITORY

Nodes labeled with :Maven:Repository

0..1

References a repository declared for this project.

Note
A Nodes labeled with :Maven:Pom node may be further qualified by a label Effective indication that it represents the effective (i.e. interpolated) model of a Maven project or artifact.
7.13.2.3. Nodes labeled with :Maven:Dependency

A declared or managed dependency of Nodes labeled with :Maven:Pom.

Table 98. Properties of :Maven:Dependency
Name Description

scope

The scope of the dependency, e.g. provided.

optional

Indicates the dependency as optional if set to true.

Table 99. Relations of :Maven:Dependency
Name Target label(s) Cardinality Description

TO_ARTIFACT

Nodes labeled with :Maven:Artifact

1

References the artifact used for the dependency.

EXCLUDES

Nodes labeled with :Maven:Exclusion

0..n

The exclusions to apply for the dependency.

7.13.2.4. Nodes labeled with :Maven:Exclusion

Describes an exclusion pattern for Nodes labeled with :Maven:Dependency.

Table 100. Properties of :Maven:Dependency
Name Description

groupId

The groupdId pattern

artifactId

The artifactId pattern

7.13.2.5. :Maven:Contributor

A contributor of the project.

Table 101. Properties of :Maven:Contributor
Name Description

id

The unique ID of the developer in the SCM

email

The email address of the developer.

name

The full name of the developer.

organization

The organization to which the contributor belongs.

organizationUrl

The URL of the organization.

timezone

The timezone the developer is in.

url

The URL for the homepage of the developer.

Table 102. Relations of :Maven:Contributor
Name Target label(s) Cardinality Description

HAS_ROLES

:Maven:Role

0..n

References a role the contributor has in the project.

7.13.2.6. :Maven:Developer

A developer taking part in the development of the project.

Table 103. Properties of :Maven:Developer
Name Description

id

The unique ID of the developer in the SCM

email

The email address of the developer.

name

The full name of the developer.

organization

The organization to which the contributor belongs.

organizationUrl

The URL of the organization.

timezone

The timezone the developer is in.

url

The URL for the homepage of the developer.

Table 104. Relations of :Maven:Developer
Name Target label(s) Cardinality Description

HAS_ROLES

:Maven:Role

0..n

References a role the developer has in the project.

7.13.2.7. :Maven:Organization

The organization behind the project.

Table 105. Properties of :Maven:Organization
Name Description

name

The name of the organization.

url

The URL of the organization.

7.13.2.8. Nodes labeled with :Maven:Repository

A Maven repository declared for a Maven POM or a profile in a Maven POM.

Table 106. Properties of :Maven:Repository
Name Description

name

The name of the repository.

layout

The layout of the repository.

releasesEnabled

Flag if this repository is enabled for releases.

releasesChecksumPolicy

The checksum policy to be used for releases provided by this repository.

releasesUpdatePolicy

The update policy to be used for releases provided by this repository.

snapshotsEnabled

Flag if this repository is enabled for snapshots.

snapshotsChecksumPolicy

The checksum policy to be used for snapshots provided by this repository.

snapshotsUpdatePolicy

The update policy to be used for snapshots provided by this repository.

url

The URL of the repository.

7.13.2.9. :Maven:Role

The roles a person plays in the project.

Table 107. Properties of :Maven:Role
Name Description

name

The name of the role a person plays in the project.

7.13.2.10. Nodes labeled with :Maven:Profile

A maven profile

Table 108. Properties of :Maven:Profile
Name Description

id

The profile id

Table 109. Relations of :Maven:Profile
Name Target label(s) Cardinality Description

HAS_PROPERTY

:Value:Property

0..n

References a property

MANAGES_DEPENDENCY

Nodes labeled with :Maven:Artifact

0..n

References an artifact which is a managed dependency

DECLARES_DEPENDENCY

Nodes labeled with :Maven:Dependency

0..n

References a declared plugin dependency

HAS_MODULE

Nodes labeled with :Maven:Module

0..n

References a sub module

MANAGES_PLUGIN

Nodes labeled with :Maven:Plugin

0..n

References a managed plugin

USES_PLUGIN

Nodes labeled with :Maven:Plugin

0..n

References a plugin that is used during maven lifecycle

HAS_ACTIVATION

Nodes labeled with :Maven:ProfileActivation

0..1

References the conditions which will trigger the profile.

HAS_REPOSITORY

Nodes labeled with :Maven:Repository

0..1

References a repository declared for this profile.

7.13.2.11. Nodes labeled with :Maven:ProfileActivation

A maven profile activation

Table 110. Properties of :Maven:ProfileActivation
Name Description

activeByDefault

Specifies if the profile is activated by default

jdk

Specifies jdk needed to activate the profile

Table 111. Relations of :Maven:ProfileActivation
Name Target label(s) Cardinality Description

HAS_PROPERTY

:Value:Property

0..1

References a property

ACTIVATED_BY_FILE

Nodes labeled with :Maven:ActivationFile

0..1

References file specification used to activate a profile

ACTIVATED_BY_OS

Nodes labeled with :Maven:ActivationOS

0..1

References os specification used to activate a profile

7.13.2.12. Nodes labeled with :Maven:ActivationFile

File specification used to activate a profile

Table 112. Properties of :Maven:ActivationFile
Name Description

exists

Specifies the name of the file that should exist to activate a profile

missing

Specifies the name of the file that should be missing to activate a profile

7.13.2.13. Nodes labeled with :Maven:ActivationOS

Defines operating system’s attributes to activate a profile

Table 113. Properties of :Maven:ActivationOS
Name Description

arch

Specifies the architecture of the OS to be used to activate a profile

family

Specifies the general family of the OS to be used to activate a profile

name

Specifies the name of the OS to be used to activate a profile

version

Specifies the version of the OS to be used to activate a profile

7.13.2.14. Nodes labeled with :Maven:Module

A Maven module

Table 114. Properties of :Maven:Module
Name Description

name

The module name

7.13.2.15. Nodes labeled with :Maven:Plugin

A Maven plugin. The Maven artifact of the plugin can be found through the outgoing IS_ARTIFACT relation.

Table 115. Properties of :Maven:Plugin
Name Description

inherited

Whether any configuration should be propagated to child POMs

Table 116. Relations of :Maven:Plugin
Name Target label(s) Cardinality Description

DECLARES_DEPENDENCY

Nodes labeled with :Maven:Artifact

0..n

References the dependencies of the plugin

HAS_EXECUTION

Nodes labeled with :Maven:PluginExecution

0..n

References a PluginExecution

HAS_CONFIGURATION

Nodes labeled with :Maven:Configuration

0..1

References the configuration for the plugin

IS_ARTIFACT

Nodes labeled with :Maven:Artifact

1

References Maven artifact representing the Maven plugin

7.13.2.16. Nodes labeled with :Maven:License

A used license

Table 117. Properties of :Maven:License
Name Description

name

The full legal name of the license.

url

The official url for the license text.

comments

Addendum information pertaining to this license.

distribution

The primary method by which this project may be distributed.

7.13.2.17. Nodes labeled with :Maven:PluginExecution

A plugin execution

Table 118. Properties of :Maven:PluginExecution
Name Description

id

The plugin id

inherited

Whether any configuration should be propagated to child POMs.

phase

The build lifecycle phase to bind the goals in this execution to.

Table 119. Relations of :Maven:PluginExecution
Name Target label(s) Cardinality Description

HAS_GOAL

Nodes labeled with :Maven:ExecutionGoal

0..n

The goals to execute with the given configuration

HAS_CONFIGURATION

Nodes labeled with :Maven:Configuration

0..1

References the configuration for the plugin

7.13.2.18. Nodes labeled with :Maven:Configuration

A configuration for plugins, executions

Table 120. Relations of :Maven:Configuration
Name Target label(s) Cardinality Description

CONTAINS

:Java:Value

0..n

References a value or a list of values

7.13.2.19. Nodes labeled with :Maven:ExecutionGoal

A goal for plugin executions

Table 121. Properties of :Maven:ExecutionGoal
Name Description

name

The name of the goal

7.13.3. Rules provided by the Maven 3 plugin

7.13.3.1. Constraints provided by the Maven 3 plugin
7.13.3.1.1. Constraint maven3:HierarchicalParentModuleRelation

If a parent Maven project declares a module then the parent project must also be declared as the parent of the module (i.e. to keep the project hierarchy consistent).

match
  (parent:Maven:Project)-[:HAS_MODULE]->(module:Maven:Project)
where
  not (module)-[:HAS_PARENT]->(parent)
return
  module as InvalidModule

7.14. OSGi Plugin

Provides rules for OSGi bundles (e.g. Bundles, Activator).

7.14.1. Rules provided by the OSGi plugin

7.14.1.1. Concepts provided by the OSGi plugin
7.14.1.1.1. Concept osgi-bundle:Activator

Creates an ACTIVATES relation between a class and the bundle artifact if the class is declared as "Bundle-Activator" in the bundle manifest.

match
  (bundle:Osgi:Bundle)-[:CONTAINS]->(manifest:File:Manifest),
  (manifest)-[:DECLARES]->(section:ManifestSection),
  (section)-[:HAS]->(entry:ManifestEntry),
  (bundle)-[:CONTAINS]->(activator:Class)
where
  entry.name = "Bundle-Activator"
  and entry.value = activator.fqn
create unique
  (activator)-[:ACTIVATES]->(bundle)
return
  activator as Activator, bundle as Bundle

Required concepts:

7.14.1.1.2. Concept osgi-bundle:Bundle

Labels all artifacts with a manifest declaring a bundle name as "Osgi" and "Bundle" and adds the properties "bundleSymbolicName" and "bundleVersion".

MATCH
  (bundle:Artifact)-[:CONTAINS]->(manifest:Manifest:File),
  (manifest)-[DECLARES]->(section:ManifestSection),
  (section)-[:HAS]->(nameEntry:ManifestEntry),
  (section)-[:HAS]->(versionEntry:ManifestEntry)
WHERE
  nameEntry.name = "Bundle-SymbolicName"
  AND versionEntry.name = "Bundle-Version"
SET
  bundle:Osgi:Bundle,
  bundle.bundleSymbolicName = nameEntry.value,
  bundle.bundleVersion = versionEntry.value
RETURN
  bundle as Bundle, bundle.bundleSymbolicName as BundleSymbolicName, bundle.bundleVersion as BundleVersion
7.14.1.1.3. Concept osgi-bundle:ExportPackage

Creates an EXPORTS relation from a bundle artifact to all packages which are declared as "Export-Package" in the bundle manifest.

match
 (bundle:Osgi:Bundle)-[:CONTAINS]->(package:Package)
with
  bundle, package, "(^|.*,)\\s*"+ replace(package.fqn, ".", "\\.")+"\\s*((;|,).*|$)" as pattern
match
  (bundle)-[:CONTAINS]->(manifest:File:Manifest),
  (manifest)-[:DECLARES]->(section:ManifestSection),
  (section)-[:HAS]->(entry:ManifestEntry)
where
  entry.name = "Export-Package"
  AND entry.value=~ pattern
create unique
  (bundle)-[:EXPORTS]->(package)
return
  bundle as Bundle, collect(package) as ExportedPackages

Required concepts:

7.14.1.1.4. Concept osgi-bundle:ImportPackage

Creates an IMPORTS relation from a bundle artifact to all packages which are declared as "Import-Package" in the bundle manifest.

match
 (package:Package)
with
  package, "(^|.*,)\\s*"+ replace(package.fqn, ".", "\\.")+"\\s*((;|,).*|$)" as pattern
match
  (bundle:Osgi:Bundle)-[:CONTAINS]->(manifest:File:Manifest),
  (manifest)-[:DECLARES]->(section:ManifestSection),
  (section)-[:HAS]->(entry:ManifestEntry)
where
  entry.name = "Import-Package"
  and entry.value =~ pattern
create unique
  (bundle)-[:IMPORTS]->(package)
return
  bundle as Bundle, collect(package) as ImportedPackages

Required concepts:

7.14.1.1.5. Concept osgi-bundle:InternalType

Labels all internal types (i.e. which are not located in an exported package) as "Internal".

match
  (bundle:Bundle:Osgi)-[:CONTAINS]->(internalPackage:Package),
  (bundle)-[:CONTAINS]->(internalType:Type),
  (internalPackage)-[:CONTAINS]->(internalType:Type)
where not
    (bundle)-[:EXPORTS]->(internalPackage)
set
  internalType:Internal
return bundle as Bundle, collect(internalType) as InternalTypes

Required concepts:

7.14.1.2. Constraints provided by the OSGi plugin
7.14.1.2.1. Constraint osgi-bundle:InternalTypeMustNotBePublic

Internal types must not be public if no depending types exist in other packages of the bundle.

match
  (bundle:Osgi:Bundle)-[:CONTAINS]->(internalType:Type:Internal),
  (internalPackage:Package)-[:CONTAINS]->(internalType)
optional match
  (bundle)-[:CONTAINS]->(otherPackage:Package),
  (otherPackage)-[:CONTAINS]->()-[:DEPENDS_ON]->(internalType)
where
  internalType.visibility='public'
with
  bundle, internalPackage, internalType, collect(otherPackage) as otherPackages
where
  all(otherPackage in otherPackages where internalPackage = otherPackage)
  and not
    (internalType)-[:ACTIVATES]->(bundle)
return
  bundle as Bundle, internalType as InternalType

Required concepts:

7.14.1.2.2. Constraint osgi-bundle:UnusedInternalType

A bundle must not contain internal types which are not used by other types in the bundle.

match
  (bundle:Osgi:Bundle)-[:CONTAINS]->(internalType:Type:Internal)
where not (
    (internalType)-[:ACTIVATES]->(bundle)
  or
    (bundle)-[:CONTAINS]->(:Type)-[:DEPENDS_ON]->(internalType)
)
return
  bundle as Bundle, internalType as InternalType

Required concepts:

7.15. RDBMS Plugin

Provides a scanner for importing the metadata of a relational database schema.

7.15.1. Scanner for metadata of a relational database schema

Imports the metadata of a relational database schema, i.e. schemas, tables and columns.

NOTE The JDBC driver must be available on the jQAssistant classpath, e.g. as dependency of the Maven plugin or copied to the plugins/ folder of the distribution.

7.15.1.1. Connection URI scanner

The connection information may be specified as URI using scope rdbms:connection, e.g. on the command line

jqassistant.sh scan -u rdbms:connection::jdbc:oracle:thin:username/password@host:1521:sid
7.15.1.2. Connection property file scanner

The connection properties can also be read from property files having a file name with prefix jqassistant.plugin.rdbms, e.g. jqassistant.plugin.rdbms_test.properties. Each of them must contain at least the properties driver, url, user and password, e.g.

rdbms_test.properties
## Required configuration properties
driver=org.hsqldb.jdbc.JDBCDriver
url=jdbc:hsqldb:file:target/myDatabase
user=SA
password=

## Optional properties which are passed to Schema Crawler (http://schemacrawler.sourceforge.net/), they affect the level of queried information.

## The name of the database specific driver provided by schema crawler, supported values are "sybaseiq", "sqlserver", "sqlite", "postgresql", "oracle", "mysql", "hsqldb", "derby", "db2"
# bundled_driver=mysql

## It may be necessary to use another info level for performance or compatibility reasons, e.g. if a database does not support retrieving metadata for stored
## procedures you might try to set "retrieve_routines=false". Allowed values are "standard", "minimum", "maximum" or "detailed"
# info_level=standard

## Activation/deactivation of single options on the selected info level
# retrieve_additional_column_attributes=true
# retrieve_additional_database_info=true
# retrieve_additional_jdbc_driver_info=true
# retrieve_additional_table_attributes=true
# retrieve_foreign_keys=true
# retrieve_indices=true
# retrieve_index_information=true
# retrieve_routines=true
# retrieve_routine_columns=true
# retrieve_routine_information=true
# retrieve_schema_crawler_info=true
# retrieve_sequence_information=true
# retrieve_tables=true
# retrieve_table_columns=true
# retrieve_trigger_information=true
# retrieve_view_information=true
7.15.1.3. Nodes labeled with :Rdbms:Connection:Properties

Represents a file containing the connection properties described above which have been used to read the schema metadata. It provides the same properties and relations as [:File:Properties].

Table 122. Relations of :Rdbms:Connection:Properties
Name Target label(s) Cardinality Description

DESCRIBES_SCHEMA

Nodes labeled with :Rdbms:Schema

1

References the schema

7.15.1.4. Nodes labeled with :Rdbms:Schema

Describes a database schema.

Table 123. Properties of :Rdbms:Schema
Name Description

name

The name of the schema.

Table 124. Relations of :Rdbms:Schema
Name Target label(s) Cardinality Description

HAS_TABLE

Nodes labeled with :Rdbms:Table

0..n

References the tables in the schema

HAS_VIEW

Nodes labeled with :Rdbms:View

0..n

References the views in the schema

HAS_SEQUENCE

Nodes labeled with :Rdbms:Sequence

0..n

References the sequences in the schema

7.15.1.5. Nodes labeled with :Rdbms:Table

Describes a database table.

Table 125. Properties of :Rdbms:Table
Name Description

name

The name of the table.

Table 126. Relations of :Rdbms:Table
Name Target label(s) Cardinality Description

HAS_COLUMN

Nodes labeled with `:Rdbms:Column

0..n

References the columns of the table

HAS_PRIMARY_KEY

Nodes labeled with :Rdbms:PrimaryKey

0..1

References the primary key of the table

HAS_INDEX

Nodes labeled with :Rdbms:Index

0..*

References indices defined for the table

7.15.1.6. Nodes labeled with :Rdbms:View

Describes a database view.

Table 127. Properties of .Rdbms:View
Name Description

name

The name of the view.

Table 128. Relations of :Rdbms:View
Name Target label(s) Cardinality Description

HAS_COLUMN

Nodes labeled with `:Rdbms:Column

0..n

References the columns of the view

7.15.1.7. Nodes labeled with `:Rdbms:Column

Describes a column of a table.

Table 129. Properties of :Rdbms:Column
Name Description

name

The name of the column

autoIncremented

Indicates an auto incremented value

generated

Indicates a generated value

defaultValue

The default value

size

The size of the column

decimalDigits

The number of digits for decimal types

partOfIndex

Indicates that the column is part of an index

partOfPrimaryKey

Indicates that the column is part of the primary key

partOfForeignKey

Indicates that the column is part of a foreign key

Table 130. Relations of :Rdbms:Column
Name Target label(s) Cardinality Description

OF_COLUMN_TYPE

Nodes labeled with :Rdbms:ColumnType

1

References the column type

7.15.1.8. Nodes labeled with :Rdbms:ColumnType

Describes a column data type, e.g. VARCHAR.

Table 131. Properties of :Rdbms:ColumnType
Name Description

databaseType

The database specific name of the type

autoIncrementable

Indicates that values of this type can auto incremented

precision

The precision

minimumScale

The minimum scale

maximumScale

The maximum scale

fixedPrecisionScale

The fixed precision scale

numericPrecisionRadix

The numeric precision radix

caseSensitive

Indicates that the type is case sensitive

unsigned

Indicates that the type is unsigned

userDefined

Indicates that the type is user defined

7.15.1.9. Nodes labeled with :Rdbms:PrimaryKey

Describes a primary key of a table.

Table 132. Properties of :Rdbms:PrimaryKey
Name Description

name

The name of the primary key.

Table 133. Relations of :Rdbms:PrimaryKey
Name Target label(s) Cardinality Description

ON_PRIMARY_KEY_COLUMN

Nodes labeled with :Rdbms:ColumnType

1

References a primary key column

7.15.1.10. ON_PRIMARY_KEY_COLUMN

Describes the properties of a column in a primary key.

Table 134. Properties of ON_PRIMARY_KEY_COLUMN
Name Description

indexOrdinalPosition

The ordinal position of the column in the primary key.

sortSequence

The sort sequence, i.e. "ascending" or "descending".

7.15.1.11. Nodes labeled with :Rdbms:Index

Describes an index defined for table.

Table 135. Properties of :Rdbms:Index
Name Description

name

The name of the index.

unique

true if the index is unique.

cardinality

The cardinality of the index.

indexType

The index type.

pages

The pages.

Table 136. Relations of :Rdbms:Index
Name Target label(s) Cardinality Description

ON_INDEX_COLUMN

Nodes labeled with :Rdbms:ColumnType

1

References an indexed column

7.15.1.12. ON_INDEX_COLUMN

Describes the properties of a column used by an index.

Table 137. Properties of ON_INDEX_COLUMN
Name Description

indexOrdinalPosition

The ordinal position of the column in the primary key.

sortSequence

The sort sequence, i.e. ascending or descending.

7.15.1.13. Nodes labeled with `:Rdbms:ForeignKey

Describes a foreign key.

Table 138. Properties of :Rdbms:ForeignKey
Name Description

name

The name of the foreign key

deferrability

The deferrability

deleteRule

The delete rule, e.g. cascade

updateRule

The update rule

Table 139. Relations of :Rdbms:ForeignKey
Name Target label(s) Cardinality Description

HAS_FOREIGN_KEY_REFERENCE

Nodes labeled with :Rdbms:ForeignKeyReference

1..n

The foreign key references

7.15.1.14. Nodes labeled with :Rdbms:ForeignKeyReference

Describes a foreign key reference, i.e. a pair consisting of a foreign key referencing a primary key.

Table 140. Relations of :Rdbms:ForeignKeyReference
Name Target label(s) Cardinality Description

FROM_FOREIGN_KEY_COLUMN

Nodes labeled with `:Rdbms:Column

1

The foreign key column

TO_PRIMARY_KEY_COLUMN

Nodes labeled with `:Rdbms:Column

1

The primary key column

7.15.1.15. Nodes labeled with :Rdbms:Sequence

Describes a database sequence.

Table 141. Properties of :Rdbms:Sequence
Name Description

name

The name of the sequence

minimumValue

The minimum value

maximumValue

The maximum value

increment

The increment

cycle

Indicates that the sequence restarts at the minimumValue if the the maximumValue has been reached.

7.16. Spring Plugin

Provides rules for applications using the Spring framework.

7.16.1. Rules provided by the Spring plugin

7.16.1.1. Concepts provided by the Spring plugin
7.16.1.1.1. Concept spring-boot:Application

Labels all Spring Boot Applications with "Spring", "Application", "Configuration" and "Component".

MATCH
  (application:Type:Class)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.boot.autoconfigure.SpringBootApplication"
SET
  application:Spring:Boot:Application:Configuration:Component
RETURN
  application as Application
7.16.1.1.2. Concept spring-component:AnnotatedInjectables

Labels all Spring Components as "Injectable".

MATCH
  (injectableComponent:Spring)
SET
  injectableComponent:Injectable
RETURN
  injectableComponent as InjectableComponent

Required concepts:

7.16.1.1.3. Concept spring-component:Component

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

MATCH
  (component:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn in [
    "org.springframework.stereotype.Component",
    "org.springframework.boot.autoconfigure.SpringBootApplication",
    "org.springframework.context.annotation.Configuration",
    "org.springframework.data.web.config.SpringDataWebConfigurationMixin",
    "org.springframework.stereotype.Controller",
    "org.springframework.stereotype.Repository",
    "org.springframework.stereotype.Service",
    "org.springframework.web.bind.annotation.ControllerAdvice",
    "org.springframework.web.bind.annotation.RestController"
  ]
SET
  component:Spring:Component:Injectable
RETURN
  component as Component
7.16.1.1.4. Concept spring-component:Configuration

Labels all types annotated with "@org.springframework.context.annotation.Configuration" with "Spring", "Configuration" and "Injectable".

MATCH
  (configuration:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn in [
    "org.springframework.context.annotation.Configuration",
    "org.springframework.boot.autoconfigure.SpringBootApplication",
    "org.springframework.data.web.config.SpringDataWebConfigurationMixin"
  ]
SET
  configuration:Spring:Configuration:Injectable
RETURN
  configuration as Configuration
7.16.1.1.5. Concept spring-component:Controller

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

MATCH
  (controller:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn in [
    "org.springframework.stereotype.Controller",
    "org.springframework.web.bind.annotation.RestController"
  ]
SET
  controller:Spring:Controller:Injectable
RETURN
  controller as Controller

Required concepts:

7.16.1.1.6. Concept spring-component:Repository

Returns all repositories.

MATCH
  (repository:Spring:Repository:Injectable)
RETURN
  repository as Repository

Required concepts:

7.16.1.1.7. Concept spring-component:Service

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

MATCH
  (service:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn in [
    "org.springframework.stereotype.Service"
  ]
SET
  service:Spring:Service:Injectable
RETURN
  service as Service
7.16.1.1.8. Concept spring-component:VirtualDependency

The rule is deprecated: This concept has been replaced by the more generic concept "java:VirtualDependsOn".

Creates a VIRTUAL_DEPENDS_ON relation between Spring Components which are connected through interfaces or abstract types.

MATCH
   (component:Spring:Injectable)-[:DEPENDS_ON]->(superType)<-[:IMPLEMENTS|EXTENDS*]-(otherComponent:Spring:Injectable)
WHERE
  component <> otherComponent
  and not (component)-[:EXTENDS|IMPLEMENTS*]->(superType) // exclude components sharing the same super classes/interfaces
MERGE
  (component)-[d:VIRTUAL_DEPENDS_ON]->(otherComponent)
RETURN
  component as Dependent, collect(distinct otherComponent) as Dependencies

Required concepts:

7.16.1.1.9. Concept spring-data:AnnotatedRepository

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

MATCH
  (repository:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.stereotype.Repository"
SET
  repository:Spring:Repository:Injectable
RETURN
  repository as Repository
7.16.1.1.10. Concept spring-data:ImplementedRepository

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

MATCH
  (repository:Type)-[:EXTENDS|IMPLEMENTS*]->(superType:Type)
WHERE
  superType.fqn in [
    "org.springframework.data.repository.Repository",
    "org.springframework.data.repository.CrudRepository",
    "org.springframework.data.repository.PagingAndSortingRepository",
    "org.springframework.data.jpa.repository.JpaRepository",
    "org.springframework.data.jpa.repository.support.SimpleJpaRepository",
    "org.springframework.data.jpa.repository.support.QueryDslJpaRepository"
  ]
SET
  repository:Spring:Repository:Injectable
RETURN
  repository as Repository
7.16.1.1.11. Concept spring-injection:BeanProducer

Labels methods which are annotated with "@org.springframework.context.annotation.Bean" with "BeanProducer" and their return types with "Spring" and "Injectable".

MATCH
   (:Type)-[:DECLARES]->(beanProducer:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type),
   (beanProducer)-[:RETURNS]->(injectable:Type)
 WHERE
   annotationType.fqn = "org.springframework.context.annotation.Bean"
 SET
   injectable:Spring:Injectable,
   beanProducer:Spring:BeanProducer
 RETURN
   injectable as Injectable, beanProducer as BeanProducer
7.16.1.1.12. Concept spring-injection:Injectable

Returns all injectables.

MATCH
  (injectable:Spring:Injectable)
RETURN
  injectable as Injectable

Required concepts:

7.16.1.1.13. Concept spring-injection:InjectionPoint
Labels all type members annotated with "@org.springframework.beans.factory.annotation.Autowired",
"javax.inject.Inject" or "javax.annotation.Resource" with "Spring" and "InjectionPoint".
MATCH
  (injectionPoint:Member)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn in [
    "org.springframework.beans.factory.annotation.Autowired",
    "javax.inject.Inject",
    "javax.annotation.Resource"
  ]
SET
  injectionPoint:Spring:InjectionPoint
RETURN
  injectionPoint as InjectionPoint
7.16.1.1.14. Concept spring-mvc:RestController

Labels all types annotated with "@org.springframework.web.bind.annotation.RestController" with "Spring", "RestController", "Controller" and "Injectable".

MATCH
  (restController:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.web.bind.annotation.RestController"
SET
  restController:Spring:RestController:Controller:Injectable
RETURN
  restController as RestController
7.16.1.1.15. Concept spring-transaction:TransactionalClass
Label all classes annotated with "@org.springframework.transaction.annotation.Transactional"and their declared methods with "Spring" and
"Transactional".
MATCH
  (transactionalClass:Class)-[:EXTENDS*0..]->(:Class)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.transaction.annotation.Transactional"
SET
  transactionalClass:Spring:Transactional
WITH
  transactionalClass
MATCH
  (transactionalClass)-[:DECLARES]->(transactionalMethod:Method)
WHERE NOT (
  transactionalMethod:Constructor
  or (exists(transactionalMethod.static) and transactionalMethod.static)
)
SET
  transactionalMethod:Spring:Transactional
RETURN
  transactionalClass as TransactionalClass, collect(transactionalMethod) as TransactionalMethods
7.16.1.1.16. Concept spring-transaction:TransactionalMethod
Label all methods which are annotated with "@org.springframework.transaction.annotation.Transactional" with "Spring" and "Transactional".
MATCH
  (type:Type)-[:DECLARES]->(transactionalMethod:Method),
  (transactionalMethod:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(annotationType:Type)
WHERE
  annotationType.fqn = "org.springframework.transaction.annotation.Transactional"
  or type:Spring:Transactional
SET
  transactionalMethod:Spring:Transactional
RETURN
  transactionalMethod as TransactionalMethod

Required concepts:

7.16.1.2. Constraints provided by the Spring plugin
7.16.1.2.1. Constraint spring-boot:AllTypesInApplicationPackage

All types of of a Spring Boot application must be located in the same package or a sub-package of the application class.

MATCH
  (artifact:Artifact),
  (artifact)-[:CONTAINS]->(applicationPackage:Package)-[:CONTAINS]->(application:Spring:Boot:Application),
  (artifact)-[:CONTAINS]->(package:Package)-[:CONTAINS]->(type:Type)
WHERE NOT
  (artifact:Test OR (applicationPackage)-[:CONTAINS*0..]->(package))
RETURN
  application as Application, applicationPackage as ApplicationPackage, collect(type) as TypesOutsideApplicationPackage

Required concepts:

7.16.1.2.2. Constraint spring-component:ControllerMustOnlyDependOnServicesRepositories

A Spring controller can only have dependencies to other Spring components that are services or repositories.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(controller:Spring:Controller)-[:DEPENDS_ON|VIRTUAL_DEPENDS_ON]->(other:Spring:Injectable)
WHERE NOT (
   artifact:Test
   or other:Service
   or other:Repository
)
RETURN
  controller as Controller, collect(other) as InvalidDependencies

Required concepts:

7.16.1.2.3. Constraint spring-component:RepositoryMustOnlyDependOnRepositories

A Spring repository can only have dependencies to other Spring components that are repositories.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(repository:Spring:Repository)-[:DEPENDS_ON|VIRTUAL_DEPENDS_ON]->(other:Spring:Injectable)
WHERE NOT (
  artifact:Test
  or other:Repository
)
RETURN
  repository as Repository, collect(other) as InvalidDependencies

Required concepts:

7.16.1.2.4. Constraint spring-component:ServiceMustOnlyDependOnServicesRepositories
A Spring service can only have dependencies to other Spring components that are services or repositories.
MATCH
  (artifact:Artifact)-[:CONTAINS]->(service:Spring:Service)-[:DEPENDS_ON|VIRTUAL_DEPENDS_ON]->(other:Spring:Injectable)
WHERE NOT (
  artifact:Test
  or other:Service
  or other:Repository
)
RETURN
  service as Service, collect(other) as InvalidDependencies

Required concepts:

7.16.1.2.5. Constraint spring-injection:AvoidAwareInterfacesInFavorOfInjection

Prefer to inject framework components over implementing '…Aware' interfaces.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:IMPLEMENTS]->(otherType:Type)
WHERE
  NOT artifact:Test
  AND otherType.fqn in [
    "org.springframework.beans.factory.BeanFactoryAware",
    "org.springframework.context.ApplicationContextAware",
    "org.springframework.context.ApplicationEventPublisherAware"
  ]
RETURN
  type as Type, otherType as ImplementedInterface
7.16.1.2.6. Constraint spring-injection:AvoidDisposableBean

Prefer to use @PreDestroy over implementing DisposableBean.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:IMPLEMENTS]->(otherType:Type)
WHERE
  NOT artifact:Test
  AND otherType.fqn = "org.springframework.beans.factory.DisposableBean"
RETURN
  type as Type
7.16.1.2.7. Constraint spring-injection:AvoidInitializingBean

Prefer to use @PostConstruct over implementing InitializingBean.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:IMPLEMENTS]->(otherType:Type)
WHERE
  NOT artifact:Test
  AND otherType.fqn = "org.springframework.beans.factory.InitializingBean"
RETURN
  type as Type
7.16.1.2.8. Constraint spring-injection:BeanProducerMustBeDeclaredInConfigurationComponent

Bean producer methods must be declared in configuration components.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:DECLARES]->(beanProducer:Method:BeanProducer)-[:RETURNS]->(injectable:Injectable)
WHERE NOT (
  artifact:Test
  OR type:Spring:Configuration
)
RETURN
  beanProducer as BeanProducer, injectable as Injectable

Required concepts:

7.16.1.2.9. Constraint spring-injection:FieldInjectionIsNotAllowed

Field injection is not allowed, use constructor injection instead.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:DECLARES]->(field:Field:InjectionPoint)
WHERE NOT
   artifact:Test
RETURN
  type as Type, field as Field

Required concepts:

7.16.1.2.10. Constraint spring-injection:FieldsOfInjectablesMustNotBeManipulated

Fields of injectable types must not be manipulated, except from constructors.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(injectable:Injectable),
  (injectable)-[:DECLARES]->(field:Field)-[:OF_TYPE]->(fieldType:Type),
  (injectable)-[:DECLARES]->(method:Method),
  (method)-[writes:WRITES]->(field)
WHERE
  (fieldType)-[:ASSIGNABLE_FROM*0..]->(:Injectable)
  AND NOT (
   artifact:Test
   OR method:Constructor // method is a constructor
   OR (exists(field.synthetic) AND field.synthetic) // synthetic fields, e.g. generated by Groovy
)
RETURN
   injectable as Injectable, writes as WriteToInjectableField, field as Field

Required concepts:

7.16.1.2.11. Constraint spring-injection:InjectablesMustNotBeAccessedStatically

Injectable components must not be accessed from static variables.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:DECLARES]->(field:Field)-[:OF_TYPE]->(fieldType:Type),
  (method:Method)-[:WRITES|READS]->(field)
WHERE
  (fieldType)-[:ASSIGNABLE_FROM*0..]->(:Injectable)
  AND field.static
  AND NOT artifact:Test
RETURN
  method as Method, field.name as Field

Required concepts:

7.16.1.2.12. Constraint spring-injection:InjectablesMustNotBeHeldInStaticVariables

Injectable components must not be held in static variables.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:DECLARES]->(field:Field)-[:OF_TYPE]->(fieldType:Type)
WHERE
  (fieldType)-[:ASSIGNABLE_FROM*0..]->(:Injectable)
  AND field.static
  AND NOT artifact:Test
RETURN
  type as Type, field.name as Field

Required concepts:

7.16.1.2.13. Constraint spring-injection:InjectablesMustNotBeInstantiated

If the constructor of an Injectable is called from another Injectable, then the caller must be a BeanProducer.

MATCH
  (injectable:Injectable:Type)-[:DECLARES]->(constructor:Constructor),
  (artifact:Artifact)-[:CONTAINS]->(type:Injectable:Type)-[:DECLARES]->(method:Method),
  shortestPath((method)-[:INVOKES*]->(constructor))
WHERE NOT (
  artifact:Test
  OR method:Spring:BeanProducer
)
RETURN
  type as Type, method as Method, injectable as Injectable

Required concepts:

7.16.1.2.14. Constraint spring-injection:InjectablesShouldBeHeldInFinalFields

Fields holding injectables should be declared final.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(source:Type:Injectable)-[declares:DECLARES]->(field:Field)-[:OF_TYPE]->(target:Type:Injectable)
WHERE NOT (
  artifact:Test
  OR (exists(field.final) AND field.final = true)
  OR (exists(field.synthetic) AND field.synthetic) // synthetic fields, e.g. generated by Groovy
)
RETURN
  source as InjectableType, field as InjectableField

Required concepts:

7.16.1.2.15. Constraint spring-transaction:TransactionalMethodMustNotBeInvokedFromSameClass

Transactional methods must not be invoked from the same class.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(type:Type)-[:DECLARES]->(calledMethod:Method:Spring:Transactional),
  (type:Type)-[:DECLARES]->(callingMethod:Method),
  (callingMethod:Method)-[invokes:INVOKES]->(calledMethod)
WHERE NOT (
  artifact:Test
  OR callingMethod:Method:Spring:Transactional
  OR type:Spring:Transactional
)
RETURN
  type as Type, callingMethod as Method, calledMethod as TransactionalMethod, invokes.lineNumber as LineNumber

Required concepts:

7.17. TestNG Plugin

Provides rules for TestNG.

7.17.1. Rules provided by the TestNG plugin

7.17.1.1. Concepts provided by the TestNG plugin
7.17.1.1.1. Concept testng:AfterClassMethod

Labels all methods annotated by "@org.testng.annotations.AfterClass" with "TestNG" and "AfterClassMethod".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.AfterClass"
SET
  m:TestNG:AfterClassMethod
RETURN
  m AS AfterClassMethod, c AS TestClass
7.17.1.1.2. Concept testng:AfterMethod

Labels all methods annotated by "@org.testng.annotations.AfterMethod" with "TestNG" and "AfterMethod".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.AfterMethod"
SET
  m:TestNG:AfterMethod
RETURN
  m AS AfterMethod, c AS TestClass
7.17.1.1.3. Concept testng:AfterTestMethod

Labels all methods annotated by "@org.testng.annotations.AfterTest" with "TestNG" and "AfterTestMethod".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.AfterTest"
SET
  m:TestNG:AfterTestMethod
RETURN
  m AS AfterTestMethod, c AS TestClass
7.17.1.1.4. Concept testng:BeforeClassMethod

Labels all methods annotated by "@org.testng.annotations.BeforeClass" with "TestNG" and "BeforeClassMethod".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.BeforeClass"
SET
  m:TestNG:BeforeClassMethod
RETURN
  m AS BeforeClassMethod, c AS TestClass
7.17.1.1.5. Concept testng:BeforeMethod

Labels all methods annotated by "@org.testng.annotations.BeforeMethod" with "TestNG" and "BeforeMethod".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.BeforeMethod"
SET
  m:TestNG:BeforeMethod
RETURN
  m AS BeforeMethod, c AS TestClass
7.17.1.1.6. Concept testng:BeforeTestMethod

Labels all methods annotated by "@org.testng.annotations.BeforeTest" with "TestNG" and "BeforeTestMethod".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method),
  (m:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.BeforeTest"
SET
  m:TestNG:BeforeTestMethod
RETURN
  m AS BeforeTestMethod, c AS TestClass
7.17.1.1.7. Concept testng:TestClass

Labels all classes containing test methods with "Test" and "TestNG".

MATCH
  (c:Type:Class)-[:DECLARES]->(m:Method:TestNG:Test)
SET
  c:Test:TestNG
RETURN
  c AS TestClass, COLLECT(m) AS TestMethods

Required concepts:

7.17.1.1.8. Concept testng:TestMethod

Finds all test methods (i.e. annotated with "@org.testng.annotations.Test") and labels them with "Test" and "TestNG".

MATCH
  (m:Method)-[:ANNOTATED_BY]-()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="org.testng.annotations.Test"
SET
  m:Test:TestNG
RETURN
  m AS Test

7.18. Tycho Plugin

Provides a scanner for tycho modules.

7.18.1. Scanner for Tycho projects

Adds Tycho specific resources to be scanned to the file system scanner.

7.19. XML Plugin

Provides scanners for XML and XSD documents.

7.19.1. Scanner for XML files

Imports all XML in a generic representation, e.g. namespaces, elements, attributes and text, using the Scanner for XML sources. The files to scan may be configured using include and exclude filters.

7.19.1.1. Configuration
Table 142. Configuration properties
Property Description Default

xml.file.include

A comma separated list of file name patterns, wildcards (?,*) are allowed, e.g. /*-INF/ejb-jar.xml.

xml.file.exclude

A comma separated list of file name patterns, wildcards (?,*) are allowed, e.g. /*-INF/ejb-jar.xml.

7.19.2. Scanner for XML sources

Imports all XML documents in a generic representation, e.g. namespaces, elements, attributes and text.

This plugin is internally used by other plugins (e.g. Scanner for XML files) to create an alternative native structure of XML documents.

7.19.2.1. :Xml:Document

Represents an XML document.

Table 143. Properties of :Xml:Document
Name Description

xmlVersion

The XML version

standalone

The "standalone" attribute of the XML declaration.

characterEncodingScheme

The encoding of the XML file.

xmlWellFormed

Indicates if the document is well-formed, i.e. could be parsed.

lineNumber

Last line number

Table 144. Relations of :Xml:Document
Name Target label(s) Cardinality Description

HAS_ROOT_ELEMENT

:Xml:Element

1

References the root element of the document.

7.19.2.2. :Xml:Element

An XML element.

Table 145. Properties of :Xml:Element
Name Description

value

The text value.

lineNumber

Last line number of the start tag of the element.

Table 146. Relations of :Xml:Element
Name Target label(s) Cardinality Description

DECLARES_NAMESPACE

:Xml:Namespace

0..n

References namespaces which are declared on the element.

OF_NAMESPACE

:Xml:Namespace

0..1

References the namespace of the element.

HAS_ELEMENT

:Xml:Element

0..n

References child elements of the element.

HAS_ATTRIBUTE

:Xml:Attribute

0..n

References attributes of the element.

HAS_TEXT

:Xml:Text

0..n

References the text values of the element.

7.19.2.3. :Xml:Namespace

A XML namespace declaration.

Table 147. Properties of :Xml:Namespace
Name Description

uri

The namespace URI.

prefix

The optional namespace prefix

7.19.2.4. :Xml:Attribute

An XML attribute.

Table 148. Properties of :Xml:Attribute
Name Description

name

The name of the atribute.

value

The value of the attribute.

Table 149. Relations of :Xml:Attribute
Name Target label(s) Cardinality Description

OF_NAMESPACE

:Xml:Namespace

0..1

References the namespace of the attribute.

7.19.2.5. :Xml:Text

A text value of an XML element.

Table 150. Properties of :Xml:Text
Name Description

value

The text value.

lineNumber

Last line number

7.19.3. Generic scanner for XSD files

Imports all files with the file name suffix ".xsd" using the Scanner for XML files.

7.20. YAML Plugin

Provides a scanner for YAML files

7.20.1. Generic scanner for YAML files

Imports YAML 1.1 files in a generic representation for jQAssistant.

Seen from a more formal perspective a YAML document is build by a tree of nodes. Each node can have one of the following values as content: scalar value, sequence or mapping. This plugin imports a YAML file in a simplified manner as simply model of keys and values. See section Examples for examples.

Important
This YAML scanner does not support the full YAML 1.1 specification as is is intended to help to scan and validate YAML configuration files with the help of a simple graph model. If you need an better support for YAML files, please report a feature request.
7.20.1.1. Activation of the plugin

The YAML scanner is not activated by default for the jQAssistant Plugin for Maven, but for the commandline tool for jQAssistant. To activated for the jQAssistant for Maven it must be added to the list of dependencies as shown below.

<plugin>
    <groupId>com.buschmais.jqassistant/groupId>
    <artifactId>jqassistant-maven-plugin</artifactId>
    <version>{projectVersion}</version>
    <dependencies>
        <dependency>
            <groupId>com.buschmais.jqassistant.plugin</groupId>
            <artifactId>jqassistant.plugin.yaml</artifactId>
            <version>{projectVersion}</version>
        </dependency>
    </dependencies>
</plugin>
7.20.1.2. Nodes labeled with :File:YAML

A file with the file extension .yaml containing zero or more YAML documents.

Table 151. Relations of :File:YAML
Name Target label(s) Cardinality Description

CONTAINS_DOCUMENT

:Document:YAML

0..n

References a document in the file

Table 152. Properties of :File:YAML
Name Description

valid

Property to indicate if the documents of this file have been parsed successfully or not. If the YAML scanner was able to parse all documents, this property is true. Otherwise it is false. This property can be used to check if all of your YAML files could have been parsed or not.

An non-parsable file with YAML documents will not have any outgoing relationships to any dependent YAML documents. Please consider this aspect when writing your queries.

7.20.1.3. :Document:YAML
Table 153. Relations of :Document:YAML
Name Target label(s) Cardinality Description

CONTAINS_VALUE

Nodes labeled with :Key:YAML

0..n

References a key in the containing document

CONTAINS_KEY

Nodes labeled with :Value:YAML

0..n

References a value in the containing document

7.20.1.4. Nodes labeled with :Key:YAML
Table 154. Properties of :Key:YAML
Name Description

name

The name of the key

fqn

The full qualified name of the key. It is build by joining all parent keys and the name of the current key with a dot as delimiter

Table 155. Relations of :Key:YAML

Name

Target label(s)

Cardinality

Description

CONTAINS_KEY

Nodes labeled with :Key:YAML

0..n

References a child key of the containing key

CONTAINS_VALUE

Nodes labeled with :Value:YAML

0..n

References a value assigned to the key

7.20.1.5. Nodes labeled with :Value:YAML

Nodes tagged with :Value:YAML represents YAML scalars assigned to a Nodes labeled with :Key:YAML.

Table 156. Properties of :Value:YAML

Name

Description

value

The value itself.

Table 157. Relations of :Value:YAML

Name

Target label(s)

Cardinality

Description

CONTAINS_VALUE

Nodes labeled with :Value:YAML

0..n

References a child value assigned to this value

7.20.1.6. Examples

Not written yet.