Stay on change screen after deleting draft patch set

Change-Id: I47a4dcb0db20c97a31eabafbd5b2db8f397fd4f5
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
index 3744ef0..c9be1d4 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
@@ -44,8 +44,21 @@
   @SignInRequired
   void deleteDraft(PatchLineComment.Key key, AsyncCallback<VoidResult> callback);
 
+  /**
+   * Deletes the specified draft patch set. If the draft patch set is the only
+   * patch set of the change, then also the change gets deleted.
+   *
+   * @param psid ID of the draft patch set that should be deleted
+   * @param callback callback to report the result of the draft patch set
+   *        deletion operation; if the draft patch set was successfully deleted
+   *        {@link AsyncCallback#onSuccess(Object)} is invoked and the change
+   *        details are passed as parameter; if the change gets deleted because
+   *        the draft patch set that was deleted was the only patch set in the
+   *        change, then <code>null</code> is passed as result to
+   *        {@link AsyncCallback#onSuccess(Object)}
+   */
   @SignInRequired
-  void deleteDraftPatchSet(PatchSet.Id psid, AsyncCallback<VoidResult> callback);
+  void deleteDraftPatchSet(PatchSet.Id psid, AsyncCallback<ChangeDetail> callback);
 
   @SignInRequired
   void publishComments(PatchSet.Id psid, String message,
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
index c3606fa..d3c3f76 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
@@ -614,9 +614,13 @@
       public void onClick(final ClickEvent event) {
         b.setEnabled(false);
         PatchUtil.DETAIL_SVC.deleteDraftPatchSet(patchSet.getId(),
-            new GerritCallback<VoidResult>() {
-              public void onSuccess(VoidResult result) {
-                Gerrit.display(PageLinks.MINE);
+            new GerritCallback<ChangeDetail>() {
+              public void onSuccess(final ChangeDetail result) {
+                if (result != null) {
+                  changeScreen.update(result);
+                } else {
+                  Gerrit.display(PageLinks.MINE);
+                }
               }
 
               @Override
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java
index a3809d9..50d6cea 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.httpd.rpc.patch;
 
+import com.google.gerrit.common.data.ChangeDetail;
 import com.google.gerrit.common.data.ReviewerResult;
 import com.google.gerrit.common.data.ReviewResult;
 import com.google.gerrit.common.data.ApprovalSummary;
@@ -24,6 +25,7 @@
 import com.google.gerrit.common.errors.NoSuchEntityException;
 import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
 import com.google.gerrit.httpd.rpc.Handler;
+import com.google.gerrit.httpd.rpc.changedetail.ChangeDetailFactory;
 import com.google.gerrit.reviewdb.Account;
 import com.google.gerrit.reviewdb.AccountDiffPreference;
 import com.google.gerrit.reviewdb.AccountPatchReview;
@@ -43,6 +45,7 @@
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.ReplicationQueue;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
+import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
 import com.google.gerrit.server.patch.PublishComments;
 import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.NoSuchChangeException;
@@ -75,6 +78,7 @@
   private final PatchSetInfoFactory patchSetInfoFactory;
   private final GitRepositoryManager gitManager;
   private final ReplicationQueue replication;
+  private final ChangeDetailFactory.Factory changeDetailFactory;
 
   @Inject
   PatchDetailServiceImpl(final Provider<ReviewDb> schema,
@@ -91,7 +95,8 @@
       final SaveDraft.Factory saveDraftFactory,
       final PatchSetInfoFactory patchSetInfoFactory,
       final GitRepositoryManager gitManager,
-      final ReplicationQueue replication) {
+      final ReplicationQueue replication,
+      final ChangeDetailFactory.Factory changeDetailFactory) {
     super(schema, currentUser);
     this.approvalTypes = approvalTypes;
 
@@ -107,6 +112,7 @@
     this.patchSetInfoFactory = patchSetInfoFactory;
     this.gitManager = gitManager;
     this.replication = replication;
+    this.changeDetailFactory = changeDetailFactory;
   }
 
   public void patchScript(final Patch.Key patchKey, final PatchSet.Id psa,
@@ -152,19 +158,28 @@
   }
 
   public void deleteDraftPatchSet(final PatchSet.Id psid,
-      final AsyncCallback<VoidResult> callback) {
-    run(callback, new Action<VoidResult>() {
-      public VoidResult run(ReviewDb db) throws OrmException, Failure {
+      final AsyncCallback<ChangeDetail> callback) {
+    run(callback, new Action<ChangeDetail>() {
+      public ChangeDetail run(ReviewDb db) throws OrmException, Failure {
         ReviewResult result = null;
         try {
           result = deleteDraftPatchSetFactory.create(psid).call();
+          if (result.getErrors().size() > 0) {
+            throw new Failure(new NoSuchEntityException());
+          }
+          if (result.getChangeId() == null) {
+            // the change was deleted because the draft patch set that was
+            // deleted was the only patch set in the change
+            return null;
+          }
+          return changeDetailFactory.create(result.getChangeId()).call();
         } catch (NoSuchChangeException e) {
           throw new Failure(new NoSuchChangeException(result.getChangeId()));
+        } catch (NoSuchEntityException e) {
+          throw new Failure(e);
+        } catch (PatchSetInfoNotAvailableException e) {
+          throw new Failure(e);
         }
-        if (result.getErrors().size() > 0) {
-          throw new Failure(new NoSuchEntityException());
-        }
-        return VoidResult.INSTANCE;
       }
     });
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java
index f36fcc0..761b765 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java
@@ -98,6 +98,7 @@
     if (restOfPatches.size() == 0) {
       try {
         ChangeUtil.deleteDraftChange(patchSetId, gitManager, replication, db);
+        result.setChangeId(null);
       } catch (IOException e) {
         result.addError(new ReviewResult.Error(
             ReviewResult.Error.Type.GIT_ERROR, e.getMessage()));