Make the message configurable

Allow the message to be configured by setting readonly.message in
the readonly.config file in the site's etc folder.

Changes to the configuration require the plugin to be reloaded to
become effective. In a later change we may consider implementing
automatic reload of the configuration.

Change-Id: I1ba284f9d95cd3668d60fb9ecc9fad4294425d9b
diff --git a/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnly.java b/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnly.java
index 1a5a6fc..d9482f1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnly.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/readonly/ReadOnly.java
@@ -14,13 +14,17 @@
 
 package com.googlesource.gerrit.plugins.readonly;
 
+import static com.google.common.base.MoreObjects.firstNonNull;
 import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
 
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.httpd.AllRequestFilter;
+import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.events.CommitReceivedEvent;
 import com.google.gerrit.server.git.validators.CommitValidationException;
 import com.google.gerrit.server.git.validators.CommitValidationListener;
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
+import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
 import java.util.List;
@@ -30,15 +34,26 @@
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jgit.lib.Config;
 
 @Singleton
 class ReadOnly extends AllRequestFilter implements CommitValidationListener {
-  private static final String READ_ONLY_MSG = "Gerrit is under maintenance - all data is READ ONLY";
+  private static final String MESSAGE_KEY = "message";
+  private static final String DEFAULT_MESSAGE =
+      "Gerrit is under maintenance - all data is READ ONLY";
+
+  private final String message;
+
+  @Inject
+  ReadOnly(PluginConfigFactory pluginConfigFactory, @PluginName String pluginName) {
+    Config cfg = pluginConfigFactory.getGlobalPluginConfig(pluginName);
+    this.message = firstNonNull(cfg.getString(pluginName, null, MESSAGE_KEY), DEFAULT_MESSAGE);
+  }
 
   @Override
   public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
       throws CommitValidationException {
-    throw new CommitValidationException(READ_ONLY_MSG);
+    throw new CommitValidationException(message);
   }
 
   @Override
@@ -47,7 +62,7 @@
     if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {
       String method = ((HttpServletRequest) request).getMethod();
       if (method == "POST" || method == "PUT" || method == "DELETE") {
-        ((HttpServletResponse) response).sendError(SC_SERVICE_UNAVAILABLE, READ_ONLY_MSG);
+        ((HttpServletResponse) response).sendError(SC_SERVICE_UNAVAILABLE, message);
         return;
       }
     }
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..883a5c5
--- /dev/null
+++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,21 @@
+@PLUGIN@ Configuration
+======================
+
+The @PLUGIN@ plugin is configured in the `$site_path/etc/@PLUGIN@.config` file:
+
+File '@PLUGIN@.config'
+----------------------
+
+```
+[readonly]
+  message = Gerrit is down for maintenance
+```
+
+If the configuration is modified, the plugin must be reloaded for the changes to
+be effective.
+
+
+```readonly.message```
+:   Message to be shown to clients when attempting to perform an opeation that
+    is blocked due to the server being in read-only mode. When not specified,
+    the default is "Gerrit is under maintenance - all data is READ ONLY".