diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt index db358f3bbf..55511bd20c 100644 --- a/Documentation/rest-api-changes.txt +++ b/Documentation/rest-api-changes.txt @@ -1369,6 +1369,29 @@ specified file was deleted in the change edit "`204 No Content`" is returned. RnJvbSA3ZGFkY2MxNTNmZGVhMTdhYTg0ZmYzMmE2ZTI0NWRiYjY... ---- +[[get-edit-file-mime-type]] +=== Retrieve file content MIME type from Change Edit +-- +'GET /changes/link:#change-id[\{change-id\}]/edit/path%2fto%2ffile/type +-- + +Retrieves content MIME type of a file from a change edit. + +.Request +---- + GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/edit/foo%2fbar%2fbaz%2fqux.txt/type HTTP/1.0 +---- + +.Response +---- + HTTP/1.1 200 OK + Content-Disposition: attachment + Content-Type: application/json;charset=UTF-8 + + )]}' + "text/plain" +---- + [[get-edit-message]] === Retrieve commit message from Change Edit or current patch set of the change -- diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java index ad4d50f86c..e84d292282 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java @@ -484,6 +484,18 @@ public class ChangeEditIT extends AbstractDaemonTest { .isEqualTo(StringUtils.newStringUtf8(CONTENT_NEW2)); } + @Test + public void getFileContentTypeRest() throws Exception { + Put.Input in = new Put.Input(); + in.content = RestSession.newRawInput(CONTENT_NEW); + assertThat(adminSession.putRaw(urlEditFile(), in.content).getStatusCode()) + .isEqualTo(SC_NO_CONTENT); + RestResponse r = adminSession.get(urlEditFileContentType()); + assertThat(r.getStatusCode()).isEqualTo(SC_OK); + String res = newGson().fromJson(r.getReader(), String.class); + assertThat(res).isEqualTo("application/octet-stream"); + } + @Test public void getFileNotFoundRest() throws Exception { assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW); @@ -606,6 +618,13 @@ public class ChangeEditIT extends AbstractDaemonTest { + FILE_NAME; } + private String urlEditFileContentType() { + return urlEdit() + + "/" + + FILE_NAME + + "/type"; + } + private String urlGetFiles() { return urlEdit() + "?list"; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java index 66d7be4374..f3f19a8308 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeEdits.java @@ -516,4 +516,23 @@ public class ChangeEdits implements return BinaryResult.create(m).base64(); } } + + @Singleton + public static class GetType implements RestReadView { + private final FileContentUtil fileContentUtil; + + @Inject + GetType(FileContentUtil fileContentUtil) { + this.fileContentUtil = fileContentUtil; + } + + @Override + public String apply(ChangeEditResource rsrc) + throws ResourceNotFoundException, IOException { + return fileContentUtil.getContentType( + rsrc.getChangeEdit().getChange().getProject(), + rsrc.getChangeEdit().getRevision().get(), + rsrc.getPath()); + } + } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/FileContentUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/FileContentUtil.java index 9a817e3f31..5d07402011 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/FileContentUtil.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/FileContentUtil.java @@ -14,14 +14,18 @@ package com.google.gerrit.server.change; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; + import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.server.FileTypeRegistry; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; @@ -33,10 +37,13 @@ import java.io.OutputStream; @Singleton public class FileContentUtil { private final GitRepositoryManager repoManager; + private final FileTypeRegistry registry; @Inject - FileContentUtil(GitRepositoryManager repoManager) { + FileContentUtil(GitRepositoryManager repoManager, + FileTypeRegistry ftr) { this.repoManager = repoManager; + this.registry = ftr; } public BinaryResult getContent(Project.NameKey project, String revstr, @@ -68,4 +75,32 @@ public class FileContentUtil { repo.close(); } } + + public String getContentType(Project.NameKey project, String revstr, + String path) throws ResourceNotFoundException, IOException { + Repository repo = repoManager.openRepository(project); + try { + RevWalk rw = new RevWalk(repo); + ObjectReader reader = repo.newObjectReader(); + try { + RevCommit commit = rw.parseCommit(repo.resolve(revstr)); + TreeWalk tw = + TreeWalk.forPath(rw.getObjectReader(), path, + commit.getTree().getId()); + if (tw == null) { + throw new ResourceNotFoundException(); + } + ObjectLoader blobLoader = reader.open(tw.getObjectId(0), OBJ_BLOB); + byte[] raw = blobLoader.isLarge() + ? null + : blobLoader.getCachedBytes(); + return registry.getMimeType(path, raw).toString(); + } finally { + reader.release(); + rw.release(); + } + } finally { + repo.close(); + } + } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java index d2d3db342e..de318ff1f4 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java @@ -113,6 +113,7 @@ public class Module extends RestApiModule { put(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Put.class); delete(CHANGE_EDIT_KIND).to(ChangeEdits.DeleteContent.class); get(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Get.class); + get(CHANGE_EDIT_KIND, "type").to(ChangeEdits.GetType.class); install(new FactoryModule() { @Override