DocumentFileRestEndPoint.java
/*
* The coLAB project
* Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.rest.document;
import ch.colabproject.colab.api.controller.document.FileManager;
import ch.colabproject.colab.generator.model.annotations.AuthenticationRequired;
import ch.colabproject.colab.generator.model.exceptions.HttpErrorMessage;
import ch.colabproject.colab.generator.model.exceptions.MessageI18nKey;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* EndPoint to managed hosted files
*
* @author xaviergood
*/
@Path("files")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@AuthenticationRequired
public class DocumentFileRestEndPoint {
/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(DocumentFileRestEndPoint.class);
/**
* File manager
*/
@Inject
private FileManager fileManager;
/**
* Overwrites existing file if any
*
* @param docId document id
* @param fileSize the file size in bytes
* @param file the file bytes
* @param bodypart file meta data
*/
@PUT
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void updateFile(
@FormDataParam("documentId") Long docId,
@FormDataParam("fileSize") Long fileSize,
@FormDataParam("file") InputStream file,
@FormDataParam("file") FormDataBodyPart bodypart
) {
try {
fileManager.updateOrCreateFile(docId, fileSize, file, bodypart);
} catch (RepositoryException ex) {
logger.debug("Could not update file with id {} : {}", docId, ex);
throw HttpErrorMessage.internalServerError();
}
}
/**
* Deletes the file associated with the document Does nothing if no file was present
*
* @param documentId document id
*/
@DELETE
@Path("DeleteFile/{documentId: [0-9]+}")
public void deleteFile(
@PathParam("documentId") Long documentId) {
try {
fileManager.deleteFile(documentId);
} catch (RepositoryException ex) {
logger.debug("Could not delete file with id {} : {}", documentId, ex);
throw HttpErrorMessage.internalServerError();
}
}
/**
* Get the file's content and meta data
*
* @param documentId document id
*
* @return file content, if no file has been set, return an empty stream (0 bytes)
*/
@GET
@Path("GetFile/{documentId: [0-9]+}")
public Response getFileContent(@PathParam("documentId") Long documentId) {
try {
ImmutableTriple<BufferedInputStream, String, MediaType> filedata;
filedata = fileManager.getDownloadFileInfo(documentId);
InputStream fileStream = filedata.left;
String filename = filedata.middle;
MediaType mimeType = filedata.right;
Response.ResponseBuilder response = Response.ok(fileStream, mimeType);
// set file name for browser download prompt
var attachment = "attachment; filename=" + filename;
response.header("Content-Disposition", attachment);
logger.debug("Generated response for file : {}, mime {}", filename, mimeType);
return response.build();
} catch (PathNotFoundException pnfe) {
throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
} catch (RepositoryException ex) {
logger.debug("Could not get file content {}", ex);
throw HttpErrorMessage.internalServerError();
}
}
/**
* Retrieves a project's disk space file usage and the maximum authorized quota
*
* @param projectId project id
*
* @return a list of 2 elements, first is usage second is maximum quota expressed in bytes
*/
@GET
@Path("GetProjectQuotaUsage/{projectId: [0-9]+}")
public List<Long> getQuotaUsage(@PathParam("projectId") Long projectId) {
try {
var result = new ArrayList<Long>();
result.add(fileManager.getUsage(projectId));
result.add(FileManager.getQuota());
return result;
} catch (RepositoryException re) {
logger.debug("Could not get project quota usage {}", re);
throw HttpErrorMessage.internalServerError();
}
}
}