jqa

This document describes the concepts of jQAssistant and usage information.

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. Quickstart

2.1. Command Line

Requirements

  • Java Development Kit 11 or later

  • optional JAVA_HOME environment variable pointing to the JDK to be used for jQAssistant

Installation

  • The latest command line distributions are available for download from Maven Central by selecting distribution.zip from the Download menu:

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

Note
jQAssistant releases until 2.0.x are available here.

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.

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

2.2. Maven

Requirements

  • Maven 3.5 or later

  • Java Development Kit 11 or later

Add the plugin

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

<project>
    <properties>
        <!-- Define your desired jQAssistant version here -->
        <jqassistant.version>2.1.0</jqassistant.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>com.buschmais.jqassistant</groupId>
                <artifactId>jqassistant-maven-plugin</artifactId>
                <version>${jqassistant.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>scan</goal>
                            <goal>analyze</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Add a rule

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

jqassistant/my-rules.adoc
= My Project

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

[[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[role=include]

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.

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

3. Introduction

This chapter provides an introduction to the concepts of jQAssistant.

3.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)

3.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.

3.3. Rules

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

my-rules.xml
<jqassistant-rules xmlns="http://schema.jqassistant.org/rule/v1.10"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://schema.jqassistant.org/rule/v1.10 https://schema.jqassistant.org/rule/jqassistant-rule-v1.10.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>

    <concept id="my-rules:MyProvidingConcept">
        <providesConcept refId="java:GeneratedType"/>
        <description>A human readable description of the concept.</description>
        <cypher><![CDATA[
            MATCH
              ...
            WHERE
              ...
            SET
              type:Generated
            RETURN
              ...
        ]]></cypher>
    </concept>

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

</jqassistant-rules>

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:*.

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.

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.

  • "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.

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.

Rule Dependencies

As shown in the snippets above concepts or constraints may define dependencies to other concepts. There are two approaches:

requiresConcept (XML) or requiresConcepts (Asciidoc)

A rule explicitly requires another concept to be executed before.

providesConcept (XML) or providesConcepts (Asciidoc)

A concept extends another concept by adding the same labels or relationships.

The rules are referenced by their ids. jQAssistant will ensure that these rules are executed in the correct order.

Usually dependencies are expressed using requiresConcept(s), e.g. a constraint requires one or more specific concepts. These concepts again might require other concepts.

There may be situation where pre-defined constraints and required concepts are defined within a plugin. In this case it can become necessary to extend such concepts with project-specific concepts, e.g. to work with generated code:

  • Constraints defined by the Spring plugin delivered with jQAssistant verify correct usage of dependency injection

  • These constraints exclude all Java types labeled with :Type:Generated and therefore require the concept java:GeneratedType which is defined by the Java plugin

  • This concept may be extended by project specific concepts adding labels :Type:Generated and declaring the provided concept java:GeneratedType using providesConcept(s)

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>

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)

Warnings and Failures

Based on the severity of violated rules jQAssistant generates warnings and failures. These are based on configurable thresholds:

  • jqassistant.analyze.report.warn-on-severity (default: minor)

  • jqassistant.analyze.report.fail-on-severity (default: major)

The warnings and failures are logged on the console and part of generated reports (e.g. XML or Asciidoc).

Furthermore, the setting jqassistant.analyze.report.continue-on-failure (default: false) controls whether jQAssistant will continue or break the build failures have been detected during analysis.

Tip
If violations are exported to dashboards (e.g. SonarQube, Teamscale) then jqassistant.analyze.report.continue-on-failure should be set to true.

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">
        store.beginTransaction()
        // 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++;
            }
            // Create the row and columns for the result
            var columns = new java.util.HashMap();
            columns.put("Class", context.toColumn(type));
            columns.put("MethodsOfType", context.toColumn(methodsOfType));
            var row = context.toRow(rule, columns);
            rows.add(row);
        }
        store.commitTransaction()
        // 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>

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.

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.

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>

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>
  • 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

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>
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>
Note
The first column will be used automatically if no primary column is explicitly specified.

4. 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

4.1. Configuration

The recommended way of configuring jQAssistant is using a file .jqassistant.yml located in the working directory. Available options are described in the section Configuration.

Furthermore, the following command line specific configuration properties are supported:

jqassistant:

  # Defines the local and remote Maven repositories for retrieving additional plugins.
  repositories:
    # The path to the local repository.
    #
    # -Djqassistant.repositories.local (optional)
    local: ~/.jqassistant/repository
    remotes:
      central:
        # The URL of the Maven repository
        #
        # -Djqassistant.repositories.central.url
        url:
        # The user name for authenticating against the repository
        #
        # -Djqassistant.repositories.central.username (optional)
        username:
        # The password for authenticating against the repository
        #
        # -Djqassistant.repositories.central.password (optional)
        password:

  # The optional proxy to use for downloading additional plugins
  proxy:
    # The protocol of the proxy
    #
    # -Djqassistant.proxy.protocol (optional)
    protocol: https
    # The proxy host
    #
    # -Djqassistant.proxy.host
    host:
    # The proxy port
    #
    # -Djqassistant.proxy.port
    port:
    # The list of hosts which should not be proxied, separated by ',' or '|', the wildcard '*' is allowed.
    #
    # -Djqassistant.proxy.non-proxy-hosts (optional)
    non-proxy-hosts:
    # The proxy password for authentication
    #
    # -Djqassistant.proxy.password (optional)
    password:
Note
Plugins will be downloaded using the configured local and remote Maven repositories (default: Maven Central). If a file ~/.m2/settings.xml exists (i.e. user specific Maven settings) the configuration from there will be used including mirrors and proxies as well as repositories, pluginRepositories and properties from active profiles.

4.2. Options

  • -configurationLocations <files> <directories>

    • the list of configuration locations, e.g. YAML files and directories

    • default: '.jqassistant.yml, .jqassistant.yaml, .jqassistant/*.yml, .jqassistant/**.yaml'

  • -mavenSettings <file>

    • the location of a Maven settings.xml file to use for repository, proxy and mirror configurations

  • -D key1=value1 [-D key2=value]

    • one or more configuration properties to extend or overwrite the existing configuration

4.3. Tasks

scan

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/
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

available-scopes

List all available scopes which may be specified for scanning.

analyze

Executes an analysis.

available-rules

List all available rules.

effective-configuration

Print the current configuration as YAML representation on the console.

effective-rules

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

list-plugins

Lists all plugins known to jQAssistant. Helpful to check which plugins are active during the scan and analysis.

jqassistant.sh list-plugins

report

Transforms an XML report into HTML.

server

Starts the integrated Neo4j web server.

5. 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.

5.1. Setup

Project Scope

The jQAssistant Maven plugins uses a root Maven module where the following items will be searched or created:

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

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

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

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

  • additional reports (e.g. CSV), default: "{project.build.directory}/jqassistant/report")

By default the root module is the directory, where the mvn command has been executed.

For reactors where multiple projects are built requiring different databases, rule sets, etc. the flag jqassistant.use-execution-root-as-project-root can be set to false. The jQAssistant Maven plugin will then detect the different project roots by searching within the module tree starting from the current module following the parent relation until either a module is found where a directory "jqassistant/" exists or no further parent is defined. 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.

Plugin Configuration

The recommended way of configuring the jQAssistant Maven plugin is using a file .jqassistant.yml located in the root directory of the reactor. Available options are described in the section Configuration.

Furthermore, the following Maven specific option is supported:

jqassistant:

  maven:
    # Force the module where 'mvn' is being executed to be used as root module. The database will be created in this module and contain all information of the reactor. Rules will be read from the rules folder of this module.
    #
    # jqassistant.maven.use-execution-root-as-project-root: true|false
    use-execution-root-as-project-root: false

    # Re-use store instances across all modules of the Maven reactor. Can be set to false for mitigating problems in specific setups,
    # the jQAssistant Maven plugin will display an according hint when this is necessary.
    #
    # jqassistant.maven.reuse-store: true|false
    reuse-store: true

  # Properties for module level goals (e.g. scan)
  module:

    # Skip goals which are executed per module, useful to exclude single modules from `scan`.
    # NOTE: 'jqassistant.skip' applies to all goals (e.g. scan, analyze)
    #
    # jqassistant.maven.module.skip: true|false
    skip: false
Tip
Maven properties (e.g. project.basedir) or user properties defined in pom.xml or settings.xml files can be referenced in YAML files by using the ${…​} syntax, e.g. ${project.basedir}/src/main.

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

Setup of the jQAssistant Maven plugin including supported configuration options and their default values (within comments).
<project>

    <build>
        <plugins>
            <plugin>
                <groupId>com.buschmais.jqassistant</groupId>
                <artifactId>jqassistant-maven-plugin</artifactId>
                <version>2.1.0</version>
                <executions>
                    <execution>
                        <!-- The id "default-cli" is used to allow execution of the goals with the given configuration from the command line -->
                        <id>default-cli</id>
                        <goals>
                            <goal>scan</goal>
                            <goal>analyze</goal>
                        </goals>
                        <!--
                        <extensions>false</extensions>
                        -->
                        <configuration>
                            <!--
                            <configurationLocations>
                                <configurationLocation>${project.basedir}/.jqassistant.yml</configurationLocation>
                            </configurationLocations>
                            <yaml>
                                jqassistant:
                                  skip: true
                            <yaml>
                            -->
                        </configuration>
                    </execution>
                </executions>
            </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>2.1.0</version>
                <reportSets>
                    <reportSet>
                        <reports>
                            <report>report</report>
                        </reports>
                    </reportSet>
                </reportSets>
            </plugin>
        </plugins>
    </reporting>

</project>
configurationLocations (-Djqassistant.configuration.locations)
  • the list of configuration locations, e.g. files and directories

  • default: '.jqassistant.yml, .jqassistant.yaml, .jqassistant/*.yml, .jqassistant/**.yaml'

yaml
  • embedded YAML configuration

  • can be used as an alternative to the .jqassistant.yml file, e.g. to provide the pom.xml as a parent with a pre-defined jQAssistant configuration

Note
Properties of the embedded YAML configuration can be overwritten by the file based configuration within the project.

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

5.2. Goals

jqassistant:scan

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

jqassistant:available-scopes

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

jqassistant:reset

Resets the database by deleting all nodes and relationships.

jqassistant:server

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

jqassistant:analyze

Executes an analysis.

Note
If for a multi-module project a report archive shall be created and installed into the local repository the Maven Install Plugin must be configured to use installAtEnd. In a similar way for deploying the report archive to a remote repository deployAtEnd must be actived for the Maven Deploy Plugin.

jqassistant:effective-configuration

Print the current configuration as YAML representation on the console.

jqassistant:effective-rules

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

jqassistant:available-rules

List all available rules.

jqassistant:report

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

6. Configuration

The behavior of jQAssistant accepts a wide range of configuration options, e.g.

  • passing properties to scanner or report plugins

  • rules to be executed during analysis including required rule parameters

  • define thresholds for warnings and failures during analysis

  • location of the database to use, e.g. directory of the embedded Neo4j instance or URL of a remote Neo4j instance

The configuration options can be passed in different ways:

  • YAML files (recommended)

  • system properties or environment variables

  • command line options for the Command Line Interface

  • configuration options in the Maven build descriptors (pom.xml)

6.1. YAML files

jQAssistant automatically loads YAML files from the following locations of the user home and the working directory:

  • .jqassistant.yml or .jqassistant.yaml

  • .yml or .yaml files located in the directory or sub-directories of .jqassistant/

Note
Configuration files in the user home directory have a lower priority than those in the working directory.
Tip
The locations can be overridden by command line parameters of the Command Line Utility or the Maven plugin.

The following options are supported (including default values):

jqassistant:
  # Controls whether the execution of jQAssistant shall be skipped
  #
  # -Djqassistant.skip: true|false
  skip: false

  # The list of jQAssistant plugins to load and activate.
  #
  # Each plugin is identified using its Maven coordinates:
  #
  # -Djqassistant.plugins[0].group-id
  # -Djqassistant.plugins[0].artifact-id
  # -Djqassistant.plugins[0].version
  # -Djqassistant.plugins[0].classifier (optional)
  # -Djqassistant.plugins[0].type (optional)
  # -Djqassistant.plugins[0].exclusions[0].group-id (optional)
  # -Djqassistant.plugins[0].exclusions[0].artifact-id (optional)
  plugins:
    - group-id:
      artifact-id:
      version:
      classifier:
      type:
      exclusions:
        - group-id:
          artifact-id:


  # The store configuration
  store:

    # URI of the database to connect to. Supported URI schemes are 'file' for embedded databases and 'bolt' for connecting to a running Neo4j instance (3.x+), e.g.
    #
    # -Djqassistant.store.uri
    uri: file://target/jqassistant/store

    # Settings for the embedded Neo4j store
    embedded:

      # Enable the HTTP and BOLT connector for the embedded store
      #
      # -Djqassistant.store.embedded.connector-enabled: true|false
      connector-enabled: false

      # The listen address for the HTTP and BOLT connectors
      #
      # -Djqassistant.store.embedded.listen-address
      listen-address: localhost

      # The BOLT connector port
      #
      # -Djqassistant.store.embedded.bolt-port
      bolt-port: 7687

      # The HTTP connector port
      #
      # -Djqassistant.store.embedded.http-port
      http-port: 7474

      # The directory from which Neo4j shall load plugins (e.g. APOC)
      #
      # -Djqassistant.store.embedded.neo4j-plugin-directory
      neo4j-plugin-directory:

      # The list of Neo4j plugins to load and activate.
      # It uses the "neo4j-plugin-directory" (see above) if provided, otherwise a temporary directory is created.
      neo4j-plugins:
        # Each plugin is identified using its Maven coordinates:
        #
        # -Djqassistant.store.embedded.neo4j-plugins[0].group-id
        # -Djqassistant.store.embedded.neo4j-plugins[0].artifact-id
        # -Djqassistant.store.embedded.neo4j-plugins[0].version
        # -Djqassistant.store.embedded.neo4j-plugins[0].classifier (optional)
        # -Djqassistant.store.embedded.neo4j-plugins[0].type (optional)
        # -Djqassistant.store.embedded.neo4j-plugins[0].exclusions[0].group-id (optional)
        # -Djqassistant.store.embedded.neo4j-plugins[0].exclusions[0].artifact-id (optional)
        - group-id:
          artifact-id:
          version:
          classifier:
          type:
          exclusions:
            - group-id:
              artifact-id:


    # Settings for connecting to a remote Neo4j store
    remote:

      # The user name for authentication.
      #
      # -Djqassistant.store.username
      username:

      # The password for authentication.
      #
      # -Djqassistant.store.password
      password:

      # Activate encryption level for 'bolt' connections.
      #
      # -Djqassistant.store.encryption: true|false
      encryption: true

      #The trust strategy for 'bolt' connections
      #
      # -Djqassistant.store.trust-strategy: trustAllCertificates|trustCustomCaSignedCertificates|trustSystemCaSignedCertificates
      trust-strategy: trustAllCertificates

      # The file containing the custom CA certificate for trust strategy.
      #
      # -Djqassistant.store.trust-certificate
      trust-certificate:

      # Additional properties to be passed to the remote store as key-value pairs.
      #
      # -Djqassistant.store.properties
      properties:


  # The Scanner configuration
  scan:

    # Indicates whether to initially reset the store (i.e. clear all nodes and relationships) before scanning.
    #
    # -Djqassistant.scan.reset: true|false
    reset: true

    # Specifies if a scan shall be continued if an error is encountered.
    #
    # -Djqassistant.scan.continue-on-error: true|false
    continue-on-error: false

    # The items to include for scanning.
    include:

      # A list of files to include.
      #
      #jqassistant.scan.include.files[0]
      files:
      # - src/folder

      # A list of URLs to include.
      #
      #jqassistant.scan.include.urls[0]
      urls:
      # - maven:repository::https://nexus/repository

    # The properties to configure scanner plugins as key-value pairs. The supported properties are plugin specific.
    #
    # -Djqassistant.scan.properties
    properties:
      # plugin.property.key: value


  # The analyze configuration
  analyze:

    # The rule configuration
    rule:

      # The name of the directory containing project rules.
      #
      # -Djqassistant.analyze.rule.directory
      directory: jqassistant/

      # The default severity of concepts without an explicit severity.
      #
      # -Djqassistant.analyze.rule.default-concept-severity: INFO|MINOR|MAJOR|CRITICAL|BLOCKER
      default-concept-severity: MINOR

      # The default severity of constraint without an explicit severity.
      #
      # -Djqassistant.analyze.rule.default-constraint-severity: INFO|MINOR|MAJOR|CRITICAL|BLOCKER
      default-constraint-severity: MAJOR

      # The default severity of groups without an explicit severity.
      #
      # -Djqassistant.analyze.rule.default-group-severity: INFO|MINOR|MAJOR|CRITICAL|BLOCKER
      default-group-severity:

    # The report configuration
    report:

      # The properties to configure report plugins. The supported properties are plugin specific.
      #
      # -Djqassistant.analyze.report.properties
      properties:
        # plugin.property.key: value

      # Determines the severity level for reporting a warning.
      #
      # -Djqassistant.analyze.report.warn-on-severity: INFO|MINOR|MAJOR|CRITICAL|BLOCKER|NEVER
      warn-on-severity: MINOR

      # Determines the severity level for reporting a failure.
      #
      # -Djqassistant.analyze.report.fail-on-severity: INFO|MINOR|MAJOR|CRITICAL|BLOCKER|NEVER
      fail-on-severity: MAJOR

      # Determines if jQAssistant shall continue the build if failures have been detected.
      #
      # -Djqassistant.analyze.report.continue-on-failure: true|false
      continue-on-failure: false

      # Create an archive containing all generated reports.
      #
      # -Djqassistant.analyze.report.create-archive: true|false
      create-archive: false

    # The concepts to be applied.
    #
    # -Djqassistant.analyze.concepts[0]
    concepts:
    # - my-concept

    # The constraints to be validated.
    #
    # -Djqassistant.analyze.constraints[0]
    constraints:
    # - my-constraint

    # The groups to be executed.
    #
    # -Djqassistant.analyze.groups[0]
    groups:
    # - spring-boot:Default

    # The parameters to be passed to the executed rules.
    #
    # -Djqassistant.analyze.rule-parameters."parameterName"
    rule-parameters:
    # parameterName: value

    # Execute concepts even if they have already been applied before
    #
    # -Djqassistant.analyze.execute-applied-concepts: true|false
    execute-applied-concepts: false

    # The execution time [seconds] for rules (concepts/constraints) to show a warning. Can be used as a hint for optimization.
    #
    # -Djqassistant.analyze.warn-on-rule-execution-time-seconds
    warn-on-rule-execution-time-seconds: 5

6.2. Environment Variables

The names of system properties may be used for environment variables. Depending on execution environment there may be restrictions on the naming, e.g. not allowing characters like .. Therefore, the following mappings are supported (see Eclipse Microprofile Config):

  • Exact match (e.g. jqassistant.scan.continue-on-error)

  • Replace each character that is neither alphanumeric nor _ with _ (e.g. jqassistant_scan_continue_on_error)

  • Replace each character that is neither alphanumeric nor _ with _; then convert the name to upper case (JQASSISTANT_SCAN_CONTINUE_ON_ERROR)

6.3. System Properties

All configuration options can be provided as system properties. The according names are documented in the YAML example above.

Note
Configuration options defined in a YAML file can be overridden by environment variables of system properties. The priorities are as following: System Property -→ Environment Variable -→ YAML file.

6.4. Property placeholders

Values may contain placeholders referering to other properties:

src-dir: ./src

jqassistant:
  scan:
    include:
      files:
        - ${src-dir}/folder1
        - ${src-dir}/folder2

The properties in placeholders can be defined in different sources:

  • within the same or other configuration files

  • system properties

  • environment variables

  • Maven or user properties specified in the files pom.xml or settings.xml (for the jQAssistant Maven plugin)

7. Plugins

This section provides detailed descriptions of all distributed plugins.

7.1. jQAssistant 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.

The Java plugin provides the following scanners:

Artifact Scanner

Nodes labeled with `:Java:Artifact

A directory or archive containing packages, classes and resources.

Table 1. Properties of :Java:Artifact
Name Description

fqn

Fully qualified name, e.g. java.lang

fileName

The file name of the artifact. `

Table 2. 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

Nodes labeled with :Java:Artifact:Directory

A directory representing a Java artifact.

Nodes labeled with :Java:Artifact:Jar:Archive

A JAR file representing a Java artifact.

Package Scanner

Imports Java packages.

Nodes labeled with :Java:Package

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

Table 3. Properties of :Java:Package
Name Description

fqn

Fully qualified name, e.g. java.lang

name

The local name, e.g. lang

Table 4. 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

Class File 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.

Nodes labeled with :Java:Type

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

Table 5. 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"

valid

true if the class file could be scanned successfully.

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

DECLARES_TYPE_PARAMETER

Nodes labeled with :Java:Bound:TypeVariable

0..n

Declares a type variable

REQUIRES_TYPE_PARAMETER

Nodes labeled with :Java:Bound:TypeVariable

0..n

References a required type variable (in case of an inner class referencin a type parameter declared by an outer class)

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

EXTENDS_GENERIC

Nodes labeled with :Java:Bound

0..1

References a generic type this type extends from

IMPLEMENTS

Nodes labeled with :Java:Type

0..1

References an interface type this type implements

IMPLEMENTS_GENERIC

Nodes labeled with :Java:Bound

0..1

References a generic 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 7. Properties of :DECLARES_TYPE_PARAMETER
Name Description

index

The index of the declared type parameter, starting with 0

Table 8. Properties of :DEPENDS_ON
Name Description

weight

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

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

lineNumber

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

Nodes labeled with :Java:Type:Class

Qualifies a Java type as class.

Nodes labeled with :Java:Type:Interface

Qualifies a Java type node as interface.

Nodes labeled with :Java:Type:Enum

Qualifies a Java type as enumeration.

Nodes labeled with :Java:Type:Record

Qualifies a Java type as record.

Nodes labeled with :Java:Type:Annotation

Qualifies a Java type as annotation.

Nodes labeled with :Java:Field

A field declared in a Java type.

Table 10. 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 11. Relations of :Java:Field
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

References the type of the field

OF_GENERIC_TYPE

Nodes labeled with :Java:Bound

0..1

References the generic 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 initializing the field

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

:Java:Method

A method declared in a Java type.

Table 12. 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 13. Relations of :Java:Method
Name Target label(s) Cardinality Description

DECLARES_TYPE_PARAMETER

Nodes labeled with :Java:Bound:TypeVariable

0..n

Declares a type variable

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 types thrown by the method

THROWS_GENERIC

Nodes labeled with :Java:Bound

0..n

References the generic exception types thrown by the method

RETURNS

Nodes labeled with :Java:Type

0..n

References the return type of the method

RETURNS_GENERIC

Nodes labeled with :Java:Bound

0..n

References the generic 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

Table 14. Properties of :DECLARES_TYPE_PARAMETER
Name Description

index

The index of the declared type parameter, starting with 0

Nodes labeled with :Java:Method:Constructor

Qualifies a method as constructor.

Nodes labeled with :Java:Parameter

A method parameter.

Table 15. Properties of :Java:Parameter
Name Description

index

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

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

OF_TYPE

Nodes labeled with :Java:Type

1

References the type of the parameter

OF_GENERIC_TYPE

Nodes labeled with :Java:Bound

0..1

References the generic type of the parameter

ANNOTATED_BY

Nodes labeled with :Java:Value:Annotation

0..n

References an annotation which is present on the parameter

Nodes labeled with :Java:Variable

A variable declared in a method.

Table 17. 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

Table 18. Relations of :Java:Variable
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

References the type of the variable

OF_GENERIC_TYPE

Nodes labeled with :Java:Bound

0..1

References the generic type of the variable

Nodes labeled with :Java:Value

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

Table 19. Properties of :Java:Value
Name Description

name

The method name, e.g. value

Nodes labeled with :Value:Primitive

A primitive value.

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

value

The value

Nodes labeled with :Java:Value:Annotation

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

Table 21. 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")

Nodes labeled with :Java:Value:Class

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

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

IS

Nodes labeled with :Java:Type

1

References the type

Nodes labeled with :Java:Value:Enum

Represents an enum value.

Table 23. 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

Nodes labeled with :Java:Value:Array

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

Table 24. 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

Nodes labeled with :Java:Bound

Represent a bound of a generic type.

A bound can be further classified by the following labels:

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

OF_RAW_TYPE

Nodes labeled with :Java:Type

0..1

References the raw type, e.g. java.util.List for a parameterized type java.util.List<String>.

Nodes labeled with :Java:Bound:TypeVariable

Represents a type variable, e.g.

  • X in public class<X> {}

  • X in java.util.List<X>

Table 26. Relations of :Java:Bound:TypeVariable
Name Target label(s) Cardinality Description

HAS_UPPER_BOUND

:Java:Bound

0..1

References the upper bounds of the type variable.

Note
TypeVariable nodes are declared by :Java:Type or :Java:Method nodes using :DECLARES_TYPE_PARAMETER relations. In this case the declaring nodes have an additional label :GenericDeclaration.
Nodes labeled with :Java:Bound:ParameterizedType

Represents a parameterized type, e.g.

  • java.util.List<X>

  • java.util.List<?>

  • java.util.List<String>

Table 27. Relations of :Java:Bound:ParameterizedType
Name Target label(s) Cardinality Description

HAS_ACTUAL_TYPE_ARGUMENT

:Java:Bound

1..*

References the type arguments, e.g. X (:TypeVariable), ? (:WildcardType) or String (:Bound)

Table 28. Properties of :HAS_ACTUAL_TYPE_ARGUMENT
Name Description

index

The index of the type argument, starting with 0

Nodes labeled with :Java:Bound:WildcardType

Represents a wildcard type, e.g. ? in

  • java.util.List<?> for an unbound wildcard

  • java.util.List<? extends X> for a wildcard with an upper bound X

  • java.util.List<? super X> for a wildcard with a lower bound X

Table 29. Relations of :Java:Bound:WildcardType
Name Target label(s) Cardinality Description

HAS_UPPER_BOUND

:Java:Bound

0..*

References the upper bounds of this wildcard type (e.g. ? extends X)

HAS_LOWER_BOUND

:Java:Bound

0..*

References the lower bounds of this wildcard type (e.g. ? extends X)

Note
There can be either upper or lower bounds. An unbound wildcard has neither upper nor lower bounds.
Nodes labeled with :Java:Bound:GenericArrayType

Represents a generic array type, i.e.

  • [] in java.util.List<java.util.List[]>

Table 30. Relations of :Java:Bound:GenericArrayType
Name Target label(s) Cardinality Description

HAS_COMPONENT_TYPE

:Java:Bound

1

References the bound of the component type.

Nodes labeled with :Java:Module

Represents a module declaration according the Java Platform Module Specification (JPMS)

Table 31. Properties of :Java:Module
Name Description

fqn

The fully qualified name of the module

version

The version of the module

open

true indicates that the module is open for access by reflection

Table 32. Relations of :Java:Module
Name Target label(s) Cardinality Description

DECLARES_MAIN_CLASS

Nodes labeled with :Java:Type

1

References the declared main class of the module

REQUIRES

Nodes labeled with :Java:Module

0..n

References the required modules

EXPORTS

Nodes labeled with :Java:ExportedPackage

0..n

References the exported package declarations

USES

Nodes labeled with :Java:Type

0..n

References used services

PROVIDES

Nodes labeled with :Java:ProvidedService

0..n

References the provided service declarations

OPENS

Nodes labeled with :Java:OpenPackage

0..n

References the open package declarations

Table 33. Properties of :REQUIRES
Name Description

static

true indicates a static reference, i.e. only at compile time

transitive

true indicates that the module is required including its transitive module dependencies

Nodes labeled with :Java:ExportedPackage

Represents an exported package declaration of a Java module.

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

OF_PACKAGE

Nodes labeled with :Java:Package

1

References the exported Java package

TO_MODULE

Nodes labeled with :Java:Module

0..n

References the modules to which the Java package is exported

Nodes labeled with :Java:ProvidedService

Represents a provided service declaration of a Java module.

Table 35. Relations of :Java:ProvidedService
Name Target label(s) Cardinality Description

OF_TYPE

Nodes labeled with :Java:Type

1

References the provided service interface

WITH_PROVIDER

Nodes labeled with :Java:Type

1..n

References the service providers implementing the service interface

Nodes labeled with :Java:OpenPackage

Represents an open package declaration of a Java module.

Table 36. Relations of :Java:OpenPackage
Name Target label(s) Cardinality Description

OF_PACKAGE

Nodes labeled with :Java:Package

1

References the open Java package (i.e. to allow access via reflection)

TO_MODULE

Nodes labeled with :Java:Module

0..n

References the modules to which the Java packages are open

Manifest File Scanner

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

Nodes labeled with :File:Java:Manifest

A MANIFEST.MF file containing sections.

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

fileName

The file name

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

DECLARES

Nodes labeled with :Java:ManifestSection

0..n

References a manifest section

Nodes labeled with :Java:ManifestSection

A manifest section.

Table 39. 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

Nodes labeled with :Java:Value:ManifestEntry

A manifest entry.

Table 40. 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.commandline.Main

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">.

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 41. Properties of :File:Java:Properties and :File:Java:Properties:Xml
Name Description

fileName

The file name

Table 42. 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

Nodes labeled with :Java:Value:Property

A key value/pair.

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

name

The name of the property

value

The value of the property

Service Loader File Scanner

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

Nodes labeled with :File:Java:ServiceLoader

A file containing the implementation class names for a service interface

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

fileName

The file name

Table 45. 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

@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>com.buschmais.jqassistant</groupId>
  <artifactId>manual</artifactId>
  <version>2.1.0</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:

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

Suppression by default 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.

If needed a custom column can be specified as well:

@jQASuppress(value = "my-rules:MyConstraint", column="method")
public class ClassViolatingMyConstraint {
}

Rules provided by the jQAssistant Java Plugin

Concept java:InnerType

Sets a label "Inner" on inner types.

MATCH
  (:Java:Type)-[:DECLARES]->(innerType:Java:Type)
CALL {
  WITH
    innerType
  SET
    innerType:Inner
} IN TRANSACTIONS
RETURN
  count(innerType) AS InnerTypes
Concept java:AnonymousInnerType

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

MATCH
  (anonymousInnerTypes:Inner:Java:Type)
WHERE
  anonymousInnerTypes.name =~ ".*\\$[0-9]*"
CALL {
  WITH
    anonymousInnerTypes
  SET
    anonymousInnerTypes:Anonymous
} IN TRANSACTIONS
RETURN
  count(anonymousInnerTypes) AS AnonymousInnerTypes

Required concepts:

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:Java:Type)-[:IMPLEMENTS|EXTENDS*0..]->(superType:Java:Type)
CALL {
    WITH
      type, superType
    MERGE
      (superType)-[:ASSIGNABLE_FROM]->(type)
} IN TRANSACTIONS
RETURN
  count(*) AS AssignableTypes
Concept java:MemberInheritedFrom

Creates a relationship INHERITS between two "Member" labeled nodes if a member is inherited from a super type.

MATCH
  (type:Java:Type)-[:DECLARES]->(member:Member),
  (superType:Java:Type)-[:DECLARES]->(superMember:Member),
  path=shortestPath((type)-[:EXTENDS|IMPLEMENTS*]->(superType))
WHERE
  type <> superType
  and member.name is null
  and superMember.name is not null
  and member.signature = superMember.signature
  and superMember.visibility <> "private"
WITH
  type, member, superType, superMember, length(path) as depth
ORDER BY
  depth asc
WITH
  member, head(collect(superMember)) as inheritedMember
CALL {
  WITH
    member, inheritedMember
  MERGE
    (member)-[:INHERITED_FROM]->(inheritedMember)
} IN TRANSACTIONS
RETURN
  count(*) as InheritedMembers
Concept java:MethodOverrides

Creates a relationship OVERRIDES between two "Method" labeled nodes if a method overrides another one from a super type.

MATCH
  (type:Java:Type)-[:DECLARES]->(method:Method),
  (superType:Java:Type)-[:DECLARES]->(superMethod:Method),
  path=(type)-[:EXTENDS|IMPLEMENTS*]->(superType)
WHERE
  method.signature = superMethod.signature
  and superMethod.visibility <> "private"
  and not (
    (method)-[:INHERITED_FROM]->(:Method)
    or (superMethod)-[:INHERITED_FROM]->(:Method)
  )
WITH
  type, method, superType, superMethod, length(path) as depth
ORDER BY
  depth asc
WITH
  method, head(collect(superMethod)) as overriddenMethod
CALL {
  WITH
    method, overriddenMethod
  MERGE
    (method)-[:OVERRIDES]->(overriddenMethod)
} IN TRANSACTIONS
RETURN
  count(*) as OverriddenMethods

Required concepts:

Concept java:VirtualInvokes

Propagates INVOKES relationships as VIRTUAL_INVOKES to non-abstract methods within the inheritance hierarchy, i.e. identifying potential methods that could be invoked.

MATCH
  (method:Method)-[invokes:INVOKES]->(:Method)-[:INHERITED_FROM*0..1]->(invokedMethod:Method),
  (invokedMethod)<-[:OVERRIDES*0..]-(overridingMethod:Method)
WHERE NOT (                                     // exclude...
  overridingMethod.abstract is not null         // ...abstract methods
  or (overridingMethod)-[:INHERITED_FROM]->()   // ...inherited methods
)
WITH
  method, overridingMethod, coalesce(invokes.lineNumber, -1) as lineNumber
CALL {
  WITH
    method, overridingMethod, lineNumber
  MERGE
    (method)-[virtualInvokes:VIRTUAL_INVOKES{lineNumber:lineNumber}]->(overridingMethod)
} IN TRANSACTIONS
RETURN
  count(*) as VirtualInvokes

Required concepts:

Concept java:VirtualDependsOn

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

MATCH
  (type:Java:Type)-[:EXTENDS|IMPLEMENTS*]->(superType:Java:Type),
  (dependent:Java:Type)-[:DEPENDS_ON]->(superType)
WHERE NOT (
  superType.fqn = "java.lang.Object"
  or (dependent)-[:EXTENDS|IMPLEMENTS*]->(superType) // exclude types sharing the same super classes/interfaces
)
WITH
  dependent, collect(distinct type) as types
UNWIND
  types as type
CALL {
  WITH
    dependent, type
  MERGE
    (dependent)-[virtualDependsOn:VIRTUAL_DEPENDS_ON]->(type)
} IN TRANSACTIONS
RETURN
  count(*) AS VirtualDependsOn
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:Java:Type)-[:DECLARES]->(method:Method),
  (type)-[:DECLARES]->(otherMethod:Method)
WHERE
  method <> otherMethod
  AND method.name = otherMethod.name
  AND method.signature <> otherMethod.signature
CALL {
  WITH method, otherMethod
  MERGE
    (method)-[:OVERLOADS]->(otherMethod)
} IN TRANSACTIONS
RETURN
  count(method) AS OverloadedMethods
Concept java:Deprecated

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

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

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

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

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

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

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

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

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

MATCH
  (throwable)-[:EXTENDS*]->(t:Java:Type)
WHERE
  t.fqn = 'java.lang.Throwable'
SET
  throwable:Throwable
RETURN
  throwable AS Throwable
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 65 THEN "Java 21"
    WHEN 64 THEN "Java 20"
    WHEN 63 THEN "Java 19"
    WHEN 62 THEN "Java 18"
    WHEN 61 THEN "Java 17"
    WHEN 60 THEN "Java 16"
    WHEN 59 THEN "Java 15"
    WHEN 58 THEN "Java 14"
    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
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
CALL {
  WITH
    i
  SET
    i:FunctionalInterface
} IN TRANSACTIONS
RETURN
  count(i) AS FunctionInterfaces
Concept java:DefaultMethod

Labels default methods of interfaces with Default.

MATCH
  (type:Type:Java:Interface)-[:DECLARES]->(defaultMethod:Java:Method)
WHERE NOT
  defaultMethod.abstract is not null
SET
  defaultMethod:Default
RETURN
  defaultMethod AS DefaultMethod, type AS Interface
Concept java:PostConstruct

Labels methods annotated @javax.annotation.PostConstruct with 'PostConstruct'.

MATCH
  (postConstruct:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(:Java:Type{fqn:"javax.annotation.PostConstruct"})
SET
  postConstruct:PostConstruct
RETURN
  postConstruct as PostConstruct
Concept java:PreDestroy

Labels methods annotated @javax.annotation.PreDestroy with 'PreDestroy'.

MATCH
  (preDestroy:Method)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(:Java:Type{fqn:"javax.annotation.PreDestroy"})
SET
  preDestroy:PreDestroy
RETURN
  preDestroy as PreDestroy
Concept java:PackageAnnotatedBy

Propagates the annotations from the package-info.java to the package node.

MATCH
  (p:Package)-[:CONTAINS]->(t:Java:Type{sourceFileName: "package-info.java"}),
  (t)-[:ANNOTATED_BY]->(a:Annotation)
MERGE
  (p)-[:ANNOTATED_BY]->(a)
RETURN p
Concept java:GeneratedType

Reports the count of types labeled with Generated, grouped by containing artifact.

MATCH
  (artifact:Artifact)-[:CONTAINS]->(generatedType:Java:Type:Generated)
RETURN
  artifact as Artifact, count(generatedType) as GeneratedTypes
ORDER BY
  GeneratedTypes desc
Concept java:InnerTypeParameterDeclaredByOuterType

Creates a DECLARED_BY relation of a type parameter required by an inner to type to its declaration by an outer type.

MATCH
  (inner:Java:Type)-[requires:REQUIRES_TYPE_PARAMETER]->(requiredTypeParameter:TypeVariable),
  (outer:Java:Type)-[declares:DECLARES_TYPE_PARAMETER]->(declaredTypeParameter:TypeVariable),
  shortestPath((outer)-[:DECLARES*]->(inner))
WHERE
  outer <> inner
  and declaredTypeParameter.name = requiredTypeParameter.name
CALL {
  WITH
    requiredTypeParameter, declaredTypeParameter
  MERGE
    (requiredTypeParameter)-[:DECLARED_BY]->(declaredTypeParameter)
} IN TRANSACTIONS
RETURN
  count(*) as OuterTypeDeclarations
Concept java:TypeArgumentDeclaredByTypeParameter

Creates a DECLARED_BY relation between a type argument of a parameterized type to the according type parameter of the declaring type.

MATCH
  (parameterizedType:ParameterizedType)-[:OF_RAW_TYPE]->(rawType:Java:Type),
  (parameterizedType)-[hasActualTypeArgument:HAS_ACTUAL_TYPE_ARGUMENT]->(typeArgument),
  (rawType)-[declaresTypeParameter:DECLARES_TYPE_PARAMETER]->(typeParameter)
WHERE
  hasActualTypeArgument.index = declaresTypeParameter.index
CALL {
  WITH
    typeArgument, typeParameter
  MERGE
    (typeArgument)-[:DECLARED_BY]->(typeParameter)
} IN TRANSACTIONS
RETURN
  count(*) as TypeParameterDeclarations
Concept java:PackageDependency
Creates a DEPENDS_ON relationship between a packages if there are type dependencies between them.
MATCH
    (p1:Package)-[:CONTAINS]->(t1:Java:Type)-[dependsOn:DEPENDS_ON]->(t2:Java:Type)<-[:CONTAINS]-(p2:Package)
WHERE
    p1 <> p2
WITH
  p1, count(dependsOn) as weight, p2
CALL {
  WITH
    p1, weight, p2
  MERGE
    (p1)-[d:DEPENDS_ON]->(p2)
  SET
    d.weight = weight
} IN TRANSACTIONS
RETURN
  p1 AS package, COUNT(p2) AS PackageDependencies
Concept java:ArtifactDependency
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]->(:Java:Type)-[dependsOn:DEPENDS_ON]->(t1:Java:Type),
  (a2:Artifact)-[:CONTAINS]->(t2:Java:Type)
WHERE
  a1 <> a2
  and t1.fqn = t2.fqn
WITH
  a1, count(dependsOn) as weight, a2
CALL {
  WITH
    a1, weight, a2
  MERGE
    (a1)-[d:DEPENDS_ON]->(a2)
  SET
    d.weight = weight
} IN TRANSACTIONS
RETURN
  a1 AS Artifact, COLLECT(DISTINCT a2.fqn) AS Dependencies
Constraint java:AvoidCyclicPackageDependencies

Cyclic package dependencies must be avoided.

MATCH
    (p1:Package)-[:DEPENDS_ON]->(p2:Package),
    path=shortestPath((p2)-[:DEPENDS_ON*]->(p1))
WHERE
    p1<>p2
RETURN
    p1 as Package, nodes(path) as Cycle
ORDER BY
    Package.fqn

Required concepts:

Constraint java:AvoidCyclicArtifactDependencies

Cyclic artifact dependencies must be avoided.

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

Required concepts:

Concept java-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:Java:Type)
WITH
  a1, t1, t1.fqn AS fqn
MATCH
  (a2:Artifact)-[:CONTAINS]->(t2:Java:Type)
WHERE
  t2.fqn = t1.fqn
CALL {
  WITH
    t1, t2
  MERGE
    (t1)-[:RESOLVES_TO]->(t2)
} IN TRANSACTIONS
RETURN
  count(*) AS ResolvedTypes
Concept java-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:Java:Type)-[:RESOLVES_TO]->(t2:Java:Type),
  (t1)-[:DECLARES]->(m1),
  (t2)-[:DECLARES]->(m2)
WHERE
  (m1:Field or m1:Method)
  and m1.signature = m2.signature
CALL {
  WITH
    m1, m2
  MERGE
  (m1)-[:RESOLVES_TO]->(m2)
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedMembers

Required concepts:

Concept java-classpath:ResolveDependsOn

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

MATCH
  (t:Java:Type)-[dependsOn:DEPENDS_ON]->(t1:Java:Type)-[:RESOLVES_TO]->(t2:Java:Type)
CALL {
  WITH
    t, dependsOn, t2
  MERGE
    (t)-[dependsOn1:DEPENDS_ON]->(t2)
  SET
    dependsOn1=dependsOn,
    dependsOn1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedDependencies

Required concepts:

Concept java-classpath:ResolveExtends

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

MATCH
  (t:Java:Type)-[extends:EXTENDS]->(t1:Java:Type)-[:RESOLVES_TO]->(t2:Java:Type)
CALL {
  WITH
    t, extends, t2
  MERGE
    (t)-[extends1:EXTENDS]->(t2)
  SET
    extends1=extends,
    extends1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedSuperClass

Required concepts:

Concept java-classpath:ResolveImplements

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

MATCH
  (t:Java:Type)-[implements:IMPLEMENTS]->(t1:Java:Type)-[:RESOLVES_TO]->(t2:Java:Type)
CALL {
  WITH
    t, implements, t2
  MERGE
    (t)-[implements1:IMPLEMENTS]->(t2)
  SET
    implements1=implements,
    implements1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedInterfaces

Required concepts:

Concept java-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]->(:Java:Type)-[:RESOLVES_TO]->(t:Java:Type)
CALL {
  WITH
    f, ofType, t
  MERGE
    (f)-[ofType1:OF_TYPE]->(t)
  SET
    ofType1=ofType,
    ofType1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedFieldTypes

Required concepts:

Concept java-classpath:ResolveThrows

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

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

Required concepts:

Concept java-classpath:ResolveReturns

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

MATCH
  (m:Method)-[returns:RETURNS]->(:Java:Type)-[:RESOLVES_TO]->(t:Java:Type)
CALL {
  WITH
    m, returns, t
  MERGE
    (m)-[returns1:RETURNS]->(t)
  SET
    returns1=returns,
    returns1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedReturnTypes

Required concepts:

Concept java-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]->(:Java:Type)-[:RESOLVES_TO]->(t:Java:Type)
CALL {
  WITH
    m, ofType, t
  MERGE
    (m)-[ofType1:OF_TYPE]->(t)
  SET
    ofType1=ofType,
    ofType1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedParameterTypes

Required concepts:

Concept java-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]->(:Java:Type)-[:RESOLVES_TO]->(t:Java:Type)
CALL {
  WITH
    a, ofType, t
  MERGE
    (a)-[ofType1:OF_TYPE]->(t)
  SET
    ofType1=ofType,
    ofType1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedAnnotationTypes

Required concepts:

Concept java-classpath:ResolveOfRawType

Propagates "OF_RAW_TYPE" relations between generic bounds and types to their resolved types with a property "resolved:true".

MATCH
  (b:Bound)-[ofRawType:OF_RAW_TYPE]->(:Java:Type)-[:RESOLVES_TO]->(t:Java:Type)
CALL {
  WITH
    b, ofRawType, t
  MERGE
    (b)-[ofRawType1:OF_RAW_TYPE]->(t)
  SET
    ofRawType1=ofRawType,
    ofRawType1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedRawTypes

Required concepts:

Concept java-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)
CALL {
  WITH
    v, is, e2
  MERGE
    (v)-[is1:IS]->(e2)
  SET
    is1=is,
    is1.resolved=true
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedValueTypes

Required concepts:

Concept java-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)
CALL {
  WITH
    m, reads, f2
  MERGE
    (m)-[reads1:READS {relationId: id(reads)}]->(f2)
  SET
    reads1=reads,
    reads1.resolved=true
  REMOVE
    reads1.relationId
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedReads

Required concepts:

Concept java-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)
CALL {
  WITH
    m, writes, f2
  MERGE
    (m)-[writes1:WRITES {relationId: id(writes)}]->(f2)
  SET
    writes1=writes,
    writes1.resolved=true
  REMOVE
    writes1.relationId
} IN TRANSACTIONS
RETURN
  count(*) as ResolvedWrites

Required concepts:

Concept java-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)
CALL {
  WITH
    m, invokes, m2
  MERGE
    (m)-[invokes1:INVOKES {relationId : id(invokes)}]->(m2)
  SET
    invokes1=invokes,
    invokes1.resolved=true
  REMOVE
    invokes1.relationId
  }
RETURN
  count(*) as ResolvedInvocations

Required concepts:

7.2. jQAssistant JSON Plugin

Provides a scanner for JSON files

7.2.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.2.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.2.1.2. Configuration
Table 46. 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.2.1.3. Nodes labeled with :Json:File
Table 47. 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 48. 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.2.1.4. Nodes labeled with :Json:Array
Table 49. Properties of :Json:Array
Name Description

None

Table 50. 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.2.1.5. Nodes labeled with :Json:Key
Table 51. Properties of :Json:Key
Name Description

name

The literal name of the key.

Table 52. 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.2.1.6. Nodes labeled with :Json:Object
Table 53. Properties of :Json:Object
Name Description

None

Table 54. 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.2.1.7. Nodes labeled with :Json:Scalar
Table 55. 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 56. Relations of :Json:Scalar
Name Target label(s) Cardinality Description

None

7.2.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 57. Properties of :Json:Value
Name Description

None

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

None

7.2.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.2.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.2.1.9.2. Empty JSON Array
An empty JSON array
[
]
example 02
Figure 2. Graph struture created out of the source document
7.2.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.2.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.3. jQAssistant JUnit Plugin

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

7.3.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.3.1.1. Nodes labeled with :File:Junit:TestSuite

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

Table 59. 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 60. Relations of :File:JUnit:TestSuite
Name Target label(s) Cardinality Description

CONTAINS

[:JUnit::TestCase]

0..n

References test cases

7.3.1.2. :JUnit:TestCase

A test case.

Table 61. 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 62. 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.3.1.3. :JUnit:Failure

Provides detail information about a test case with result FAILURE.

Table 63. Properties of :JUnit:Failure
Name Description

type

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

details

Detail information, e.g. the stack trace.

7.3.1.4. :JUnit:Error

Provides detail information about a test case with result ERROR.

Table 64. Properties of :JUnit:Error
Name Description

type

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

details

Detail information, e.g. the stack trace.

7.3.2. Rules provided by the jQAssistant JUnit Plugin

7.3.2.1. 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.3.2.2. 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.3.2.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.3.2.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.3.2.5. Group junit4:Default

Includes constraints:

7.3.2.6. 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.3.2.7. 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.3.2.8. 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.3.2.9. 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.3.2.10. 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.3.2.11. 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.3.2.12. 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.3.2.13. 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.3.2.14. 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.3.2.15. 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)
MERGE
  (suite)-[c:CONTAINS_TESTCLASS]->(testClass)
RETURN
  suite, collect(testClass)
7.3.2.16. Concept junit4:InnerTestClass

Labels inner types of types labeled with "Test" with "Test" and "Inner".

MATCH
    (source:Type:Junit4:Test)-[:DECLARES]->(target:Type)
SET
    target:Junit4:Test:Inner
RETURN
    target

Required concepts:

7.3.2.17. Constraint junit4:AssertionMustProvideMessage

All assertions must provide a message.

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

Required concepts:

7.3.2.18. Constraint junit4:NonJUnit4TestMethod

Only the jUnit 4-test annotation must be used to identify test methods in a jUnit 4-based project.

MATCH
  (:Artifact)-[:CONTAINS]->(t:Type)-[:DECLARES]->(m:Test:Method)
WHERE
  m:Junit3 OR m:Junit5
RETURN
  t AS TestClass,
  m AS TestMethod

Required concepts:

7.3.2.19. Constraint junit4:UsageOfJUnit5TestApi

Only the jUnit 4-test api must be used in a jUnit 4-based project.

MATCH
  (:Artifact)-[:CONTAINS]->(t:Type)-[:DECLARES]->(m:Test:Method),
  (m)-[:INVOKES*..3]->(:Junit5:Assert:Method)
RETURN DISTINCT
  t AS TestClass,
  m AS TestMethod

Required concepts:

7.3.2.20. Group junit5:Default

Includes constraints:

7.3.2.21. 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.3.2.22. 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.3.2.23. 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.3.2.24. 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.3.2.25. 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.3.2.26. 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.3.2.27. 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.3.2.28. 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.3.2.29. 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.3.2.30. 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.3.2.31. 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.3.2.32. 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.3.2.33. 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.3.2.34. 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.3.2.35. 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.3.2.36. 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.3.2.37. 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.3.2.38. 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 CONTAINS ' assert'
SET
  assertMethod:Junit5:Assert
RETURN
  assertMethod
7.3.2.39. Constraint junit5:AssertionMustProvideMessage

All assertions must provide a message.

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

Required concepts:

7.3.2.40. Constraint junit5:NonJUnit5TestMethod

Only the jUnit 5-test annotation must be used to identify test methods in a jUnit 5-based project.

MATCH
  (:Artifact)-[:CONTAINS]->(t:Type)-[:DECLARES]->(m:Test:Method)
WHERE
  m:Junit3 OR m:Junit4
RETURN
  t AS TestClass,
  m AS TestMethod

Required concepts:

7.3.2.41. Constraint junit5:UsageOfJUnit4TestApi

Only the jUnit 5-test api must be used in a jUnit 5-based project.

MATCH
  (:Artifact)-[:CONTAINS]->(t:Type)-[:DECLARES]->(m:Test:Method),
  (m)-[:INVOKES*..3]->(:Junit4:Assert:Method)
RETURN DISTINCT
  t AS TestClass,
  m AS TestMethod

Required concepts:

7.3.2.43. 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.3.2.44. 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.3.2.45. 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.3.2.46. Constraint junit:AssertionMustProvideMessage

The rule is deprecated: This constraint has been replaced by "junit4:AssertionMustProvideMessage" and "junit5: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.3.2.47. 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.4. jQAssistant Maven 3 Plugin

Provides a scanner for Maven 3 modules.

7.4.1. Scanner for Maven projects

Imports information from Maven projects.

7.4.1.1. Configuration
Table 65. Configuration properties
Property Description Default

maven3.dependencies.scan

If set to true the declared dependencies will be scanned.

false

maven3.dependencies.includes

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

include all artifacts

maven3.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.4.1.2. Nodes labeled with :Maven:Project:File:Directory

A pom.xml file describing a single Maven project.

Table 66. 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 67. 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.4.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 68. 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 69. 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 70. Properties of :DEPENDS_ON
Name Description

scope

The declared scope, e.g. compile

optional

true indicates that this dependency is optional.

7.4.2. Scanner for Maven POMs

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

7.4.2.1. Nodes labeled with :Maven:Scm
Table 71. 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.4.2.2. Nodes labeled with :Maven:Pom

A POM describing a Maven project.

Table 72. 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 73. 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.4.2.3. Nodes labeled with :Maven:Dependency

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

Table 74. 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 75. 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.4.2.4. Nodes labeled with :Maven:Exclusion

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

Table 76. Properties of :Maven:Dependency
Name Description

groupId

The groupdId pattern

artifactId

The artifactId pattern

7.4.2.5. :Maven:Contributor

A contributor of the project.

Table 77. 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 78. 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.4.2.6. :Maven:Developer

A developer taking part in the development of the project.

Table 79. 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 80. 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.4.2.7. :Maven:Organization

The organization behind the project.

Table 81. Properties of :Maven:Organization
Name Description

name

The name of the organization.

url

The URL of the organization.

7.4.2.8. Nodes labeled with :Maven:Repository

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

Table 82. 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.4.2.9. :Maven:Role

The roles a person plays in the project.

Table 83. Properties of :Maven:Role
Name Description

name

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

7.4.2.10. Nodes labeled with :Maven:Profile

A maven profile

Table 84. Properties of :Maven:Profile
Name Description

id

The profile id

Table 85. 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.4.2.11. Nodes labeled with :Maven:ProfileActivation

A maven profile activation

Table 86. Properties of :Maven:ProfileActivation
Name Description

activeByDefault

Specifies if the profile is activated by default

jdk

Specifies jdk needed to activate the profile

Table 87. 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.4.2.12. Nodes labeled with :Maven:ActivationFile

File specification used to activate a profile

Table 88. 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.4.2.13. Nodes labeled with :Maven:ActivationOS

Defines operating system’s attributes to activate a profile

Table 89. 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.4.2.14. Nodes labeled with :Maven:Module

A Maven module

Table 90. Properties of :Maven:Module
Name Description

name

The module name

7.4.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 91. Properties of :Maven:Plugin
Name Description

inherited

Whether any configuration should be propagated to child POMs

Table 92. 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.4.2.16. Nodes labeled with :Maven:License

A used license

Table 93. 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.4.2.17. Nodes labeled with :Maven:PluginExecution

A plugin execution

Table 94. 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 95. 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.4.2.18. Nodes labeled with :Maven:Configuration

A configuration for plugins, executions

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

CONTAINS

:Java:Value

0..n

References a value or a list of values

7.4.2.19. Nodes labeled with :Maven:ExecutionGoal

A goal for plugin executions

Table 97. Properties of :Maven:ExecutionGoal
Name Description

name

The name of the goal

7.4.3. Rules provided by the jQAssistant Maven 3 Plugin

7.4.3.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.5. jQAssistant XML Plugin

Provides scanners for XML and XSD documents.

7.5.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.5.1.1. Configuration
Table 98. 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.5.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.5.2.1. :Xml:Document

Represents an XML document.

Table 99. 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 100. Relations of :Xml:Document
Name Target label(s) Cardinality Description

HAS_ROOT_ELEMENT

:Xml:Element

1

References the root element of the document.

7.5.2.2. :Xml:Element

An XML element.

Table 101. Properties of :Xml:Element
Name Description

value

The text value.

lineNumber

Last line number of the start tag of the element.

Table 102. 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.5.2.3. :Xml:Namespace

A XML namespace declaration.

Table 103. Properties of :Xml:Namespace
Name Description

uri

The namespace URI.

prefix

The optional namespace prefix

7.5.2.4. :Xml:Attribute

An XML attribute.

Table 104. Properties of :Xml:Attribute
Name Description

name

The name of the atribute.

value

The value of the attribute.

Table 105. Relations of :Xml:Attribute
Name Target label(s) Cardinality Description

OF_NAMESPACE

:Xml:Namespace

0..1

References the namespace of the attribute.

7.5.2.5. :Xml:Text

A text value of an XML element.

Table 106. Properties of :Xml:Text
Name Description

value

The text value.

lineNumber

Last line number

7.5.3. Generic scanner for XSD files

Imports all files with the file name suffix ".xsd" using the Scanner for XML files.