From 34e3ac54789685b01dd5131d5a1449046691b0b8 Mon Sep 17 00:00:00 2001 From: jendib Date: Sun, 23 Feb 2014 14:09:41 +0100 Subject: [PATCH] Download all files from a document as ZIP --- .../com/sismics/util/mime/MimeTypeUtil.java | 25 +++++++ docs-parent/TODO | 1 - .../docs/rest/resource/FileResource.java | 73 +++++++++++++++++++ .../src/partial/docs/document.view.html | 8 +- .../main/webapp/src/partial/share/share.html | 7 +- .../sismics/docs/rest/TestFileResource.java | 10 +++ 6 files changed, 121 insertions(+), 3 deletions(-) diff --git a/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java b/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java index e9e8cd00..76c49ba1 100644 --- a/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java +++ b/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java @@ -56,4 +56,29 @@ public class MimeTypeUtil { return null; } + + /** + * Get a file extension linked to a MIME type. + * + * @param mimeType MIME type + * @return File extension + */ + public static String getFileExtension(String mimeType) { + switch (mimeType) { + case MimeType.APPLICATION_ZIP: + return "zip"; + case MimeType.IMAGE_GIF: + return "gif"; + case MimeType.IMAGE_JPEG: + return "jpg"; + case MimeType.IMAGE_PNG: + return "png"; + case MimeType.IMAGE_X_ICON: + return "ico"; + case MimeType.APPLICATION_PDF: + return "pdf"; + default: + return null; + } + } } diff --git a/docs-parent/TODO b/docs-parent/TODO index ea021c12..33d0be56 100644 --- a/docs-parent/TODO +++ b/docs-parent/TODO @@ -1,3 +1,2 @@ - Automatic backup system using Quartz (server) - Handle error while uploading a file -- Download all files as zip (docs & share) 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 81ee815e..5ab4bd10 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 @@ -11,6 +11,8 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import javax.persistence.NoResultException; import javax.ws.rs.Consumes; @@ -372,4 +374,75 @@ public class FileResource extends BaseResource { .header("Expires", new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z").format(new Date().getTime() + 3600000 * 24)) .build(); } + + /** + * Returns all files from a document, zipped. + * + * @param documentId Document ID + * @return Response + * @throws JSONException + */ + @GET + @Path("zip") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response zip( + @QueryParam("id") String documentId, + @QueryParam("share") String shareId) throws JSONException { + authenticate(); + + // Get the document + DocumentDao documentDao = new DocumentDao(); + Document document; + try { + document = documentDao.getDocument(documentId); + + // Check document visibility + ShareDao shareDao = new ShareDao(); + if (!shareDao.checkVisibility(document, principal.getId(), shareId)) { + throw new ForbiddenClientException(); + } + } catch (NoResultException e) { + throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", documentId)); + } + + // Get files and user associated with this document + FileDao fileDao = new FileDao(); + UserDao userDao = new UserDao(); + final List fileList = fileDao.getByDocumentId(documentId); + final User user = userDao.getById(document.getUserId()); + + // Create the ZIP stream + StreamingOutput stream = new StreamingOutput() { + @Override + public void write(OutputStream outputStream) throws IOException, WebApplicationException { + try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) { + // Add each file to the ZIP stream + int index = 0; + for (File file : fileList) { + java.io.File storedfile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file.getId()).toFile(); + InputStream fileInputStream = new FileInputStream(storedfile); + + // Add the decrypted file to the ZIP stream + try (InputStream decryptedStream = EncryptionUtil.decryptInputStream(fileInputStream, user.getPrivateKey())) { + ZipEntry zipEntry = new ZipEntry(index + "." + MimeTypeUtil.getFileExtension(file.getMimeType())); + zipOutputStream.putNextEntry(zipEntry); + ByteStreams.copy(decryptedStream, zipOutputStream); + zipOutputStream.closeEntry(); + } catch (Exception e) { + e.printStackTrace(); + throw new WebApplicationException(e); + } + index++; + } + } + outputStream.close(); + } + }; + + // Write to the output + return Response.ok(stream) + .header("Content-Type", "application/zip") + .header("Content-Disposition", "attachment; filename=\"" + document.getTitle().replaceAll("\\W+", "_") + ".zip\"") + .build(); + } } diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.html b/docs-web/src/main/webapp/src/partial/docs/document.view.html index 147165cb..c70d8930 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.view.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.view.html @@ -9,7 +9,13 @@