Merge "Add project UI action to complete a project import"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
index 7cb35ac..81363e7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
@@ -15,12 +15,21 @@
 package com.googlesource.gerrit.plugins.importer;
 
 import com.google.gerrit.extensions.annotations.PluginData;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.CapabilityControl;
+import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
+import com.google.inject.Provider;
 
 import com.googlesource.gerrit.plugins.importer.CompleteProjectImport.Input;
 
@@ -67,4 +76,57 @@
       throw new ResourceConflictException("failed to lock project for delete");
     }
   }
+
+  public static class OnProjects implements
+      RestModifyView<ProjectResource, Input>, UiAction<ProjectResource> {
+    private final ProjectsCollection projectsCollection;
+    private final CompleteProjectImport completeProjectImport;
+    private final Provider<CurrentUser> currentUserProvider;
+    private final String pluginName;
+
+    @Inject
+    public OnProjects(ProjectsCollection projectsCollection,
+        CompleteProjectImport completeProjectImport,
+        Provider<CurrentUser> currentUserProvider,
+        @PluginName String pluginName) {
+      this.projectsCollection = projectsCollection;
+      this.completeProjectImport = completeProjectImport;
+      this.currentUserProvider = currentUserProvider;
+      this.pluginName = pluginName;
+    }
+
+    @Override
+    public Response<?> apply(ProjectResource rsrc, Input input)
+        throws ResourceNotFoundException, ResourceConflictException {
+      ImportProjectResource projectResource =
+          projectsCollection.parse(new ConfigResource(),
+              IdString.fromDecoded(rsrc.getName()));
+      return completeProjectImport.apply(projectResource, input);
+    }
+
+    @Override
+    public UiAction.Description getDescription(ProjectResource rsrc) {
+      UiAction.Description desc = new UiAction.Description()
+          .setLabel("Complete Import...")
+          .setTitle("Complete the project import."
+              + " After completion, resume is not possible anymore.");
+
+      try {
+        projectsCollection.parse(new ConfigResource(),
+            IdString.fromDecoded(rsrc.getName()));
+        desc.setVisible(canCompleteImport(rsrc));
+      } catch (ResourceNotFoundException e) {
+        desc.setVisible(false);
+      }
+
+      return desc;
+    }
+
+    private boolean canCompleteImport(ProjectResource rsrc) {
+      CapabilityControl ctl = currentUserProvider.get().getCapabilities();
+      return ctl.canAdministrateServer()
+          || (ctl.canPerform(pluginName + "-" + ImportCapability.ID)
+              && rsrc.getControl().isOwner());
+    }
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java
index 7a5bdfc..7b6edf0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/HttpModule.java
@@ -29,6 +29,8 @@
         .toInstance(new JavaScriptPlugin("resume-copy-project.js"));
     DynamicSet.bind(binder(), WebUiPlugin.class)
         .toInstance(new JavaScriptPlugin("resume-project-import.js"));
+    DynamicSet.bind(binder(), WebUiPlugin.class)
+        .toInstance(new JavaScriptPlugin("complete-project-import.js"));
 
     DynamicSet.bind(binder(), WebUiPlugin.class)
         .toInstance(new GwtPlugin("importer"));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java b/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
index d703aa8..0a121be 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/Module.java
@@ -52,6 +52,7 @@
         put(PROJECT_KIND, "copy").to(CopyProject.class);
         put(PROJECT_KIND, "copy.resume").to(ResumeCopyProject.class);
         put(PROJECT_KIND, "import.resume").to(ResumeProjectImport.OnProjects.class);
+        post(PROJECT_KIND, "delete").to(CompleteProjectImport.OnProjects.class);
 
         child(CONFIG_KIND, "groups").to(GroupsCollection.class);
       }
diff --git a/src/main/resources/Documentation/rest-api-projects.md b/src/main/resources/Documentation/rest-api-projects.md
index ebc443f..252b33d 100644
--- a/src/main/resources/Documentation/rest-api-projects.md
+++ b/src/main/resources/Documentation/rest-api-projects.md
@@ -73,6 +73,25 @@
   }
 ```
 
+### <a id="complete-project-import"> Complete Project Import
+_POST /projects/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)/@PLUGIN@~delete)_
+
+Mark a project import as completed.
+
+Once a project import is completed it cannot be resumed any more.
+
+#### Request
+
+```
+  POST /projects/myProject/@PLUGIN@~delete HTTP/1.0
+```
+
+#### Response
+
+```
+  HTTP/1.1 204 No Content
+```
+
 
 <a id="json-entities">JSON Entities
 -----------------------------------
diff --git a/src/main/resources/static/complete-project-import.js b/src/main/resources/static/complete-project-import.js
new file mode 100644
index 0000000..059dc46
--- /dev/null
+++ b/src/main/resources/static/complete-project-import.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 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.
+
+Gerrit.install(function(self) {
+    function onCompleteProjectImport(c) {
+      var b = c.button('Complete',
+        {onclick: function(){
+          c.call(
+            {},
+            function(r) {
+              c.hide();
+              window.alert('Import for project "'
+                + c.project
+                + '" was completed."'),
+              Gerrit.go('/admin/projects/' + c.project);
+            });
+        }});
+      c.popup(c.div(
+        c.msg('Complete import for project "'
+          + c.project
+          + '" ?'),
+        c.br(),
+        c.br(),
+        b));
+    }
+    self.onAction('project', 'delete', onCompleteProjectImport);
+  });