A plugin is a Set of Extensions

A Sonar plugin is a set of Java objects that implement extension points. These extension points are interfaces or abstract classes which model an aspect of the system and define contracts of what needs to be implemented. They can be for example pages in the web application or sensors generating measures.

The extensions implemented in the plugin must be declared in a Java class extending org.sonar.api.Plugin. This class must then be declared in the pom with the property <pluginClass> :

Extension Points

Here is list of extension points available in the sonar plugin API. Please note that partial implementation of those extensions are available in the api as well. See all known sub-interfaces and implementing classes of org.sonar.api.Extension to get an exhaustive list.

Batch side

What

Since

Description

org.sonar.api.batch.CpdMapping

1.10

CPD definition to detect duplicated lines on a new language

org.sonar.api.batch.Decorator

1.10

Used to decorate resources, i.e. calculate measures from other measures. Example : the number of lines of code of a package is the sum of the lines of its classes.

org.sonar.api.resources.Language

1.10

Define a new language.

org.sonar.api.batch.maven.MavenPluginHandler

1.10

Define a Maven2 plugin to execute before analyzing the project.

org.sonar.api.measures.Metrics

1.10

List new Metrics. A metric is an instance of org.sonar.api.measure.Metric. It can be quantitative (lines of code, number of rule violations) or qualitative (code coverage, complexity by class, rules compliance). As a rule, a metric is used to store a number but it can also be used to store a text field with list of key/value pairs, an XML or even binary data.

Provides logic to determine which users are interested in receiving notification. Example : notify me when when someone changes review assigned to me or created by me.

Sensor or Decorator?

There are two extensions that enables to save measures : Sensor and Decorator. A common problem when writing a plugin is to decide which one to use.

Sensor

A Sensor is invoked once during the analysis of a project. The sensor can invoke a maven plugin, parse a flat file, connect to a web server... For example the Cobertura Sensor invokes the Codehaus Cobertura MOJO. Then the generated XML file is parsed and used to save the first-level of measures on resources (project, package or class). A sensor can access and save measures on the whole tree of resources. Sensor are generally used to add measure at the lowest level of the resource tree.

Decorator

Decorators are triggered once all sensors have completed. Their decorate method is called on every resource of a certain level bottom up. Decorators can load (SELECT) and save (INSERT) measures. The call is contextual, i.e it is only possible to access the resource and its children. Decorators are generally used to consolidate at higher levels measures that have been added by Sensors at the lowest level.

How to Reuse Existing Components?

Extensions are registered in an IoC container, with constructor injection. To communicate with other extensions or with existing components provided by the API, just declare them in the constructor of your extension. For example to get references on DatabaseSession or RulesProfile:

You should never directly instantiate classes which implements BatchComponent or ServerComponent , because they should be retrieved as an IoC dependency. Otherwise it leads to issues with backward compatibility.

How to Quickly Start the Plugin?

As described in the Getting Started page, you can build sources, copy the JAR file to the directory extensions/plugins/ and restart the server. But this approach can quickly become tedious. The following solutions help to edit code without leaving your development environment:

Changes on Java code

The sonar-dev-maven-plugin allows to start a Sonar server and to deploy the plugin.

Once the server is launched, hit http://localhost:9000. By default, the in-process database (H2, or Derby prior to Sonar 3.2) is used but you can specify to use a local MySQL instance with the property "-Dsonar.database=mysql". In that case, the sonar schema must exist in the MySQL DB along with the user sonar/sonar (login/password) who must have all rights on the sonar schema.

Then you can feed the database by inspecting projects :

Note for Mac OS

Icon

Add the property -Djava.io.tmpdir=/tmp to the mvn command.

Limitation

Icon

Changes on Java code are not reloaded dynamically. You need to rebuild the plugin and to re-execute sonar-dev-maven-plugin.

To benefit from advanced features (default value, availability in the settings page), properties should be declared on the Plugin entry point or on extensions :

Persistent properties are also accessible from the Web Service named 'properties'. To exclude some properties from anonymous requests, add the suffix ".secured" to the key (my.property.secured). It can be useful for license keys for example.