= Gerrit Code Review - Plugin Development

The Gerrit server functionality can be extended by installing plugins.
This page describes how plugins for Gerrit can be developed.

Depending on how tightly the extension code is coupled with the Gerrit
server code, there is a distinction between `plugins` and `extensions`.

[[plugin]]
A `plugin` in Gerrit is tightly coupled code that runs in the same
JVM as Gerrit. It has full access to all server internals. Plugins
are tightly coupled to a specific major.minor server version and
may require source code changes to compile against a different
server version.

[[extension]]
An `extension` in Gerrit runs inside of the same JVM as Gerrit
in the same way as a plugin, but has limited visibility to the
server's internals. The limited visibility reduces the extension's
dependencies, enabling it to be compatible across a wider range
of server versions.

Most of this documentation refers to either type as a plugin.

[[getting-started]]
== Getting started

To get started with the development of a plugin there are two
recommended ways:

. use the Gerrit Plugin Maven archetype to create a new plugin project:
+
With the Gerrit Plugin Maven archetype you can create a skeleton for a
plugin project.
+
----
mvn archetype:generate -DarchetypeGroupId=com.google.gerrit \
    -DarchetypeArtifactId=gerrit-plugin-archetype \
    -DarchetypeVersion=2.14-SNAPSHOT \
    -DgroupId=com.googlesource.gerrit.plugins.testplugin \
    -DartifactId=testplugin
----
+
Maven will ask for additional properties and then create the plugin in
the current directory. To change the default property values answer 'n'
when Maven asks to confirm the properties configuration. It will then
ask again for all properties including those with predefined default
values.

. clone the sample plugin:
+
This is a project that demonstrates the various features of the
plugin API. It can be taken as an example to develop an own plugin.
+
----
$ git clone https://gerrit.googlesource.com/plugins/cookbook-plugin
----
+
When starting from this example one should take care to adapt the
`Gerrit-ApiVersion` in the `pom.xml` to the version of Gerrit for which
the plugin is developed. If the plugin is developed for a released
Gerrit version (no `SNAPSHOT` version) then the URL for the
`gerrit-api-repository` in the `pom.xml` needs to be changed to
`https://gerrit-api.storage.googleapis.com/release/`.

[[API]]
== API

There are two different API formats offered against which plugins can
be developed:

gerrit-extension-api.jar::
  A stable but thin interface. Suitable for extensions that need
  to be notified of events, but do not require tight coupling to
  the internals of Gerrit. Extensions built against this API can
  expect to be binary compatible across a wide range of server
  versions.

gerrit-plugin-api.jar::
  The complete internals of the Gerrit server, permitting a
  plugin to tightly couple itself and provide additional
  functionality that is not possible as an extension. Plugins
  built against this API are expected to break at the source
  code level between every major.minor Gerrit release. A plugin
  that compiles against 2.5 will probably need source code level
  changes to work with 2.6, 2.7, and so on.

== Manifest

Plugins may provide optional description information with standard
manifest fields:

----
  Implementation-Title: Example plugin showing examples
  Implementation-Version: 1.0
  Implementation-Vendor: Example, Inc.
----

=== ApiType

Plugins using the tightly coupled `gerrit-plugin-api.jar` must
declare this API dependency in the manifest to gain access to server
internals. If no `Gerrit-ApiType` is specified the stable `extension`
API will be assumed. This may cause ClassNotFoundExceptions when
loading a plugin that needs the plugin API.

----
  Gerrit-ApiType: plugin
----

=== Explicit Registration

Plugins that use explicit Guice registration must name the Guice
modules in the manifest. Up to three modules can be named in the
manifest. `Gerrit-Module` supplies bindings to the core server;
`Gerrit-SshModule` supplies SSH commands to the SSH server (if
enabled); `Gerrit-HttpModule` supplies servlets and filters to the HTTP
server (if enabled). If no modules are named automatic registration
will be performed by scanning all classes in the plugin JAR for
`@Listen` and `@Export("")` annotations.

----
  Gerrit-Module:     tld.example.project.CoreModuleClassName
  Gerrit-SshModule:  tld.example.project.SshModuleClassName
  Gerrit-HttpModule: tld.example.project.HttpModuleClassName
----

[[plugin_name]]
=== Plugin Name

A plugin can optionally provide its own plugin name.

----
  Gerrit-PluginName: replication
----

This is useful for plugins that contribute plugin-owned capabilities that
are stored in the `project.config` file. Another use case is to be able to put
project specific plugin configuration section in `project.config`. In this
case it is advantageous to reserve the plugin name to access the configuration
section in the `project.config` file.

If `Gerrit-PluginName` is omitted, then the plugin's name is determined from
the plugin file name.

If a plugin provides its own name, then that plugin cannot be deployed
multiple times under different file names on one Gerrit site.

For Maven driven plugins, the following line must be included in the pom.xml
file:

[source,xml]
----
<manifestEntries>
  <Gerrit-PluginName>name</Gerrit-PluginName>
</manifestEntries>
----

For Buck driven plugins, the following line must be included in the BUCK
configuration file:

[source,python]
----
manifest_entries = [
   'Gerrit-PluginName: name',
]
----

A plugin can get its own name injected at runtime:

[source,java]
----
public class MyClass {

  private final String pluginName;

  @Inject
  public MyClass(@PluginName String pluginName) {
    this.pluginName = pluginName;
  }

  [...]
}
----

A plugin can get its canonical web URL injected at runtime:

[source,java]
----
public class MyClass {

  private final String url;

  @Inject
  public MyClass(@PluginCanonicalWebUrl String url) {
    this.url = url;
  }

  [...]
}
----

The URL is composed of the server's canonical web URL and the plugin's
name, i.e. `http://review.example.com:8080/plugin-name`.

The canonical web URL may be injected into any .jar plugin regardless of
whether or not the plugin provides an HTTP servlet.

[[reload_method]]
=== Reload Method

If a plugin holds an exclusive resource that must be released before
loading the plugin again (for example listening on a network port or
acquiring a file lock) the manifest must declare `Gerrit-ReloadMode`
to be `restart`. Otherwise the preferred method of `reload` will
be used, as it enables the server to hot-patch an updated plugin
with no down time.

----
  Gerrit-ReloadMode: restart
----

In either mode ('restart' or 'reload') any plugin or extension can
be updated without restarting the Gerrit server. The difference is
how Gerrit handles the upgrade:

restart::
  The old plugin is completely stopped. All registrations of SSH
  commands and HTTP servlets are removed. All registrations of any
  extension points are removed. All registered LifecycleListeners
  have their `stop()` method invoked in reverse order. The new
  plugin is started, and registrations are made from the new
  plugin. There is a brief window where neither the old nor the
  new plugin is connected to the server. This means SSH commands
  and HTTP servlets will return not found errors, and the plugin
  will not be notified of events that occurred during the restart.

reload::
  The new plugin is started. Its LifecycleListeners are permitted
  to perform their `start()` methods. All SSH and HTTP registrations
  are atomically swapped out from the old plugin to the new plugin,
  ensuring the server never returns a not found error. All extension
  point listeners are atomically swapped out from the old plugin to
  the new plugin, ensuring no events are missed (however some events
  may still route to the old plugin if the swap wasn't complete yet).
  The old plugin is stopped.

To reload/restart a plugin the link:cmd-plugin-reload.html[plugin reload]
command can be used.

[[init_step]]
=== Init step

Plugins can contribute their own "init step" during the Gerrit init
wizard. This is useful for guiding the Gerrit administrator through
the settings needed by the plugin to work properly.

For instance plugins to integrate Jira issues to Gerrit changes may
contribute their own "init step" to allow configuring the Jira URL,
credentials and possibly verify connectivity to validate them.

----
  Gerrit-InitStep: tld.example.project.MyInitStep
----

MyInitStep needs to follow the standard Gerrit InitStep syntax
and behavior: writing to the console using the injected ConsoleUI
and accessing / changing configuration settings using Section.Factory.

In addition to the standard Gerrit init injections, plugins receive
the @PluginName String injection containing their own plugin name.

During their initialization plugins may get access to the
`project.config` file of the `All-Projects` project and they are able
to store configuration parameters in it. For this a plugin `InitStep`
can get `com.google.gerrit.pgm.init.api.AllProjectsConfig` injected:

[source,java]
----
  public class MyInitStep implements InitStep {
    private final String pluginName;
    private final ConsoleUI ui;
    private final AllProjectsConfig allProjectsConfig;

    @Inject
    public MyInitStep(@PluginName String pluginName, ConsoleUI ui,
        AllProjectsConfig allProjectsConfig) {
      this.pluginName = pluginName;
      this.ui = ui;
      this.allProjectsConfig = allProjectsConfig;
    }

    @Override
    public void run() throws Exception {
    }

    @Override
    public void postRun() throws Exception {
      ui.message("\n");
      ui.header(pluginName + " Integration");
      boolean enabled = ui.yesno(true, "By default enabled for all projects");
      Config cfg = allProjectsConfig.load().getConfig();
      if (enabled) {
        cfg.setBoolean("plugin", pluginName, "enabled", enabled);
      } else {
        cfg.unset("plugin", pluginName, "enabled");
      }
      allProjectsConfig.save(pluginName, "Initialize " + pluginName + " Integration");
    }
  }
----

Bear in mind that the Plugin's InitStep class will be loaded but
the standard Gerrit runtime environment is not available and the plugin's
own Guice modules were not initialized.
This means the InitStep for a plugin is not executed in the same way that
the plugin executes within the server, and may mean a plugin author cannot
trivially reuse runtime code during init.

For instance a plugin that wants to verify connectivity may need to statically
call the constructor of their connection class, passing in values obtained
from the Section.Factory rather than from an injected Config object.

Plugins' InitSteps are executed during the "Gerrit Plugin init" phase, after
the extraction of the plugins embedded in the distribution .war file into
`$GERRIT_SITE/plugins` and before the DB Schema initialization or upgrade.

A plugin's InitStep cannot refer to Gerrit's DB Schema or any other Gerrit
runtime objects injected at startup.

[source,java]
----
public class MyInitStep implements InitStep {
  private final ConsoleUI ui;
  private final Section.Factory sections;
  private final String pluginName;

  @Inject
  public GitBlitInitStep(final ConsoleUI ui, Section.Factory sections, @PluginName String pluginName) {
    this.ui = ui;
    this.sections = sections;
    this.pluginName = pluginName;
  }

  @Override
  public void run() throws Exception {
    ui.header("\nMy plugin");

    Section mySection = getSection("myplugin", null);
    mySection.string("Link name", "linkname", "MyLink");
  }

  @Override
  public void postRun() throws Exception {
  }
}
----

[[classpath]]
== Classpath

Each plugin is loaded into its own ClassLoader, isolating plugins
from each other. A plugin or extension inherits the Java runtime
and the Gerrit API chosen by `Gerrit-ApiType` (extension or plugin)
from the hosting server.

Plugins are loaded from a single JAR file. If a plugin needs
additional libraries, it must include those dependencies within
its own JAR. Plugins built using Maven may be able to use the
link:http://maven.apache.org/plugins/maven-shade-plugin/[shade plugin]
to package additional dependencies. Relocating (or renaming) classes
should not be necessary due to the ClassLoader isolation.

[[events]]
== Listening to Events

Certain operations in Gerrit trigger events. Plugins may receive
notifications of these events by implementing the corresponding
listeners.

* `com.google.gerrit.common.EventListener`:
+
Allows to listen to events without user visibility restrictions. These
are the same link:cmd-stream-events.html#events[events] that are also streamed by
the link:cmd-stream-events.html[gerrit stream-events] command.

* `com.google.gerrit.common.UserScopedEventListener`:
+
Allows to listen to events visible to the specified user. These are the
same link:cmd-stream-events.html#events[events] that are also streamed
by the link:cmd-stream-events.html[gerrit stream-events] command.

* `com.google.gerrit.extensions.events.LifecycleListener`:
+
Plugin start and stop

* `com.google.gerrit.extensions.events.NewProjectCreatedListener`:
+
Project creation

* `com.google.gerrit.extensions.events.ProjectDeletedListener`:
+
Project deletion

* `com.google.gerrit.extensions.events.HeadUpdatedListener`:
+
Update of HEAD on a project

* `com.google.gerrit.extensions.events.UsageDataPublishedListener`:
+
Publication of usage data

* `com.google.gerrit.extensions.events.GarbageCollectorListener`:
+
Garbage collection ran on a project

* `com.google.gerrit.server.extensions.events.ChangeIndexedListener`:
+
Update of the secondary index

* `com.google.gerrit.httpd.WebLoginListener`:
+
User login or logout interactively on the Web user interface.

The event listener is under the Gerrit http package to automatically
inherit the javax.servlet.http dependencies and allowing to influence
the login or logout flow with additional redirections.

[[stream-events]]
== Sending Events to the Events Stream

Plugins may send events to the events stream where consumers of
Gerrit's `stream-events` ssh command will receive them.

To send an event, the plugin must invoke one of the `postEvent`
methods in the `EventDispatcher` interface, passing an instance of
its own custom event class derived from
`com.google.gerrit.server.events.Event`.

[source,java]
----
import com.google.gerrit.common.EventDispatcher;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

class MyPlugin {
  private final DynamicItem<EventDispatcher> eventDispatcher;

  @Inject
  myPlugin(DynamicItem<EventDispatcher> eventDispatcher) {
    this.eventDispatcher = eventDispatcher;
  }

  private void postEvent(MyPluginEvent event) {
    try {
      eventDispatcher.get().postEvent(event);
    } catch (OrmException e) {
      // error handling
    }
  }
}
----

Plugins which define new Events should register them via the
`com.google.gerrit.server.events.EventTypes.registerClass()`
method. This will make the EventType known to the system.
Deserializing events with the
`com.google.gerrit.server.events.EventDeserializer` class requires
that the event be registered in EventTypes.

== Modifying the Stream Event Flow

It is possible to modify the stream event flow from plugins by registering
an `com.google.gerrit.server.events.EventDispatcher`. A plugin may register
a Dispatcher class to replace the internal Dispatcher. EventDispatcher is
a DynamicItem, so Gerrit may only have one copy.

[[validation]]
== Validation Listeners

Certain operations in Gerrit can be validated by plugins by
implementing the corresponding link:config-validation.html[listeners].

[[receive-pack]]
== Receive Pack Initializers

Plugins may provide ReceivePack initializers which will be invoked
by Gerrit just before a ReceivePack instance will be used. Usually,
plugins will make use of the setXXX methods on the ReceivePack to
set additional properties on it.

[[post-receive-hook]]
== Post Receive-Pack Hooks

Plugins may register PostReceiveHook instances in order to get
notified when JGit successfully receives a pack. This may be useful
for those plugins which would like to monitor changes in Git
repositories.

[[pre-upload-hook]]
== Pre Upload-Pack Hooks

Plugins may register PreUploadHook instances in order to get
notified when JGit is about to upload a pack. This may be useful
for those plugins which would like to monitor usage in Git
repositories.

[[post-upload-hook]]
== Post Upload-Pack Hooks

Plugins may register PostUploadHook instances in order to get notified after
JGit is done uploading a pack.

[[ssh]]
== SSH Commands

Plugins may provide commands that can be accessed through the SSH
interface (extensions do not have this option).

Command implementations must extend the base class SshCommand:

[source,java]
----
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.CommandMetaData;

@CommandMetaData(name="print", description="Print hello command")
class PrintHello extends SshCommand {
  @Override
  protected void run() {
    stdout.print("Hello\n");
  }
}
----

If no Guice modules are declared in the manifest, SSH commands may
use auto-registration by providing an `@Export` annotation:

[source,java]
----
import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.sshd.SshCommand;

@Export("print")
class PrintHello extends SshCommand {
  @Override
  protected void run() {
    stdout.print("Hello\n");
  }
}
----

If explicit registration is being used, a Guice module must be
supplied to register the SSH command and declared in the manifest
with the `Gerrit-SshModule` attribute:

[source,java]
----
import com.google.gerrit.sshd.PluginCommandModule;

class MyCommands extends PluginCommandModule {
  @Override
  protected void configureCommands() {
    command(PrintHello.class);
  }
}
----

For a plugin installed as name `helloworld`, the command implemented
by PrintHello class will be available to users as:

----
$ ssh -p 29418 review.example.com helloworld print
----

[[multiple-commands]]
=== Multiple Commands bound to one implementation

Multiple SSH commands can be bound to the same implementation class. For
example a Gerrit Shell plugin can bind different shell commands to the same
implementation class:

[source,java]
----
public class SshShellModule extends PluginCommandModule {
  @Override
  protected void configureCommands() {
    command("ls").to(ShellCommand.class);
    command("ps").to(ShellCommand.class);
    [...]
  }
}
----

With the possible implementation:

[source,java]
----
public class ShellCommand extends SshCommand {
  @Override
  protected void run() throws UnloggedFailure {
    String cmd = getName().substring(getPluginName().length() + 1);
    ProcessBuilder proc = new ProcessBuilder(cmd);
    Process cmd = proc.start();
    [...]
  }
}
----

And the call:

----
$ ssh -p 29418 review.example.com shell ls
$ ssh -p 29418 review.example.com shell ps
----

[[root-level-commands]]
=== Root Level Commands

Single command plugins are also supported. In this scenario plugin binds
SSH command to its own name. `SshModule` must inherit from
`SingleCommandPluginModule` class:

[source,java]
----
public class SshModule extends SingleCommandPluginModule {
 @Override
 protected void configure(LinkedBindingBuilder<Command> b) {
    b.to(ShellCommand.class);
  }
}
----

If the plugin above is deployed under sh.jar file in `$site/plugins`
directory, generic commands can be called without specifying the
actual SSH command. Note in the example below, that the called commands
`ls` and `ps` was not explicitly bound:

----
$ ssh -p 29418 review.example.com sh ls
$ ssh -p 29418 review.example.com sh ps
----

[[search_operators]]
== Search Operators

Plugins can define new search operators to extend change searching by
implementing the `ChangeQueryBuilder.ChangeOperatorFactory` interface
and registering it to an operator name in the plugin module's
`configure()` method.  The search operator name is defined during
registration via the DynamicMap annotation mechanism.  The plugin
name will get appended to the annotated name, with an underscore
in between, leading to the final operator name.  An example
registration looks like this:

    bind(ChangeOperatorFactory.class)
       .annotatedWith(Exports.named("sample"))
       .to(SampleOperator.class);

If this is registered in the `myplugin` plugin, then the resulting
operator will be named `sample_myplugin`.

The search operator itself is implemented by ensuring that the
`create()` method of the class implementing the
`ChangeQueryBuilder.ChangeOperatorFactory` interface returns a
`Predicate<ChangeData>`.  Here is a sample operator factory
definition which creates a `MyPredicate`:

[source,java]
----
@Singleton
public class SampleOperator
    implements ChangeQueryBuilder.ChangeOperatorFactory {
  public static class MyPredicate extends OperatorChangePredicate<ChangeData> {
    ...
  }

  @Override
  public Predicate<ChangeData> create(ChangeQueryBuilder builder, String value)
      throws QueryParseException {
    return new MyPredicate(value);
  }
}
----

[[search_operands]]
=== Search Operands ===

Plugins can define new search operands to extend change searching.
Plugin methods implementing search operands (returning a
`Predicate<ChangeData>`), must be defined on a class implementing
one of the `ChangeQueryBuilder.ChangeOperandsFactory` interfaces
(.e.g., ChangeQueryBuilder.ChangeHasOperandFactory).  The specific
`ChangeOperandFactory` class must also be bound to the `DynamicSet` from
a module's `configure()` method in the plugin.

The new operand, when used in a search would appear as:
  operatorName:operandName_pluginName

A sample `ChangeHasOperandFactory` class implementing, and registering, a
new `has:sample_pluginName` operand is shown below:

====
  @Singleton
  public class SampleHasOperand implements ChangeHasOperandFactory {
    public static class Module extends AbstractModule {
      @Override
      protected void configure() {
        bind(ChangeHasOperandFactory.class)
            .annotatedWith(Exports.named("sample")
            .to(SampleHasOperand.class);
      }
    }

    @Override
    public Predicate<ChangeData> create(ChangeQueryBuilder builder)
        throws QueryParseException {
      return new HasSamplePredicate();
    }
====


[[simple-configuration]]
== Simple Configuration in `gerrit.config`

In Gerrit, global configuration is stored in the `gerrit.config` file.
If a plugin needs global configuration, this configuration should be
stored in a `plugin` subsection in the `gerrit.config` file.

This approach of storing the plugin configuration is only suitable for
plugins that have a simple configuration that only consists of
key-value pairs. With this approach it is not possible to have
subsections in the plugin configuration. Plugins that require a complex
configuration need to store their configuration in their
link:#configuration[own configuration file] where they can make use of
subsections. On the other hand storing the plugin configuration in a
'plugin' subsection in the `gerrit.config` file has the advantage that
administrators have all configuration parameters in one file, instead
of having one configuration file per plugin.

To avoid conflicts with other plugins, it is recommended that plugins
only use the `plugin` subsection with their own name. For example the
`helloworld` plugin should store its configuration in the
`plugin.helloworld` subsection:

----
[plugin "helloworld"]
  language = Latin
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its configuration and there is no need for a
plugin to parse the `gerrit.config` file on its own:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String language = cfg.getFromGerritConfig("helloworld")
                     .getString("language", "English");
----

[[configuration]]
== Configuration in own config file

Plugins can store their configuration in an own configuration file.
This makes sense if the plugin configuration is rather complex and
requires the usage of subsections. Plugins that have a simple
key-value pair configuration can store their configuration in a
link:#simple-configuration[`plugin` subsection of the `gerrit.config`
file].

The plugin configuration file must be named after the plugin and must
be located in the `etc` folder of the review site. For example a
configuration file for a `default-reviewer` plugin could look like
this:

.$site_path/etc/default-reviewer.config
----
[branch "refs/heads/master"]
  reviewer = Project Owners
  reviewer = john.doe@example.com
[match "file:^.*\.txt"]
  reviewer = My Info Developers
----

Plugins that have sensitive configuration settings can store those settings in
an own secure configuration file. The plugin's secure configuration file must be
named after the plugin and must be located in the `etc` folder of the review
site. For example a secure configuration file for a `default-reviewer` plugin
could look like this:

.$site_path/etc/default-reviewer.secure.config
----
[auth]
  password = secret
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its configuration:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String[] reviewers = cfg.getGlobalPluginConfig("default-reviewer")
                        .getStringList("branch", "refs/heads/master", "reviewer");
String password = cfg.getGlobalPluginConfig("default-reviewer")
                     .getString("auth", null, "password");
----


[[simple-project-specific-configuration]]
== Simple Project Specific Configuration in `project.config`

In Gerrit, project specific configuration is stored in the project's
`project.config` file on the `refs/meta/config` branch.  If a plugin
needs configuration on project level (e.g. to enable its functionality
only for certain projects), this configuration should be stored in a
`plugin` subsection in the project's `project.config` file.

This approach of storing the plugin configuration is only suitable for
plugins that have a simple configuration that only consists of
key-value pairs. With this approach it is not possible to have
subsections in the plugin configuration. Plugins that require a complex
configuration need to store their configuration in their
link:#project-specific-configuration[own configuration file] where they
can make use of subsections. On the other hand storing the plugin
configuration in a 'plugin' subsection in the `project.config` file has
the advantage that project owners have all configuration parameters in
one file, instead of having one configuration file per plugin.

To avoid conflicts with other plugins, it is recommended that plugins
only use the `plugin` subsection with their own name. For example the
`helloworld` plugin should store its configuration in the
`plugin.helloworld` subsection:

----
  [plugin "helloworld"]
    enabled = true
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its project specific configuration and there
is no need for a plugin to parse the `project.config` file on its own:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

boolean enabled = cfg.getFromProjectConfig(project, "helloworld")
                     .getBoolean("enabled", false);
----

It is also possible to get missing configuration parameters inherited
from the parent projects:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

boolean enabled = cfg.getFromProjectConfigWithInheritance(project, "helloworld")
                     .getBoolean("enabled", false);
----

Project owners can edit the project configuration by fetching the
`refs/meta/config` branch, editing the `project.config` file and
pushing the commit back.

Plugin configuration values that are stored in the `project.config`
file can be exposed in the ProjectInfoScreen to allow project owners
to see and edit them from the UI.

For this an instance of `ProjectConfigEntry` needs to be bound for each
parameter. The export name must be a valid Git variable name. The
variable name is case-insensitive, allows only alphanumeric characters
and '-', and must start with an alphabetic character.

The example below shows how the parameters `plugin.helloworld.enabled`
and `plugin.helloworld.language` are bound to be editable from the
Web UI. For the parameter `plugin.helloworld.enabled` "Enable Greeting"
is provided as display name and the default value is set to `true`.
For the parameter `plugin.helloworld.language` "Preferred Language"
is provided as display name and "en" is set as default value.

[source,java]
----
class Module extends AbstractModule {
  @Override
  protected void configure() {
    bind(ProjectConfigEntry.class)
        .annotatedWith(Exports.named("enabled"))
        .toInstance(new ProjectConfigEntry("Enable Greeting", true));
    bind(ProjectConfigEntry.class)
        .annotatedWith(Exports.named("language"))
        .toInstance(new ProjectConfigEntry("Preferred Language", "en"));
  }
}
----

By overwriting the `onUpdate` method of `ProjectConfigEntry` plugins
can be notified when this configuration parameter is updated on a
project.

[[configuring-groups]]
=== Referencing groups in `project.config`

Plugins can refer to groups so that when they are renamed, the project
config will also be updated in this section. The proper format to use is
the string representation of a GroupReference, as shown below.

----
Group[group_name / group_uuid]
----

[[project-specific-configuration]]
== Project Specific Configuration in own config file

Plugins can store their project specific configuration in an own
configuration file in the projects `refs/meta/config` branch.
This makes sense if the plugins project specific configuration is
rather complex and requires the usage of subsections. Plugins that
have a simple key-value pair configuration can store their project
specific configuration in a link:#simple-project-specific-configuration[
`plugin` subsection of the `project.config` file].

The plugin configuration file in the `refs/meta/config` branch must be
named after the plugin. For example a configuration file for a
`default-reviewer` plugin could look like this:

.default-reviewer.config
----
[branch "refs/heads/master"]
  reviewer = Project Owners
  reviewer = john.doe@example.com
[match "file:^.*\.txt"]
  reviewer = My Info Developers
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its project specific configuration:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String[] reviewers = cfg.getProjectPluginConfig(project, "default-reviewer")
                        .getStringList("branch", "refs/heads/master", "reviewer");
----

It is also possible to get missing configuration parameters inherited
from the parent projects:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String[] reviewers = cfg.getProjectPluginConfigWithInheritance(project, "default-reviewer")
                        .getStringList("branch", "refs/heads/master", "reviewer");
----

Project owners can edit the project configuration by fetching the
`refs/meta/config` branch, editing the `<plugin-name>.config` file and
pushing the commit back.

== React on changes in project configuration

If a plugin wants to react on changes in the project configuration, it
can implement a `GitReferenceUpdatedListener` and filter on events for
the `refs/meta/config` branch:

[source,java]
----
public class MyListener implements GitReferenceUpdatedListener {

  private final MetaDataUpdate.Server metaDataUpdateFactory;

  @Inject
  MyListener(MetaDataUpdate.Server metaDataUpdateFactory) {
    this.metaDataUpdateFactory = metaDataUpdateFactory;
  }

  @Override
  public void onGitReferenceUpdated(Event event) {
    if (event.getRefName().equals(RefNames.REFS_CONFIG)) {
      Project.NameKey p = new Project.NameKey(event.getProjectName());
      try {
        ProjectConfig oldCfg = parseConfig(p, event.getOldObjectId());
        ProjectConfig newCfg = parseConfig(p, event.getNewObjectId());

        if (oldCfg != null && newCfg != null
            && !oldCfg.getProject().getSubmitType().equals(newCfg.getProject().getSubmitType())) {
          // submit type has changed
          ...
        }
      } catch (IOException | ConfigInvalidException e) {
        ...
      }
    }
  }

  private ProjectConfig parseConfig(Project.NameKey p, String idStr)
      throws IOException, ConfigInvalidException, RepositoryNotFoundException {
    ObjectId id = ObjectId.fromString(idStr);
    if (ObjectId.zeroId().equals(id)) {
      return null;
    }
    return ProjectConfig.read(metaDataUpdateFactory.create(p), id);
  }
}
----


[[capabilities]]
== Plugin Owned Capabilities

Plugins may provide their own capabilities and restrict usage of SSH
commands or `UiAction` to the users who are granted those capabilities.

Plugins define the capabilities by overriding the `CapabilityDefinition`
abstract class:

[source,java]
----
public class PrintHelloCapability extends CapabilityDefinition {
  @Override
  public String getDescription() {
    return "Print Hello";
  }
}
----

If no Guice modules are declared in the manifest, capability may
use auto-registration by providing an `@Export` annotation:

[source,java]
----
@Export("printHello")
public class PrintHelloCapability extends CapabilityDefinition {
  [...]
}
----

Otherwise the capability must be bound in a plugin module:

[source,java]
----
public class HelloWorldModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(CapabilityDefinition.class)
      .annotatedWith(Exports.named("printHello"))
      .to(PrintHelloCapability.class);
  }
}
----

With a plugin-owned capability defined in this way, it is possible to restrict
usage of an SSH command or `UiAction` to members of the group that were granted
this capability in the usual way, using the `RequiresCapability` annotation:

[source,java]
----
@RequiresCapability("printHello")
@CommandMetaData(name="print", description="Print greeting in different languages")
public final class PrintHelloWorldCommand extends SshCommand {
  [...]
}
----

Or with `UiAction`:

[source,java]
----
@RequiresCapability("printHello")
public class SayHelloAction extends UiAction<RevisionResource>
  implements RestModifyView<RevisionResource, SayHelloAction.Input> {
  [...]
}
----

Capability scope was introduced to differentiate between plugin-owned
capabilities and core capabilities. Per default the scope of the
`@RequiresCapability` annotation is `CapabilityScope.CONTEXT`, that means:

* when `@RequiresCapability` is used within a plugin the scope of the
capability is assumed to be that plugin.

* If `@RequiresCapability` is used within the core Gerrit Code Review server
(and thus is outside of a plugin) the scope is the core server and will use
the `GlobalCapability` known to Gerrit Code Review server.

If a plugin needs to use a core capability name (e.g. "administrateServer")
this can be specified by setting `scope = CapabilityScope.CORE`:

[source,java]
----
@RequiresCapability(value = "administrateServer", scope =
    CapabilityScope.CORE)
  [...]
----

[[ui_extension]]
== UI Extension

[[panels]]
=== Panels

GWT plugins can contribute panels to Gerrit screens.

Gerrit screens define extension points where plugins can add GWT
panels with custom controls:

* Change Screen:
** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER`:
+
Panel will be shown in the header bar to the right of the change
status.

** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_BUTTONS`:
+
Panel will be shown in the header bar on the right side of the buttons.

** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS`:
+
Panel will be shown in the header bar on the right side of the pop down
buttons.

** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_COMMIT_INFO_BLOCK`:
+
Panel will be shown below the commit info block.

** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK`:
+
Panel will be shown below the change info block.

** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_RELATED_INFO_BLOCK`:
+
Panel will be shown below the related info block.

** `GerritUiExtensionPoint.CHANGE_SCREEN_HISTORY_RIGHT_OF_BUTTONS`:
+
Panel will be shown in the history bar on the right side of the buttons.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.CHANGE_INFO`:
+
The link:rest-api-changes.html#change-info[ChangeInfo] entity for the
current change.
+
The link:rest-api-changes.html#revision-info[RevisionInfo] entity for
the current patch set.

* Project Info Screen:
** `GerritUiExtensionPoint.PROJECT_INFO_SCREEN_TOP`:
+
Panel will be shown at the top of the screen.

** `GerritUiExtensionPoint.PROJECT_INFO_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.PROJECT_NAME`:
+
The name of the project.

* User Password Screen:
** `GerritUiExtensionPoint.PASSWORD_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
+
The link:rest-api-accounts.html#account-info[AccountInfo] entity for
the current user.

* User Preferences Screen:
** `GerritUiExtensionPoint.PREFERENCES_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
+
The link:rest-api-accounts.html#account-info[AccountInfo] entity for
the current user.

* User Profile Screen:
** `GerritUiExtensionPoint.PROFILE_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen below the grid with the
profile data.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
+
The link:rest-api-accounts.html#account-info[AccountInfo] entity for
the current user.

Example panel:
[source,java]
----
public class MyPlugin extends PluginEntryPoint {
  @Override
  public void onPluginLoad() {
    Plugin.get().panel(GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
        new Panel.EntryPoint() {
          @Override
          public void onLoad(Panel panel) {
            panel.setWidget(new InlineLabel("My Panel for change "
                + panel.getInt(GerritUiExtensionPoint.Key.CHANGE_ID, -1));
          }
        });
  }
}
----

[[actions]]
=== Actions

Plugins can contribute UI actions on core Gerrit pages. This is useful
for workflow customization or exposing plugin functionality through the
UI in addition to SSH commands and the REST API.

For instance a plugin to integrate Jira with Gerrit changes may
contribute a "File bug" button to allow filing a bug from the change
page or plugins to integrate continuous integration systems may
contribute a "Schedule" button to allow a CI build to be scheduled
manually from the patch set panel.

Two different places on core Gerrit pages are supported:

* Change screen
* Project info screen

Plugins contribute UI actions by implementing the `UiAction` interface:

[source,java]
----
@RequiresCapability("printHello")
class HelloWorldAction implements UiAction<RevisionResource>,
    RestModifyView<RevisionResource, HelloWorldAction.Input> {
  static class Input {
    boolean french;
    String message;
  }

  private Provider<CurrentUser> user;

  @Inject
  HelloWorldAction(Provider<CurrentUser> user) {
    this.user = user;
  }

  @Override
  public String apply(RevisionResource rev, Input input) {
    final String greeting = input.french
        ? "Bonjour"
        : "Hello";
    return String.format("%s %s from change %s, patch set %d!",
        greeting,
        Strings.isNullOrEmpty(input.message)
            ? Objects.firstNonNull(user.get().getUserName(), "world")
            : input.message,
        rev.getChange().getId().toString(),
        rev.getPatchSet().getPatchSetId());
  }

  @Override
  public Description getDescription(
      RevisionResource resource) {
    return new Description()
        .setLabel("Say hello")
        .setTitle("Say hello in different languages");
  }
}
----

Sometimes plugins may want to be able to change the state of a patch set or
change in the `UiAction.apply()` method and reflect these changes on the core
UI. For example a buildbot plugin which exposes a 'Schedule' button on the
patch set panel may want to disable that button after the build was scheduled
and update the tooltip of that button. But because of Gerrit's caching
strategy the following must be taken into consideration.

The browser is allowed to cache the `UiAction` information until something on
the change is modified. More accurately the change row needs to be modified in
the database to have a more recent `lastUpdatedOn` or a new `rowVersion`, or
the +refs/meta/config+ of the project or any parents needs to change to a new
SHA-1. The ETag SHA-1 computation code can be found in the
`ChangeResource.getETag()` method.

The easiest way to accomplish this is to update `lastUpdatedOn` of the change:

[source,java]
----
@Override
public Object apply(RevisionResource rcrs, Input in) {
  // schedule a build
  [...]
  // update change
  ReviewDb db = dbProvider.get();
  try (BatchUpdate bu = batchUpdateFactory.create(
      db, project.getNameKey(), user, TimeUtil.nowTs())) {
    bu.addOp(change.getId(), new BatchUpdate.Op() {
      @Override
      public boolean updateChange(BatchUpdate.ChangeContext ctx) {
        return true;
      }
    });
    bu.execute();
  }
  [...]
}
----

`UiAction` must be bound in a plugin module:

[source,java]
----
public class Module extends AbstractModule {
  @Override
  protected void configure() {
    install(new RestApiModule() {
      @Override
      protected void configure() {
        post(REVISION_KIND, "say-hello")
            .to(HelloWorldAction.class);
      }
    });
  }
}
----

The module above must be declared in the `pom.xml` for Maven driven
plugins:

[source,xml]
----
<manifestEntries>
  <Gerrit-Module>com.googlesource.gerrit.plugins.cookbook.Module</Gerrit-Module>
</manifestEntries>
----

or in the `BUCK` configuration file for Buck driven plugins:

[source,python]
----
manifest_entries = [
  'Gerrit-Module: com.googlesource.gerrit.plugins.cookbook.Module',
]
----

In some use cases more user input must be gathered, for that `UiAction` can be
combined with the JavaScript API. This would display a small popup near the
activation button to gather additional input from the user. The JS file is
typically put in the `static` folder within the plugin's directory:

[source,javascript]
----
Gerrit.install(function(self) {
  function onSayHello(c) {
    var f = c.textfield();
    var t = c.checkbox();
    var b = c.button('Say hello', {onclick: function(){
      c.call(
        {message: f.value, french: t.checked},
        function(r) {
          c.hide();
          window.alert(r);
          c.refresh();
        });
    }});
    c.popup(c.div(
      c.prependLabel('Greeting message', f),
      c.br(),
      c.label(t, 'french'),
      c.br(),
      b));
    f.focus();
  }
  self.onAction('revision', 'say-hello', onSayHello);
});
----

The JS module must be exposed as a `WebUiPlugin` and bound as
an HTTP Module:

[source,java]
----
public class HttpModule extends HttpPluginModule {
  @Override
  protected void configureServlets() {
    DynamicSet.bind(binder(), WebUiPlugin.class)
        .toInstance(new JavaScriptPlugin("hello.js"));
  }
}
----

The HTTP module above must be declared in the `pom.xml` for Maven
driven plugins:

[source,xml]
----
<manifestEntries>
  <Gerrit-HttpModule>com.googlesource.gerrit.plugins.cookbook.HttpModule</Gerrit-HttpModule>
</manifestEntries>
----

or in the `BUCK` configuration file for Buck driven plugins

[source,python]
----
manifest_entries = [
  'Gerrit-HttpModule: com.googlesource.gerrit.plugins.cookbook.HttpModule',
]
----

If `UiAction` is annotated with the `@RequiresCapability` annotation, then the
capability check is done during the `UiAction` gathering, so the plugin author
doesn't have to set `UiAction.Description.setVisible()` explicitly in this
case.

The following prerequisites must be met, to satisfy the capability check:

* user is authenticated
* user is a member of a group which has the `Administrate Server` capability, or
* user is a member of a group which has the required capability

The `apply` method is called when the button is clicked. If `UiAction` is
combined with JavaScript API (its own JavaScript function is provided),
then a popup dialog is normally opened to gather additional user input.
A new button is placed on the popup dialog to actually send the request.

Every `UiAction` exposes a REST API endpoint. The endpoint from the example above
can be accessed from any REST client, i. e.:

----
  curl -X POST -H "Content-Type: application/json" \
    -d '{message: "François", french: true}' \
    --digest --user joe:secret \
    http://host:port/a/changes/1/revisions/1/cookbook~say-hello
  "Bonjour François from change 1, patch set 1!"
----

A special case is to bind an endpoint without a view name.  This is
particularly useful for `DELETE` requests:

[source,java]
----
public class Module extends AbstractModule {
  @Override
  protected void configure() {
    install(new RestApiModule() {
      @Override
      protected void configure() {
        delete(PROJECT_KIND)
            .to(DeleteProject.class);
      }
    });
  }
}
----

For a `UiAction` bound this way, a JS API function can be provided.

Currently only one restriction exists: per plugin only one `UiAction`
can be bound per resource without view name. To define a JS function
for the `UiAction`, "/" must be used as the name:

[source,javascript]
----
Gerrit.install(function(self) {
  function onDeleteProject(c) {
    [...]
  }
  self.onAction('project', '/', onDeleteProject);
});
----


[[action-visitor]]
=== Action Visitors

In addition to providing new actions, plugins can have fine-grained control
over the link:rest-api-changes.html#action-info[ActionInfo] map, modifying or
removing existing actions, including those contributed by core.

Visitors are provided the link:rest-api-changes.html#action-info[ActionInfo],
which is mutable, along with copies of the
link:rest-api-changes.html#change-info[ChangeInfo] and
link:rest-api-changes.html#revision-info[RevisionInfo]. They can modify the
action, or return `false` to exclude it from the resulting map.

These operations only affect the action buttons that are displayed in the UI;
the underlying REST API endpoints are not affected. Multiple plugins may
implement the visitor interface, but the order in which they are run is
undefined.

For example, to exclude "Cherry-Pick" only from certain projects, and rename
"Abandon":

[source,java]
----
public class MyActionVisitor implements ActionVisitor {
  @Override
  public boolean visit(String name, ActionInfo actionInfo,
      ChangeInfo changeInfo) {
    if (name.equals("abandon")) {
      actionInfo.label = "Drop";
    }
    return true;
  }

  @Override
  public boolean visit(String name, ActionInfo actionInfo,
      ChangeInfo changeInfo, RevisionInfo revisionInfo) {
    if (project.startsWith("some-team/") && name.equals("cherrypick")) {
      return false;
    }
    return true;
  }
}
----


[[top-menu-extensions]]
== Top Menu Extensions

Plugins can contribute items to Gerrit's top menu.

A single top menu extension can have multiple elements and will be put as
the last element in Gerrit's top menu.

Plugins define the top menu entries by implementing `TopMenu` interface:

[source,java]
----
public class MyTopMenuExtension implements TopMenu {

  @Override
  public List<MenuEntry> getEntries() {
    return Lists.newArrayList(
               new MenuEntry("Top Menu Entry", Lists.newArrayList(
                      new MenuItem("Gerrit", "http://gerrit.googlecode.com/"))));
  }
}
----

Plugins can also add additional menu items to Gerrit's top menu entries
by defining a `MenuEntry` that has the same name as a Gerrit top menu
entry:

[source,java]
----
public class MyTopMenuExtension implements TopMenu {

  @Override
  public List<MenuEntry> getEntries() {
    return Lists.newArrayList(
               new MenuEntry(GerritTopMenu.PROJECTS, Lists.newArrayList(
                      new MenuItem("Browse Repositories", "https://gerrit.googlesource.com/"))));
  }
}
----

`MenuItems` that are bound for the `MenuEntry` with the name
`GerritTopMenu.PROJECTS` can contain a `${projectName}` placeholder
which is automatically replaced by the actual project name.

E.g. plugins may register an link:#http[HTTP Servlet] to handle project
specific requests and add an menu item for this:

[source,java]
---
  new MenuItem("My Screen", "/plugins/myplugin/project/${projectName}");
---

This also enables plugins to provide menu items for project aware
screens:

[source,java]
---
  new MenuItem("My Screen", "/x/my-screen/for/${projectName}");
---

If no Guice modules are declared in the manifest, the top menu extension may use
auto-registration by providing an `@Listen` annotation:

[source,java]
----
@Listen
public class MyTopMenuExtension implements TopMenu {
  [...]
}
----

Otherwise the top menu extension must be bound in the plugin module used
for the Gerrit system injector (Gerrit-Module entry in MANIFEST.MF):

[source,java]
----
package com.googlesource.gerrit.plugins.helloworld;

public class HelloWorldModule extends AbstractModule {
  @Override
  protected void configure() {
    DynamicSet.bind(binder(), TopMenu.class).to(MyTopMenuExtension.class);
  }
}
----

[source,manifest]
----
Gerrit-ApiType: plugin
Gerrit-Module: com.googlesource.gerrit.plugins.helloworld.HelloWorldModule
----

It is also possible to show some menu entries only if the user has a
certain capability:

[source,java]
----
public class MyTopMenuExtension implements TopMenu {
  private final String pluginName;
  private final Provider<CurrentUser> userProvider;
  private final List<MenuEntry> menuEntries;

  @Inject
  public MyTopMenuExtension(@PluginName String pluginName,
      Provider<CurrentUser> userProvider) {
    this.pluginName = pluginName;
    this.userProvider = userProvider;
    menuEntries = new ArrayList<TopMenu.MenuEntry>();

    // add menu entry that is only visible to users with a certain capability
    if (canSeeMenuEntry()) {
      menuEntries.add(new MenuEntry("Top Menu Entry", Collections
          .singletonList(new MenuItem("Gerrit", "http://gerrit.googlecode.com/"))));
    }

    // add menu entry that is visible to all users (even anonymous users)
    menuEntries.add(new MenuEntry("Top Menu Entry", Collections
          .singletonList(new MenuItem("Documentation", "/plugins/myplugin/"))));
  }

  private boolean canSeeMenuEntry() {
    if (userProvider.get().isIdentifiedUser()) {
      CapabilityControl ctl = userProvider.get().getCapabilities();
      return ctl.canPerform(pluginName + "-" + MyCapability.ID)
          || ctl.canAdministrateServer();
    } else {
      return false;
    }
  }

  @Override
  public List<MenuEntry> getEntries() {
    return menuEntries;
  }
}
----


[[gwt_ui_extension]]
== GWT UI Extension
Plugins can extend the Gerrit UI with own GWT code.

The Maven archetype 'gerrit-plugin-gwt-archetype' can be used to
generate a GWT plugin skeleton. How to use the Maven plugin archetypes
is described in the link:#getting-started[Getting started] section.

The generated GWT plugin has a link:#top-menu-extensions[top menu] that
opens a GWT dialog box when the user clicks on it.

In addition to the Gerrit-Plugin API a GWT plugin depends on
`gerrit-plugin-gwtui`. This dependency must be specified in the
`pom.xml`:

[source,xml]
----
<dependency>
  <groupId>com.google.gerrit</groupId>
  <artifactId>gerrit-plugin-gwtui</artifactId>
  <version>${Gerrit-ApiVersion}</version>
</dependency>
----

A GWT plugin must contain a GWT module file, e.g. `HelloPlugin.gwt.xml`,
that bundles together all the configuration settings of the GWT plugin:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to="hello_gwt_plugin">
  <!-- Inherit the core Web Toolkit stuff. -->
  <inherits name="com.google.gwt.user.User"/>
  <!-- Other module inherits -->
  <inherits name="com.google.gerrit.Plugin"/>
  <inherits name="com.google.gwt.http.HTTP"/>
  <!-- Using GWT built-in themes adds a number of static -->
  <!-- resources to the plugin. No theme inherits lines were -->
  <!-- added in order to make this plugin as simple as possible -->
  <!-- Specify the app entry point class. -->
  <entry-point class="${package}.client.HelloPlugin"/>
  <stylesheet src="hello.css"/>
</module>
----

The GWT module must inherit `com.google.gerrit.Plugin` and
`com.google.gwt.http.HTTP`.

To register the GWT module a `GwtPlugin` needs to be bound.

If no Guice modules are declared in the manifest, the GWT plugin may
use auto-registration by using the `@Listen` annotation:

[source,java]
----
@Listen
public class MyExtension extends GwtPlugin {
  public MyExtension() {
    super("hello_gwt_plugin");
  }
}
----

Otherwise the binding must be done in an `HttpModule`:

[source,java]
----
public class HttpModule extends HttpPluginModule {

  @Override
  protected void configureServlets() {
    DynamicSet.bind(binder(), WebUiPlugin.class)
        .toInstance(new GwtPlugin("hello_gwt_plugin"));
  }
}
----

The HTTP module above must be declared in the `pom.xml` for Maven
driven plugins:

[source,xml]
----
<manifestEntries>
  <Gerrit-HttpModule>com.googlesource.gerrit.plugins.myplugin.HttpModule</Gerrit-HttpModule>
</manifestEntries>
----

The name that is provided to the `GwtPlugin` must match the GWT
module name compiled into the plugin. The name of the GWT module
can be explicitly set in the GWT module XML file by specifying
the `rename-to` attribute on the module. It is important that the
module name be unique across all plugins installed on the server,
as the module name determines the JavaScript namespace used by the
compiled plugin code.

[source,xml]
----
<module rename-to="hello_gwt_plugin">
----

The actual GWT code must be implemented in a class that extends
`com.google.gerrit.plugin.client.PluginEntryPoint`:

[source,java]
----
public class HelloPlugin extends PluginEntryPoint {

  @Override
  public void onPluginLoad() {
    // Create the dialog box
    final DialogBox dialogBox = new DialogBox();

    // The content of the dialog comes from a User specified Preference
    dialogBox.setText("Hello from GWT Gerrit UI plugin");
    dialogBox.setAnimationEnabled(true);
    Button closeButton = new Button("Close");
    VerticalPanel dialogVPanel = new VerticalPanel();
    dialogVPanel.setWidth("100%");
    dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
    dialogVPanel.add(closeButton);

    closeButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        dialogBox.hide();
      }
    });

    // Set the contents of the Widget
    dialogBox.setWidget(dialogVPanel);

    RootPanel rootPanel = RootPanel.get(HelloMenu.MENU_ID);
    rootPanel.getElement().removeAttribute("href");
    rootPanel.addDomHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
          dialogBox.center();
          dialogBox.show();
        }
    }, ClickEvent.getType());
  }
}
----

This class must be set as entry point in the GWT module:

[source,xml]
----
<entry-point class="${package}.client.HelloPlugin"/>
----

In addition this class must be defined as module in the `pom.xml` for the
`gwt-maven-plugin` and the `webappDirectory` option of `gwt-maven-plugin`
must be set to `${project.build.directory}/classes/static`:

[source,xml]
----
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>gwt-maven-plugin</artifactId>
  <version>2.7.0</version>
  <configuration>
    <module>com.googlesource.gerrit.plugins.myplugin.HelloPlugin</module>
    <disableClassMetadata>true</disableClassMetadata>
    <disableCastChecking>true</disableCastChecking>
    <webappDirectory>${project.build.directory}/classes/static</webappDirectory>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>
----

To attach a GWT widget defined by the plugin to the Gerrit core UI
`com.google.gwt.user.client.ui.RootPanel` can be used to manipulate the
Gerrit core widgets:

[source,java]
----
RootPanel rootPanel = RootPanel.get(HelloMenu.MENU_ID);
rootPanel.getElement().removeAttribute("href");
rootPanel.addDomHandler(new ClickHandler() {
  @Override
  public void onClick(ClickEvent event) {
    dialogBox.center();
    dialogBox.show();
  }
}, ClickEvent.getType());
----

GWT plugins can come with their own css file. This css file must have a
unique name and must be registered in the GWT module:

[source,xml]
----
<stylesheet src="hello.css"/>
----

If a GWT plugin wants to invoke the Gerrit REST API it can use
`com.google.gerrit.plugin.client.rpc.RestApi` to construct the URL
path and to trigger the REST calls.

Example for invoking a Gerrit core REST endpoint:

[source,java]
----
new RestApi("projects").id(projectName).view("description")
    .put("new description", new AsyncCallback<JavaScriptObject>() {

  @Override
  public void onSuccess(JavaScriptObject result) {
    // TODO
  }

  @Override
  public void onFailure(Throwable caught) {
    // never invoked
  }
});
----

Example for invoking a REST endpoint defined by a plugin:

[source,java]
----
new RestApi("projects").id(projectName).view("myplugin", "myview")
    .get(new AsyncCallback<JavaScriptObject>() {

  @Override
  public void onSuccess(JavaScriptObject result) {
    // TODO
  }

  @Override
  public void onFailure(Throwable caught) {
    // never invoked
  }
});
----

The `onFailure(Throwable)` of the provided callback is never invoked.
If an error occurs, it is shown in an error dialog.

In order to be able to do REST calls the GWT module must inherit
`com.google.gwt.json.JSON`:

[source,xml]
----
<inherits name="com.google.gwt.json.JSON"/>
----

[[screen]]
== Add Screen
A link:#gwt_ui_extension[GWT plugin] can link:#top-menu-extensions[add
a menu item] that opens a screen that is implemented by the plugin.
This way plugin screens can be fully integrated into the Gerrit UI.

Example menu item:
[source,java]
----
public class MyMenu implements TopMenu {
  private final List<MenuEntry> menuEntries;

  @Inject
  public MyMenu(@PluginName String name) {
    menuEntries = new ArrayList<>();
    menuEntries.add(new MenuEntry("My Menu", Collections.singletonList(
      new MenuItem("My Screen", "#/x/" + name + "/my-screen", ""))));
  }

  @Override
  public List<MenuEntry> getEntries() {
    return menuEntries;
  }
}
----

Example screen:
[source,java]
----
public class MyPlugin extends PluginEntryPoint {
  @Override
  public void onPluginLoad() {
    Plugin.get().screen("my-screen", new Screen.EntryPoint() {
      @Override
      public void onLoad(Screen screen) {
        screen.add(new InlineLabel("My Screen");
        screen.show();
      }
    });
  }
}
----

[[user-settings-screen]]
== Add User Settings Screen

A link:#gwt_ui_extension[GWT plugin] can implement a user settings
screen that is integrated into the Gerrit user settings menu.

Example settings screen:
[source,java]
----
public class MyPlugin extends PluginEntryPoint {
  @Override
  public void onPluginLoad() {
    Plugin.get().settingsScreen("my-preferences", "My Preferences",
        new Screen.EntryPoint() {
          @Override
          public void onLoad(Screen screen) {
            screen.setPageTitle("Settings");
            screen.add(new InlineLabel("My Preferences"));
            screen.show();
          }
    });
  }
}
----

By defining an link:config-gerrit.html#urlAlias[urlAlias] Gerrit
administrators can map plugin screens into the Gerrit URL namespace or
even replace Gerrit screens by plugin screens.

Plugins may also programatically add URL aliases in the preferences of
of a user. This way certain screens can be replaced for certain users.
E.g. the plugin may offer a user preferences setting for choosing a
screen that then sets/unsets a URL alias for the user.

[[settings-screen]]
== Plugin Settings Screen

If a plugin implements a screen for administrating its settings that is
available under "#/x/<plugin-name>/settings" it is automatically linked
from the plugin list screen.

[[http]]
== HTTP Servlets

Plugins or extensions may register additional HTTP servlets, and
wrap them with HTTP filters.

Servlets may use auto-registration to declare the URL they handle:

[source,java]
----
import com.google.gerrit.extensions.annotations.Export;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Export("/print")
@Singleton
class HelloServlet extends HttpServlet {
  protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    res.setContentType("text/plain");
    res.setCharacterEncoding("UTF-8");
    res.getWriter().write("Hello");
  }
}
----

The auto registration only works for standard servlet mappings like
`/foo` or `+/foo/*+`. Regex style bindings must use a Guice ServletModule
to register the HTTP servlets and declare it explicitly in the manifest
with the `Gerrit-HttpModule` attribute:

[source,java]
----
import com.google.inject.servlet.ServletModule;

class MyWebUrls extends ServletModule {
  protected void configureServlets() {
    serve("/print").with(HelloServlet.class);
  }
}
----

For a plugin installed as name `helloworld`, the servlet implemented
by HelloServlet class will be available to users as:

----
$ curl http://review.example.com/plugins/helloworld/print
----

[[data-directory]]
== Data Directory

Plugins can request a data directory with a `@PluginData` Path (or File,
deprecated) dependency. A data directory will be created automatically
by the server in `$site_path/data/$plugin_name` and passed to the
plugin.

Plugins can use this to store any data they want.

[source,java]
----
@Inject
MyType(@PluginData java.nio.file.Path myDir) {
  this.in = Files.newInputStream(myDir.resolve("my.config"));
}
----

[[secure-store]]
== SecureStore

SecureStore allows to change the way Gerrit stores sensitive data like
passwords.

In order to replace the default SecureStore (no-op) implementation,
a class that extends `com.google.gerrit.server.securestore.SecureStore`
needs to be provided (with dependencies) in a separate jar file. Then
link:pgm-SwitchSecureStore.html[SwitchSecureStore] must be run to
switch implementations.

The SecureStore implementation is instantiated using a Guice injector
which binds the `File` annotated with the `@SitePath` annotation.
This means that a SecureStore implementation class can get access to
the `site_path` like in the following example:

[source,java]
----
@Inject
MySecureStore(@SitePath java.io.File sitePath) {
  // your code
}
----

No Guice bindings or modules are required. Gerrit will automatically
discover and bind the implementation.

[[accountcreation]]
== Account Creation

Plugins can hook into the
link:rest-api-accounts.html#create-account[account creation] REST API and
inject additional external identifiers for an account that represents a user
in some external user store. For that, an implementation of the extension
point `com.google.gerrit.server.api.accounts.AccountExternalIdCreator`
must be registered.

[source,java]
----
class MyExternalIdCreator implements AccountExternalIdCreator {
  @Override
  public List<AccountExternalId> create(Account.Id id, String username,
      String email) {
    // your code
  }
}

bind(AccountExternalIdCreator.class)
  .annotatedWith(UniqueAnnotations.create())
  .to(MyExternalIdCreator.class);
}
----

[[download-commands]]
== Download Commands

Gerrit offers commands for downloading changes and cloning projects
using different download schemes (e.g. for downloading via different
network protocols). Plugins can contribute download schemes, download
commands and clone commands by implementing
`com.google.gerrit.extensions.config.DownloadScheme`,
`com.google.gerrit.extensions.config.DownloadCommand` and
`com.google.gerrit.extensions.config.CloneCommand`.

The download schemes, download commands and clone commands which are
used most often are provided by the Gerrit core plugin
`download-commands`.

[[included-in]]
== Included In

For merged changes the link:user-review-ui.html#included-in[Included In]
drop-down panel shows the branches and tags in which the change is
included.

Plugins can add additional systems in which the change can be included
by implementing `com.google.gerrit.extensions.config.ExternalIncludedIn`,
e.g. a plugin can provide a list of servers on which the change was
deployed.

[[links-to-external-tools]]
== Links To External Tools

Gerrit has extension points that enables development of a
light-weight plugin that links commits to external
tools (GitBlit, CGit, company specific resources etc).

PatchSetWebLinks will appear to the right of the commit-SHA1 in the UI.

[source, java]
----
import com.google.gerrit.extensions.annotations.Listen;
import com.google.gerrit.extensions.webui.PatchSetWebLink;;
import com.google.gerrit.extensions.webui.WebLinkTarget;

@Listen
public class MyWeblinkPlugin implements PatchSetWebLink {

  private String name = "MyLink";
  private String placeHolderUrlProjectCommit = "http://my.tool.com/project=%s/commit=%s";
  private String imageUrl = "http://placehold.it/16x16.gif";

  @Override
  public WebLinkInfo getPatchSetWebLink(String projectName, String commit) {
    return new WebLinkInfo(name,
        imageUrl,
        String.format(placeHolderUrlProjectCommit, project, commit),
        WebLinkTarget.BLANK);
  }
}
----

FileWebLinks will appear in the side-by-side diff screen on the right
side of the patch selection on each side.

DiffWebLinks will appear in the side-by-side and unified diff screen in
the header next to the navigation icons.

ProjectWebLinks will appear in the project list in the
`Repository Browser` column.

BranchWebLinks will appear in the branch list in the last column.

FileHistoryWebLinks will appear on the access rights screen.

[[lfs-extension]]
== LFS Storage Plugins

Gerrit provides an extension point that enables development of
link:https://github.com/github/git-lfs/blob/master/docs/api/v1/http-v1-batch.md[
LFS (Large File Storage)] storage plugins. Gerrit core exposes the default LFS
protocol endpoint `<project-name>/info/lfs/objects/batch` and forwards the requests
to the configured link:config-gerrit.html#lfs[lfs.plugin] plugin which implements
the LFS protocol. By exposing the default LFS endpoint, the git-lfs client can be
used without any configuration.

[source, java]
----
/** Provide an LFS protocol implementation */
import org.eclipse.jgit.lfs.server.LargeFileRepository;
import org.eclipse.jgit.lfs.server.LfsProtocolServlet;

@Singleton
public class LfsApiServlet extends LfsProtocolServlet {
  private static final long serialVersionUID = 1L;

  private final S3LargeFileRepository repository;

  @Inject
  LfsApiServlet(S3LargeFileRepository repository) {
    this.repository = repository;
  }

  @Override
  protected LargeFileRepository getLargeFileRepository() {
    return repository;
  }
}

/** Register the LfsApiServlet to listen on the default LFS protocol endpoint */
import static com.google.gerrit.httpd.plugins.LfsPluginServlet.URL_REGEX;

import com.google.gerrit.httpd.plugins.HttpPluginModule;

public class HttpModule extends HttpPluginModule {

  @Override
  protected void configureServlets() {
    serveRegex(URL_REGEX).with(LfsApiServlet.class);
  }
}

/** Provide an implementation of the LargeFileRepository */
import org.eclipse.jgit.lfs.server.s3.S3Repository;

public class S3LargeFileRepository extends S3Repository {
...
}
----

[[metrics]]
== Metrics

=== Metrics Reporting

To send Gerrit's metrics data to an external reporting backend, a plugin can
get a `MetricRegistry` injected and register an instance of a class that
implements the `Reporter` interface from link:http://metrics.dropwizard.io/[
DropWizard Metrics].

Metric reporting plugin implementations are provided for
link:https://gerrit.googlesource.com/plugins/metrics-reporter-jmx/[JMX],
link:https://gerrit.googlesource.com/plugins/metrics-reporter-elasticsearch/[Elastic Search],
and link:https://gerrit.googlesource.com/plugins/metrics-reporter-graphite/[Graphite].

There is also a working example of reporting metrics to the console in the
link:https://gerrit.googlesource.com/plugins/cookbook-plugin/+/master/src/main/java/com/googlesource/gerrit/plugins/cookbook/ConsoleMetricReporter.jave[
cookbook plugin].

=== Providing own metrics

Plugins may provide metrics to be dispatched to external reporting services by
getting a `MetricMaker` injected and creating instances of specific types of
metric:

* Counter
+
Metric whose value increments during the life of the process.

* Timer
+
Metric recording time spent on an operation.

* Histogram
+
Metric recording statistical distribution (rate) of values.

Plugin metrics are recorded under `plugins/${plugin-name}/${metric-name}`.

See the replication metrics in the
link:https://gerrit.googlesource.com/plugins/replication/+/master/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationMetrics.java[
replication plugin] for an example of usage.

[[account-patch-review-store]]
== AccountPatchReviewStore

The AccountPatchReviewStore is used to store reviewed flags on changes.
A reviewed flag is a tuple of (patch set ID, file, account ID) and
records whether the user has reviewed a file in a patch set. Each user
can easily have thousands of reviewed flags and the number of reviewed
flags is growing without bound. The store must be able handle this data
volume efficiently.

Gerrit implements this extension point, but plugins may bind another
implementation, e.g. one that supports multi-master.

----
DynamicItem.bind(binder(), AccountPatchReviewStore.class)
    .to(MultiMasterAccountPatchReviewStore.class);

...

public class MultiMasterAccountPatchReviewStore
    implements AccountPatchReviewStore {
  ...
}
----


[[documentation]]
== Documentation

If a plugin does not register a filter or servlet to handle URLs
`+/Documentation/*+` or `+/static/*+`, the core Gerrit server will
automatically export these resources over HTTP from the plugin JAR.

Static resources under the `static/` directory in the JAR will be
available as `/plugins/helloworld/static/resource`. This prefix is
configurable by setting the `Gerrit-HttpStaticPrefix` attribute.

Documentation files under the `Documentation/` directory in the JAR
will be available as `/plugins/helloworld/Documentation/resource`. This
prefix is configurable by setting the `Gerrit-HttpDocumentationPrefix`
attribute.

Documentation may be written in the Markdown flavor
link:https://github.com/sirthias/pegdown[pegdown]
if the file name ends with `.md`. Gerrit will automatically convert
Markdown to HTML if accessed with extension `.html`.

[[macros]]
Within the Markdown documentation files macros can be used that allow
to write documentation with reasonably accurate examples that adjust
automatically based on the installation.

The following macros are supported:

[width="40%",options="header"]
|===================================================
|Macro       | Replacement
|@PLUGIN@    | name of the plugin
|@URL@       | Gerrit Web URL
|@SSH_HOST@  | SSH Host
|@SSH_PORT@  | SSH Port
|===================================================

The macros will be replaced when the documentation files are rendered
from Markdown to HTML.

Macros that start with `\` such as `\@KEEP@` will render as `@KEEP@`
even if there is an expansion for `KEEP` in the future.

[[auto-index]]
=== Automatic Index

If a plugin does not handle its `/` URL itself, Gerrit will
redirect clients to the plugin's `/Documentation/index.html`.
Requests for `/Documentation/` (bare directory) will also redirect
to `/Documentation/index.html`.

If neither resource `Documentation/index.html` or
`Documentation/index.md` exists in the plugin JAR, Gerrit will
automatically generate an index page for the plugin's documentation
tree by scanning every `*.md` and `*.html` file in the Documentation/
directory.

For any discovered Markdown (`*.md`) file, Gerrit will parse the
header of the file and extract the first level one title. This
title text will be used as display text for a link to the HTML
version of the page.

For any discovered HTML (`*.html`) file, Gerrit will use the name
of the file, minus the `*.html` extension, as the link text. Any
hyphens in the file name will be replaced with spaces.

If a discovered file is named `about.md` or `about.html`, its
content will be inserted in an 'About' section at the top of the
auto-generated index page.  If both `about.md` and `about.html`
exist, only the first discovered file will be used.

If a discovered file name beings with `cmd-` it will be clustered
into a 'Commands' section of the generated index page.

If a discovered file name beings with `servlet-` it will be clustered
into a 'Servlets' section of the generated index page.

If a discovered file name beings with `rest-api-` it will be clustered
into a 'REST APIs' section of the generated index page.

All other files are clustered under a 'Documentation' section.

Some optional information from the manifest is extracted and
displayed as part of the index page, if present in the manifest:

[width="40%",options="header"]
|===================================================
|Field       | Source Attribute
|Name        | Implementation-Title
|Vendor      | Implementation-Vendor
|Version     | Implementation-Version
|URL         | Implementation-URL
|API Version | Gerrit-ApiVersion
|===================================================

[[deployment]]
== Deployment

Compiled plugins and extensions can be deployed to a running Gerrit
server using the link:cmd-plugin-install.html[plugin install] command.

Web UI plugins distributed as  single `.js` file can be deployed
without the overhead of JAR packaging, for more information refer to
link:cmd-plugin-install.html[plugin install] command.

Plugins can also be copied directly into the server's
directory at `$site_path/plugins/$name.(jar|js)`.  The name of
the JAR file, minus the `.jar` or `.js` extension, will be used as the
plugin name. Unless disabled, servers periodically scan this
directory for updated plugins. The time can be adjusted by
link:config-gerrit.html#plugins.checkFrequency[plugins.checkFrequency].

For disabling plugins the link:cmd-plugin-remove.html[plugin remove]
command can be used.

Disabled plugins can be re-enabled using the
link:cmd-plugin-enable.html[plugin enable] command.

== Known issues and bugs

=== Error handling in UI when using the REST API

When a plugin invokes a REST endpoint in the UI, it provides an
`AsyncCallback` to handle the result. At the moment the
`onFailure(Throwable)` of the callback is never invoked, even if there
is an error. Errors are always handled by the Gerrit core UI which
shows the error dialog. This means currently plugins cannot do any
error handling and e.g. ignore expected errors.

In the following example the REST endpoint would return '404 Not Found'
if there is no HTTP password and the Gerrit core UI would display an
error dialog for this. However having no HTTP password is not an error
and the plugin may like to handle this case.

[source,java]
----
new RestApi("accounts").id("self").view("password.http")
    .get(new AsyncCallback<NativeString>() {

  @Override
  public void onSuccess(NativeString httpPassword) {
    // TODO
  }

  @Override
  public void onFailure(Throwable caught) {
    // never invoked
  }
});
----


[[reviewer-suggestion]]
== Reviewer Suggestion Plugins

Gerrit provides an extension point that enables Plugins to rank
the list of reviewer suggestion a user receives upon clicking "Add Reviewer" on
the change screen.
Gerrit supports both a default suggestion that appears when the user has not yet
typed anything and a filtered suggestion that is shown as the user starts
typing.
Plugins receive a candidate list and can return a Set of suggested reviewers
containing the Account.Id and a score for each reviewer.
The candidate list is non-binding and plugins can choose to return reviewers not
initially contained in the candidate list.
Server administrators can configure the overall weight of each plugin using the
weight config parameter on [addreviewer "<pluginName-exportName>"].

[source, java]
----
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.annotations.ExtensionPoint;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;

import java.util.Set;

public class MyPlugin implements ReviewerSuggestion {
  public Set<SuggestedReviewer> suggestReviewers(Project.NameKey project,
      @Nullable Change.Id changeId, @Nullable String query,
      Set<Account.Id> candidates) {
    Set<SuggestedReviewer> suggestions = new HashSet<>();
    // Implement your ranking logic here
    return suggestions;
  }
}
----


== SEE ALSO

* link:js-api.html[JavaScript API]
* link:dev-rest-api.html[REST API Developers' Notes]

GERRIT
------
Part of link:index.html[Gerrit Code Review]

SEARCHBOX
---------
