Reuse Gerrit code for head update

To avoid code duplication and to make sure that head update is done
correctly replace pull-replication custom code with the code from Gerrit
core.

Bug: Issue 15396
Change-Id: Ic49b731a8e5394ead3a4d36134db7a38f068718d
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/UpdateHeadAction.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/UpdateHeadAction.java
index 4195435..ae9c072 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/UpdateHeadAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/UpdateHeadAction.java
@@ -14,66 +14,28 @@
 
 package com.googlesource.gerrit.plugins.replication.pull.api;
 
-import com.google.common.base.Strings;
-import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.extensions.api.projects.HeadInput;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 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.restapi.UnprocessableEntityException;
-import com.google.gerrit.server.permissions.PermissionBackend;
-import com.google.gerrit.server.permissions.RefPermission;
 import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.restapi.project.SetHead;
 import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.replication.LocalFS;
-import com.googlesource.gerrit.plugins.replication.pull.GerritConfigOps;
-import java.util.Optional;
-import org.eclipse.jgit.transport.URIish;
 
-@Singleton
 public class UpdateHeadAction implements RestModifyView<ProjectResource, HeadInput> {
-  private final GerritConfigOps gerritConfigOps;
-  private final PermissionBackend permissionBackend;
+
+  private final SetHead setHead;
 
   @Inject
-  UpdateHeadAction(GerritConfigOps gerritConfigOps, PermissionBackend permissionBackend) {
-    this.gerritConfigOps = gerritConfigOps;
-    this.permissionBackend = permissionBackend;
+  public UpdateHeadAction(SetHead setHead) {
+    this.setHead = setHead;
   }
 
   @Override
-  public Response<?> apply(ProjectResource projectResource, HeadInput input)
+  public Response<?> apply(ProjectResource resource, HeadInput input)
       throws AuthException, BadRequestException, ResourceConflictException, Exception {
-    if (input == null || Strings.isNullOrEmpty(input.ref)) {
-      throw new BadRequestException("ref required");
-    }
-    String ref = RefNames.fullName(input.ref);
-
-    permissionBackend
-        .user(projectResource.getUser())
-        .project(projectResource.getNameKey())
-        .ref(ref)
-        .check(RefPermission.SET_HEAD);
-
-    // TODO: the .git suffix should not be added here, but rather it should be
-    //  dealt with by the caller, honouring the naming style from the
-    //  replication.config (Issue 15221)
-    Optional<URIish> maybeRepo =
-        gerritConfigOps.getGitRepositoryURI(String.format("%s.git", projectResource.getName()));
-
-    if (maybeRepo.isPresent()) {
-      if (new LocalFS(maybeRepo.get()).updateHead(projectResource.getNameKey(), ref)) {
-        return Response.ok(ref);
-      }
-      throw new UnprocessableEntityException(
-          String.format(
-              "Could not update HEAD of repo %s to ref %s", projectResource.getName(), ref));
-    }
-    throw new ResourceNotFoundException(
-        String.format("Could not compute URL for repo: %s", projectResource.getName()));
+    return setHead.apply(resource, input);
   }
 }