diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/FileDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/FileDao.java index a35a03e4..473511c9 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/FileDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/FileDao.java @@ -190,4 +190,18 @@ public class FileDao { q.setParameter("documentId", documentId); return q.getResultList(); } + + /** + * Get all files from a version. + * + * @param versionId Version ID + * @return List of files + */ + @SuppressWarnings("unchecked") + public List getByVersionId(String versionId) { + EntityManager em = ThreadLocalContext.get().getEntityManager(); + Query q = em.createQuery("select f from File f where f.versionId = :versionId and f.deleteDate is null order by f.order asc"); + q.setParameter("versionId", versionId); + return q.getResultList(); + } } diff --git a/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java b/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java index 98dbeca0..49357e33 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java +++ b/docs-core/src/main/java/com/sismics/docs/core/util/FileUtil.java @@ -160,10 +160,13 @@ public class FileUtil { previousFile.setVersionId(UUID.randomUUID().toString()); } - previousFile.setLatestVersion(false); + // Copy the previous file metadata + file.setOrder(previousFile.getOrder()); file.setVersionId(previousFile.getVersionId()); file.setVersion(previousFile.getVersion() + 1); + // Update the previous file + previousFile.setLatestVersion(false); fileDao.update(previousFile); } } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java index 02195329..21d7cb3e 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java @@ -392,10 +392,10 @@ public class FileResource extends BaseResource { * @apiParam {String} share Share ID * @apiSuccess {Object[]} files List of files * @apiSuccess {String} files.id ID - * @apiSuccess {String} files.mimetype MIME type + * @apiSuccess {String} files.processing True if the file is currently processing * @apiSuccess {String} files.name File name * @apiSuccess {String} files.version Zero-based version number - * @apiSuccess {String} files.processing True if the file is currently processing + * @apiSuccess {String} files.mimetype MIME type * @apiSuccess {String} files.document_id Document ID * @apiSuccess {String} files.create_date Create date (timestamp) * @apiSuccess {String} files.size File size (in bytes) @@ -450,6 +450,57 @@ public class FileResource extends BaseResource { .add("files", files); return Response.ok().entity(response.build()).build(); } + + /** + * List all versions of a file. + * + * @api {get} /file/id/versions Get versions of a file + * @apiName GetFileVersions + * @apiGroup File + * @apiParam {String} id File ID + * @apiSuccess {Object[]} files List of files + * @apiSuccess {String} files.id ID + * @apiSuccess {String} files.name File name + * @apiSuccess {String} files.version Zero-based version number + * @apiSuccess {String} files.mimetype MIME type + * @apiSuccess {String} files.create_date Create date (timestamp) + * @apiError (client) ForbiddenError Access denied + * @apiError (client) NotFound File not found + * @apiPermission user + * @apiVersion 1.5.0 + * + * @param id File ID + * @return Response + */ + @GET + @Path("{id: [a-z0-9\\-]+}/versions") + public Response versions(@PathParam("id") String id) { + if (!authenticate()) { + throw new ForbiddenClientException(); + } + + // Get versions + File file = findFile(id, null); + FileDao fileDao = new FileDao(); + List fileList = Lists.newArrayList(file); + if (file.getVersionId() != null) { + fileList = fileDao.getByVersionId(file.getVersionId()); + } + + JsonArrayBuilder files = Json.createArrayBuilder(); + for (File fileDb : fileList) { + files.add(Json.createObjectBuilder() + .add("id", fileDb.getId()) + .add("name", JsonUtil.nullable(fileDb.getName())) + .add("version", fileDb.getVersion()) + .add("mimetype", fileDb.getMimeType()) + .add("create_date", fileDb.getCreateDate().getTime())); + } + + JsonObjectBuilder response = Json.createObjectBuilder() + .add("files", files); + return Response.ok().entity(response.build()).build(); + } /** * Deletes a file. diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java index 278f1bb6..126252bf 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestFileResource.java @@ -140,6 +140,7 @@ public class TestFileResource extends BaseJerseyTest { Assert.assertEquals(2, files.size()); Assert.assertEquals(file1Id, files.getJsonObject(0).getString("id")); Assert.assertEquals("PIA00452.jpg", files.getJsonObject(0).getString("name")); + Assert.assertEquals("image/jpeg", files.getJsonObject(0).getString("mimetype")); Assert.assertEquals(0, files.getJsonObject(0).getInt("version")); Assert.assertEquals(163510L, files.getJsonObject(0).getJsonNumber("size").longValue()); Assert.assertEquals(file2Id, files.getJsonObject(1).getString("id")); @@ -228,6 +229,19 @@ public class TestFileResource extends BaseJerseyTest { .cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token) .post(Entity.form(new Form()), JsonObject.class); + // Get all versions from a file + json = target().path("/file/" + file2Id + "/versions") + .request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token) + .get(JsonObject.class); + files = json.getJsonArray("files"); + Assert.assertEquals(1, files.size()); + JsonObject file = files.getJsonObject(0); + Assert.assertEquals(file2Id, file.getString("id")); + Assert.assertEquals("PIA00452.jpg", file.getString("name")); + Assert.assertEquals("image/jpeg", file.getString("mimetype")); + Assert.assertEquals(0, file.getInt("version")); + // Add a new version to a file String file3Id; try (InputStream is0 = Resources.getResource("file/document.txt").openStream()) { @@ -248,6 +262,25 @@ public class TestFileResource extends BaseJerseyTest { } } + // Get all versions from a file + json = target().path("/file/" + file2Id + "/versions") + .request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token) + .get(JsonObject.class); + files = json.getJsonArray("files"); + Assert.assertEquals(2, files.size()); + file = files.getJsonObject(1); + Assert.assertEquals(file3Id, file.getString("id")); + Assert.assertEquals("document.txt", file.getString("name")); + Assert.assertEquals("text/plain", file.getString("mimetype")); + Assert.assertEquals(1, file.getInt("version")); + + // Delete the previous version + json = target().path("/file/" + file2Id).request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token) + .delete(JsonObject.class); + Assert.assertEquals("ok", json.getString("status")); + // Check the newly created version json = target().path("/file/list") .queryParam("id", document1Id)