/*
* Copyright (c) 2011 Michigan State University - Facility for Rare Isotope Beams
*/
package edu.msu.nscl.olog;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataParam;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.io.IOUtils;
/**
* Top level Jersey HTTP methods for the .../attachments URL
*
* @author Eric Berryman
*/
@Path("/attachments/")
public class AttachmentsResource {
@Context
private UriInfo uriInfo;
@Context
private SecurityContext securityContext;
private Logger audit = Logger.getLogger(this.getClass().getPackage().getName() + ".audit");
private Logger log = Logger.getLogger(this.getClass().getName());
/** Creates a new instance of AttachmentsResource */
public AttachmentsResource() {
}
/**
* GET method for retrieving attachments identified by <tt>id</tt>.
*
* @param logId log id
* @return HTTP Response
*/
@GET
@Path("{logId}")
@Produces({"application/xml", "application/json"})
public Response read(@PathParam("logId") Long logId) throws UnsupportedEncodingException, NoSuchAlgorithmException {
OlogImpl cm = OlogImpl.getInstance();
String user = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : "";
XmlAttachments result;
try {
result = cm.findAttachmentsById(logId);
Response r = Response.ok(result).build();
audit.fine(user + "|" + uriInfo.getPath() + "|GET|OK|" + r.getStatus());
return r;
} catch (OlogException e) {
log.warning(user + "|" + uriInfo.getPath() + "|GET|ERROR|"
+ e.getResponseStatusCode() + "|cause=" + e);
return e.toResponse();
}
}
/**
* GET method for retrieving the list of attachments for a given log.
*
* @return
*/
@GET
@Path("{logId}/{fileName}")
public Response getFile(@PathParam("logId") Long logId, @PathParam("fileName") String fileName ) {
OlogImpl cm = OlogImpl.getInstance();
String user = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : "";
Attachment result;
try {
String filePath = logId.toString();
result = cm.getAttachment(filePath, fileName);
Response r;
if (result == null) {
r = Response.status(Response.Status.NOT_FOUND).build();
} else {
r = Response.ok((Object)result.getContent()).type(result.getMimeType()).build();
}
audit.info( user+"|" + uriInfo.getPath() + "|GET|OK|" + r.getStatus());
return r;
} catch (OlogException e) {
log.warning(user + "|" + uriInfo.getPath() + "|GET|ERROR|" + e.getResponseStatusCode() + "|cause=" + e);
return e.toResponse();
}
}
/**
* GET method for retrieving the list of attachments for a given log.
*
* @return
*/
@GET
@Path("{logId}/{fileName}:thumbnail")
public Response getThumbnail(@PathParam("logId") Long logId, @PathParam("fileName") String fileName ) {
OlogImpl cm = OlogImpl.getInstance();
String user = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : "";
Attachment result;
try {
String filePath = "thumbnails/"+logId.toString();
result = cm.getAttachment(filePath, fileName);
Response r;
if (result == null) {
r = Response.status(Response.Status.NOT_FOUND).build();
} else {
r = Response.ok((Object)result.getContent()).type(result.getMimeType()).build();
}
audit.info( user+"|" + uriInfo.getPath() + "|GET|OK|" + r.getStatus());
return r;
} catch (OlogException e) {
log.warning(user + "|" + uriInfo.getPath() + "|GET|ERROR|" + e.getResponseStatusCode() + "|cause=" + e);
return e.toResponse();
}
}
/**
* POST method for adding a new Attachment to a log entry.
*
* @param Long logId the id of the log entry that the property is being added to
* @param data the MULTIPART_FORM_DATA containing attachment and values to be added to be associated with the log entry
* @return
*/
@POST
@Path("{logId}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response addAttachment(@Context HttpServletRequest req,
@Context HttpHeaders headers,
@PathParam("logId") Long logId,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition disposition,
@FormDataParam("file") FormDataBodyPart body) throws UnsupportedEncodingException, NoSuchAlgorithmException {
OlogImpl cm = OlogImpl.getInstance();
UserManager um = UserManager.getInstance();
um.setUser(securityContext.getUserPrincipal(), securityContext.isUserInRole("Administrator"));
um.setHostAddress(req.getHeader("X-Forwarded-For") == null ? req.getRemoteAddr() : req.getHeader("X-Forwarded-For"));
Attachment attachment = new Attachment();
XmlAttachment result;
try {
if (!um.userHasAdminRole()) {
cm.checkUserBelongsToGroupOfLog(um.getUserName(), logId);
}
//TODO: Check PathParam fileName?
attachment.setFileName(disposition.getFileName());
attachment.setMimeType(body.getMediaType().toString());
attachment.setContent(uploadedInputStream);
attachment.setFileSize(disposition.getSize());
attachment.setEncoding(nonNull(body.getHeaders().getFirst("Content-Transfer-Encoding")));
result = cm.createAttachment(attachment, logId);
Response r = Response.ok(result).build();
audit.fine(um.getUserName() + "|" + uriInfo.getPath() + "|POST|OK|" + r.getStatus());
return r;
} catch (OlogException e) {
log.warning(um.getUserName() + "|" + uriInfo.getPath() + "|POST|ERROR|"
+ e.getResponseStatusCode() + "|cause=" + e);
return e.toResponse();
}
}
/**
* PUT method for adding a new Attachment to a log entry.
*
* @param String fileName the fileName of the file being added
* @param Long logId the id of the log entry that the property is being added to
* @param data the MULTIPART_FORM_DATA containing attachment and values to be added to be associated with the log entry
* @return
*/
@PUT
@Path("{logId}/{fileName}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response addReplaceAttachment(@Context HttpServletRequest req,
@Context HttpHeaders headers,
@PathParam("fileName") String fileName,
@PathParam("logId") Long logId,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition disposition,
@FormDataParam("file") FormDataBodyPart body) throws UnsupportedEncodingException, NoSuchAlgorithmException {
OlogImpl cm = OlogImpl.getInstance();
UserManager um = UserManager.getInstance();
um.setUser(securityContext.getUserPrincipal(), securityContext.isUserInRole("Administrator"));
um.setHostAddress(req.getHeader("X-Forwarded-For") == null ? req.getRemoteAddr() : req.getHeader("X-Forwarded-For"));
Attachment attachment = new Attachment();
try {
if (!um.userHasAdminRole()) {
cm.checkUserBelongsToGroupOfLog(um.getUserName(), logId);
}
//TODO: Check PathParam fileName?
attachment.setFileName(disposition.getFileName());
attachment.setMimeType(body.getMediaType().toString());
attachment.setContent(uploadedInputStream);
attachment.setFileSize(disposition.getSize());
attachment.setEncoding(nonNull(body.getHeaders().getFirst("Content-Transfer-Encoding")));
//TODO: Should be destructive (replace)
//cm.removeExistingAttachment(fileName,logId);
cm.createAttachment(attachment, logId);
String output = "File uploaded to : " + logId.toString()+"/"+disposition.getFileName();
Response r = Response.status(200).entity(output).build();
audit.info(um.getUserName() + "|" + uriInfo.getPath() + "|PUT|OK|" + r.getStatus() + " | " + output);
return r;
} catch (OlogException e) {
log.warning(um.getUserName() + "|" + uriInfo.getPath() + "|PUT|ERROR|"
+ e.getResponseStatusCode() + "|cause=" + e);
return e.toResponse();
}
}
/**
* DELETE method for removing an attachment from a log entry.
*
* @param String attachment being deleted
* @param Long logId the id of the log entry that the property is being added to
* @return
*/
@DELETE
@Path("{logId}/{fileName}")
public Response removeAttachment(@Context HttpServletRequest req,
@Context HttpHeaders headers,
@PathParam("fileName") String fileName,
@PathParam("logId") Long logId) throws UnsupportedEncodingException, NoSuchAlgorithmException {
UserManager um = UserManager.getInstance();
OlogImpl cm = OlogImpl.getInstance();
um.setUser(securityContext.getUserPrincipal(), securityContext.isUserInRole("Administrator"));
try {
if (!um.userHasAdminRole()) {
cm.checkUserBelongsToGroupOfLog(um.getUserName(), logId);
cm.checkUserBelongsToGroup(um.getUserName(), cm.findLogById(logId));
}
cm.removeAttachment(fileName,logId);
Response r = Response.ok().build();
audit.info(um.getUserName() + "|" + uriInfo.getPath() + "|DELETE|OK|" + r.getStatus());
return r;
} catch (OlogException e) {
log.warning(um.getUserName() + "|" + uriInfo.getPath() + "|DELETE|ERROR|" + e.getResponseStatusCode()
+ "|cause=" + e);
return e.toResponse();
}
}
/**
* Return a not null string.
*
* @param s String
* @return empty string if it is null otherwise the string passed in as
* parameter.
*/
private static String nonNull(String s) {
if (s == null) {
return "";
}
return s;
}
}