Provide global configuration to show/hide job panels

The verify result job panels can be hidden or shown by setting the
following parameters in gerrit.config:

[plugin "verify-status"]
   showJobsPanel = true
   showJobsDropDownPanel = false

The default for these parameters is 'true'.

Change-Id: I853be0a0c9bd7b7864c4a3342fa14f01615af0d3
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/GlobalModule.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/GlobalModule.java
index bf00355..4e41127 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/GlobalModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/GlobalModule.java
@@ -16,6 +16,7 @@
 
 import static com.google.inject.Scopes.SINGLETON;
 import static com.google.gerrit.server.change.RevisionResource.REVISION_KIND;
+import static com.google.gerrit.server.config.ConfigResource.CONFIG_KIND;
 
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.restapi.RestApiModule;
@@ -26,6 +27,8 @@
 import com.google.inject.Module;
 import com.google.inject.name.Names;
 
+import com.googlesource.gerrit.plugins.verifystatus.server.PutConfig;
+import com.googlesource.gerrit.plugins.verifystatus.server.GetConfig;
 import com.googlesource.gerrit.plugins.verifystatus.server.GetVerifications;
 import com.googlesource.gerrit.plugins.verifystatus.server.PostVerification;
 import com.googlesource.gerrit.plugins.verifystatus.server.schema.CiDataSourceModule;
@@ -80,6 +83,8 @@
     install(new RestApiModule() {
       @Override
       protected void configure() {
+        get(CONFIG_KIND, "config").to(GetConfig.class);
+        put(CONFIG_KIND, "config").to(PutConfig.class);
         get(REVISION_KIND, "verifications").to(GetVerifications.class);
         post(REVISION_KIND, "verifications").to(PostVerification.class);
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
new file mode 100644
index 0000000..c05a51f
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/ConfigInfo.java
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.verifystatus.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+public class ConfigInfo extends JavaScriptObject {
+  final native boolean showJobsPanel() /*-{ return this.show_jobs_panel ? true : false; }-*/;
+  final native boolean showJobsDropDownPanel() /*-{ return this.show_jobs_drop_down_panel ? true : false; }-*/;
+
+  final native void setShowJobsPanel(boolean s) /*-{ this.show_jobs_panel = s; }-*/;
+  final native void setShowJobsDropDownPanel(boolean s) /*-{ this.show_jobs_drop_down_panel = s; }-*/;
+
+  static ConfigInfo create() {
+    ConfigInfo g = (ConfigInfo) createObject();
+    return g;
+  }
+
+  protected ConfigInfo() {
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
index fb45440..4555328 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
@@ -18,18 +18,36 @@
 import  com.googlesource.gerrit.plugins.verifystatus.client.Resources;
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.PluginEntryPoint;
+import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
 
 public class VerifyStatusPlugin extends PluginEntryPoint {
   public static final Resources RESOURCES = GWT.create(Resources.class);
 
   @Override
   public void onPluginLoad() {
-    Plugin.get().panel(
-        GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS,
-        new JobsDropDownPanel.Factory());
-    Plugin.get().panel(
-        GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
-        new JobsPanel.Factory());
+    new RestApi("config").view("server")
+        .view(Plugin.get().getPluginName(), "config")
+        .get(new AsyncCallback<ConfigInfo>() {
+          @Override
+          public void onSuccess(ConfigInfo info) {
+            if (info.showJobsPanel()) {
+              Plugin.get().panel(
+                  GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
+                  new JobsPanel.Factory());
+            }
+            if (info.showJobsDropDownPanel()) {
+              Plugin.get().panel(
+                  GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS,
+                  new JobsDropDownPanel.Factory());
+            }
+          }
+
+          @Override
+          public void onFailure(Throwable caught) {
+            // never invoked
+          }
+        });
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
new file mode 100644
index 0000000..bca56b7
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetConfig.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.verifystatus.server;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.config.PluginConfig;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.inject.Inject;
+
+public class GetConfig implements RestReadView<ConfigResource> {
+
+  private final PluginConfig cfg;
+
+  @Inject
+  public GetConfig(PluginConfigFactory cfgFactory,
+      @PluginName String pluginName) {
+    this.cfg = cfgFactory.getFromGerritConfig(pluginName);
+  }
+
+  @Override
+  public ConfigInfo apply(ConfigResource resource) {
+    ConfigInfo info = new ConfigInfo();
+    info.showJobsPanel = cfg.getBoolean("showJobsPanel", true);
+    info.showJobsDropDownPanel = cfg.getBoolean("showJobsDropDownPanel", true);
+    return info;
+  }
+
+  public static class ConfigInfo {
+    Boolean showJobsPanel;
+    Boolean showJobsDropDownPanel;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
new file mode 100644
index 0000000..8ca1c4a
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/PutConfig.java
@@ -0,0 +1,85 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.verifystatus.server;
+
+import com.google.gerrit.common.data.GlobalCapability;
+import com.google.gerrit.extensions.annotations.CapabilityScope;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
+import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+
+import com.googlesource.gerrit.plugins.verifystatus.server.PutConfig.Input;
+
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+
+import java.io.IOException;
+
+@RequiresCapability(
+    value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
+public class PutConfig implements RestModifyView<ConfigResource, Input>{
+  public static class Input {
+    public Boolean showJobsPanel;
+    public Boolean showJobsDropDownPanel;
+  }
+
+  private final PluginConfigFactory cfgFactory;
+  private final SitePaths sitePaths;
+  private final String pluginName;
+
+  @Inject
+  PutConfig(PluginConfigFactory cfgFactory,
+      SitePaths sitePaths,
+      @PluginName String pluginName) {
+    this.cfgFactory = cfgFactory;
+    this.sitePaths = sitePaths;
+    this.pluginName = pluginName;
+  }
+
+  @Override
+  public Response<?> apply(ConfigResource rsrc, Input input)
+      throws IOException, ConfigInvalidException, UnprocessableEntityException {
+    if (input == null) {
+      input = new Input();
+    }
+    FileBasedConfig cfg =
+        new FileBasedConfig(sitePaths.gerrit_config.toFile(), FS.DETECTED);
+    cfg.load();
+
+    if (input.showJobsPanel != null) {
+      cfg.setBoolean("plugin", pluginName, "showJobsPanel",
+          input.showJobsPanel);
+    } else {
+      cfg.unset("plugin", pluginName, "showJobsPanel");
+    }
+    if (input.showJobsDropDownPanel != null) {
+      cfg.setBoolean("plugin", pluginName, "showJobsDropDownPanel",
+          input.showJobsDropDownPanel);
+    } else {
+      cfg.unset("plugin", pluginName, "showJobsDropDownPanel");
+    }
+
+    cfg.save();
+    cfgFactory.getFromGerritConfig(pluginName, true);
+    return Response.none();
+  }
+}
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index a51943a..d00afa5 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -49,3 +49,30 @@
 The information icon is an indicator that a job has abstained from voting
 (or is a non-voting job).  Abstaining typically indicates that a job's
 score may not factor into determining the combined vote.
+
+
+### <a id="configure-panels"> @PLUGIN@ configure-panels
+
+Configuration
+-------------
+
+The @PLUGIN@ job panels can be configured in the [gerrit.config]
+(../../../Documentation/config-gerrit.html#_file_code_etc_gerrit_config_code)
+file.
+
+#### Parameters
+
+|Field Name             |Description|
+|:----------------------|:----------|
+|showJobsPanel          | Whether jobs panel should be displayed (default to true)|
+|showJobsDropDownPanel  | Whether jobs drop down panel should be displayed (default to true)|
+
+
+#### Example
+
+```
+[plugin "@PLUGIN@"]
+   showJobsPanel = false
+   showJobsDropDownPanel = false
+```
+
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
new file mode 100644
index 0000000..eaf22e5
--- /dev/null
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -0,0 +1,83 @@
+@PLUGIN@ - /config/ REST API
+============================
+
+This page describes the '/config/' REST endpoints that are added by the
+@PLUGIN@ plugin.
+
+Please also take note of the general information on the
+[REST API](../../../Documentation/rest-api.html).
+
+<a id="project-endpoints"> @PLUGIN@ Endpoints
+--------------------------------------------
+
+### <a id="get-config"> Get Config
+_GET /config/server/@PLUGIN@~config_
+
+Gets the configuration of the @PLUGIN@ plugin.
+
+#### Request
+
+```
+  GET /config/server/@PLUGIN@~config HTTP/1.0
+```
+
+As response a [ConfigInfo](#config-info) entity is returned that
+contains the configuration of the @PLUGIN@ plugin.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json;charset=UTF-8
+
+  )]}'
+  {
+    "show_jobs_panel": true,
+    "show_jobs_drop_down_panel": false
+  }
+```
+
+### <a id="put-config"> Put Config
+_PUT /config/server/@PLUGIN@~config_
+
+Sets the configuration of the @PLUGIN@ plugin.
+
+The new configuration must be specified as a [ConfigInfo](#config-info)
+entity in the request body. Not setting a parameter leaves the
+parameter unchanged.
+
+#### Request
+
+```
+  PUT /config/server/@PLUGIN@~config HTTP/1.0
+  Content-Type: application/json;charset=UTF-8
+
+  {
+    "show_jobs_panel": true,
+    "show_jobs_drop_down_panel": false
+  }
+```
+
+<a id="json-entities">JSON Entities
+-----------------------------------
+
+### <a id="config-info"></a>ConfigInfo
+
+The `ConfigInfo` entity contains the configuration of the @PLUGIN@
+plugin.
+
+|Field Name               |Description|
+|:------------------------|:----------|
+|show_jobs_panel          | Whether jobs panel should be displayed|
+|show_jobs_drop_down_panel| Whether jobs drop down panel should be displayed|
+
+
+SEE ALSO
+--------
+
+* [Config related REST endpoints](../../../Documentation/rest-api-config.html)
+
+GERRIT
+------
+Part of [Gerrit Code Review](../../../Documentation/index.html)