package controllers;
import static helpers.FileStoreHelper.getNameWithExt;
import static service.filestore.roles.Admin.isAdmin;
import helpers.ExtractionHelper;
import helpers.FileStoreHelper;
import helpers.FileStoreHelper.FileOrFolderException;
import jackrabbit.AorraAccessManager;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.util.Map;
import java.util.SortedSet;
import java.util.TimeZone;
import javax.jcr.AccessDeniedException;
import javax.jcr.ItemExistsException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import models.Flag;
import models.GroupManager;
import models.User;
import models.UserDAO;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.api.security.user.Group;
import org.jcrom.Jcrom;
import org.jcrom.util.PathUtils;
import play.Logger;
import play.api.http.MediaRange;
import play.api.libs.MimeTypes;
import play.libs.F;
import play.libs.Json;
import play.mvc.Http.MultipartFormData;
import play.mvc.Result;
import play.mvc.With;
import providers.CacheableUserProvider;
import service.EventManager.Event;
import service.JcrSessionFactory;
import service.filestore.FileStore;
import service.filestore.FileStore.Folder;
import service.filestore.FileStore.Permission;
import service.filestore.FileStoreImpl;
import service.filestore.FlagStore;
import service.filestore.FlagStore.FlagType;
import service.filestore.JsonBuilder;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.util.ISO8601Utils;
import com.google.inject.Inject;
@With(UncacheableAction.class)
public final class FileStoreController extends SessionAwareController {
private final FileStore fileStoreImpl;
private final FlagStore flagStoreImpl;
@Inject
public FileStoreController(final JcrSessionFactory sessionFactory,
final Jcrom jcrom,
final CacheableUserProvider sessionHandler,
final FileStore fileStoreImpl,
final FlagStore flagStoreImpl) {
super(sessionFactory, jcrom, sessionHandler);
this.fileStoreImpl = fileStoreImpl;
this.flagStoreImpl = flagStoreImpl;
}
@SubjectPresent
public Result index() {
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
final FileStore.Manager fm = fileStoreImpl.getManager(session);
return ok(views.html.FileStoreController.index.render(
fileStoreImpl.getEventManager().getLastEventId(),
jb.toJson(fm.getFolders()),
getUsersJson(session))).as("text/html; charset=utf-8");
}
});
}
@SubjectPresent
public Result mkdir(final String folderId, final String path) {
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
final FileStore.Manager fm = fileStoreImpl.getManager(session);
final FileStoreHelper fh = new FileStoreHelper(session);
try {
final FileStore.Folder baseFolder =
(FileStore.Folder) fm.getByIdentifier(folderId);
final String absPath =
baseFolder.getPath() + "/" + PathUtils.relativePath(path);
final FileStore.Folder newFolder = fh.mkdir(absPath, true);
final ArrayNode json = JsonNodeFactory.instance.arrayNode();
FileStore.Folder f = newFolder;
while (f != null && !f.getIdentifier().equals(folderId)) {
// Shift onto the front, because we need to return in order
// of creation.
json.insert(0, jb.toJsonShallow(f, false));
f = f.getParent();
}
return created(json).as("application/json; charset=utf-8");
} catch (FileOrFolderException e) {
return badRequest(e.getMessage());
}
}
});
}
@SubjectPresent
public Result showFolder(final String folderId) {
for (final MediaRange m : ctx().request().acceptedTypes()) {
if (m.accepts("text/html")) {
return index();
} else if (m.accepts("application/json") || m.accepts("text/javascript")){
return folderJson(folderId);
}
}
return status(UNSUPPORTED_MEDIA_TYPE);
}
@SubjectPresent
public Result showFile(final String fileId) {
for (final MediaRange m : ctx().request().acceptedTypes()) {
if (m.accepts("text/html")) {
return index();
} else if (m.accepts("application/json") || m.accepts("text/javascript")){
return fileJson(fileId);
}
}
return status(UNSUPPORTED_MEDIA_TYPE);
}
@SubjectPresent
public Result filestoreJson() {
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
final FileStore.Manager fm = fileStoreImpl.getManager(session);
return ok(jb.toJson(fm.getFolders()))
.as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result flagsJson(final String flagTypeName) {
final FlagType t = FlagType.valueOf(flagTypeName.toUpperCase());
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
final ArrayNode json = JsonNodeFactory.instance.arrayNode();
for (final Flag flag : flagStoreImpl.getManager(session).getFlags(t)) {
json.add(jb.toJson(flag));
}
return ok(json).as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result flagJson(final String flagTypeName, final String flagId) {
final FlagType t = FlagType.valueOf(flagTypeName.toUpperCase());
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
final Flag flag = flagStoreImpl.getManager(session).getFlag(t, flagId);
if (flag == null) {
return notFound();
}
return ok(jb.toJson(flag)).as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result addFlag(final String flagTypeName) {
final FlagType t = FlagType.valueOf(flagTypeName.toUpperCase());
final JsonNode params = ctx().request().body().asJson();
if (!params.has("targetId") || !params.has("userId"))
return badRequest();
final String targetId = params.get("targetId").asText();
final String userId = params.get("userId").asText();
if (!getUser().getId().equals(userId))
return forbidden();
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final User user = (new UserDAO(session, jcrom)).get(getUser());
final JsonBuilder jb = new JsonBuilder();
final Flag flag = flagStoreImpl.getManager(session)
.setFlag(t, targetId, user);
fileStoreImpl.getEventManager()
.tell(FlagStore.Events.create(flag, t, user));
return created(jb.toJson(flag)).as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result deleteFlag(final String flagTypeName, final String flagId) {
final FlagType t = FlagType.valueOf(flagTypeName.toUpperCase());
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final FlagStore.Manager flm = flagStoreImpl.getManager(session);
final Flag flag = flm.getFlag(t, flagId);
if (flag == null)
return notFound();
flm.unsetFlag(t, flagId);
fileStoreImpl.getEventManager()
.tell(FlagStore.Events.delete(flag, t, getUser()));
return status(204);
}
});
}
protected Result folderJson(final String folderId) {
return folderBasedResult(folderId, new FolderOp() {
@Override
public final Result apply(Session session, FileStore.Folder f)
throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
return ok(jb.toJsonShallow(f, false));
}
});
}
protected Result fileJson(final String fileId) {
return fileBasedResult(fileId, new FileOp() {
@Override
public final Result apply(Session session, FileStore.File f)
throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
return ok(jb.toJsonShallow(f)).as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result modifyFolder(final String folderId) {
return folderBasedResult(folderId, new FolderOp() {
@Override
public final Result apply(Session session, FileStore.Folder f)
throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
try {
return ok(jb.toJsonShallow((FileStore.Folder)modify(session, f), false));
} catch (ItemExistsException e) {
return badRequest(e.getMessage());
}
}
});
}
@SubjectPresent
public Result modifyFile(final String fileId) {
return fileBasedResult(fileId, new FileOp() {
@Override
public final Result apply(Session session, FileStore.File f)
throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
try {
return ok(jb.toJsonShallow((FileStore.File)modify(session, f)));
} catch (ItemExistsException e) {
return badRequest(e.getMessage());
}
}
});
}
private FileStore.FileOrFolder modify(Session session, FileStore.FileOrFolder f) throws RepositoryException {
final FileStore.Manager fm = fileStoreImpl.getManager(session);
String newName = getParamAsString("name");
String newParent = getParamAsString("parent");
if(newName != null && !StringUtils.equals(f.getName(), newName)) {
f.rename(newName);
} else if(newParent != null && !StringUtils.equals(
f.getParent().getIdentifier(), newParent)) {
FileStore.FileOrFolder fof = fm.getByIdentifier(newParent);
if(fof instanceof FileStore.Folder) {
f.move((Folder)fof);
} else {
throw new RuntimeException("new parent is not a folder or null");
}
}
return fm.getByIdentifier(f.getIdentifier());
}
private String getParamAsString(String name) {
final JsonNode params = ctx().request().body().asJson();
return ((params!=null)&&(params.get(name)!=null))?params.get(name).asText():null;
}
@SubjectPresent
public Result delete(final String fileOrFolderId) {
return inUserSession(new F.Function<Session, Result>() {
@Override
public final Result apply(Session session) throws RepositoryException {
final FileStore.Manager fm = fileStoreImpl.getManager(session);
final UserDAO dao = getUserDAO(session);
if (!isAdmin(session, dao, dao.get(getUser())))
return forbidden();
FileStore.FileOrFolder fof = fm.getByIdentifier(fileOrFolderId);
if (fof == null) {
return notFound();
} else {
fof.delete();
return noContent();
}
}
});
}
@SubjectPresent
public Result deleteVersion(final String fileId, final String versionName) {
return versionBasedResult(fileId, versionName, new FileVersionOp() {
@Override
public final Result apply(
final Session session,
final FileStore.File file,
final FileStore.File version)
throws RepositoryException, IOException {
final UserDAO dao = getUserDAO(session);
final User u = dao.get(getUser());
if (!isAdmin(session, dao, u) && !version.getAuthor().equals(u))
return forbidden();
try {
version.delete();
return noContent();
} catch (AccessDeniedException e) {
return forbidden(e.getMessage());
}
}
});
}
@SubjectPresent
public Result downloadFolder(final String folderId) {
return folderBasedResult(folderId, new FolderOp() {
@Override
public Result apply(Session session, Folder folder)
throws RepositoryException, IOException {
final FileStoreHelper fh = new FileStoreHelper(session);
ctx().response().setContentType("application/zip");
ctx().response().setHeader("Content-Disposition",
ContentDispositionSupport.attachment(folder.getName()+".zip"));
return ok(fh.createZipFile(folder));
}
});
}
@SubjectPresent
public Result downloadFile(final String fileId, final String versionName) {
return versionBasedResult(fileId, versionName, new FileVersionOp() {
@Override
public final Result apply(
final Session session,
final FileStore.File file,
final FileStore.File version)
throws RepositoryException, IOException {
if (versionName.equals("latest") ||
versionName.equals(version.getName())) {
return seeOther(
controllers.routes.FileStoreController.downloadFile(
file.getIdentifier(),
version.getIdentifier()));
}
// Versions don't change, so they can be cached privately for a week
ctx().response().setHeader("Cache-Control", "max-age=604800, private");
// Check if we can send a 304 Not Modified
if (!ifNoneMatch(version)) {
return status(304);
}
final String authorName = version.getAuthor() != null ?
version.getAuthor().getName() : "unknown";
final String versionStamp =
String.format("(%1$tY%1$tm%1$tdT%1$tH%1$tM%1$tS %2$s)",
version.getModificationTime(),
authorName);
final String filename = getNameWithExt(
file.getName(), file.getMimeType()).replaceAll(
"(\\.?[^\\.]+$)", versionStamp + "$1" );
ctx().response().setContentType(version.getMimeType());
if (!version.getDigest().isEmpty()) {
ctx().response().setHeader("ETag",
version.getDigest().substring(0, 16));
}
ctx().response().setHeader("Last-Modified",
asHttpDate(version.getModificationTime()));
ctx().response().setHeader("Content-Disposition",
ContentDispositionSupport.attachment(filename));
return ok(version.getData());
}
private boolean ifNoneMatch(FileStore.File version) {
String etag = request().getHeader("If-None-Match");
if (etag == null) {
// RFC2616 allows us to check ifModifiedSince now
return ifModifiedSince(version);
}
return !version.getDigest().startsWith(etag);
}
private boolean ifModifiedSince(FileStore.File version) {
String lastModified = request().getHeader("If-Modified-Since");
if (lastModified == null)
return true;
try {
return version.getModificationTime()
.after(fromHttpDate(lastModified));
} catch (ParseException e) {
return true;
}
}
});
}
@SubjectPresent
public Result fileTextSummary(final String fileId, final String versionName) {
return versionBasedResult(fileId, versionName, new FileVersionOp() {
@Override
public final Result apply(
final Session session,
final FileStore.File file,
final FileStore.File version)
throws RepositoryException, IOException {
final ExtractionHelper eh = new ExtractionHelper(version);
return ok(eh.getPlainText()).as("text/plain; charset=utf-8");
}
});
}
@SubjectPresent
public Result groupPermissionList(final String folderId) {
return folderBasedResult(folderId, new FolderOp() {
@Override
public final Result apply(Session session, Folder folder)
throws RepositoryException {
final ArrayNode perms = JsonNodeFactory.instance.arrayNode();
for (final Map.Entry<String, Permission> e :
folder.getGroupPermissions().entrySet()) {
perms.add(groupJson(e.getKey(), e.getValue()));
}
return ok(perms).as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result groupPermission(final String folderId, final String groupName) {
return folderBasedResult(folderId, new FolderOp() {
@Override
public final Result apply(Session session, Folder folder)
throws RepositoryException {
final Map<String, Permission> permissions =
folder.getGroupPermissions();
if (!permissions.containsKey(groupName)) {
return notFound();
}
final Permission access = permissions.get(groupName);
return ok(groupJson(groupName, access))
.as("application/json; charset=utf-8");
}
});
}
protected ObjectNode groupJson(String groupName, Permission permission) {
final ObjectNode obj = Json.newObject();
obj.put("name", groupName);
obj.put("access", permission.toString());
return obj;
}
@SubjectPresent
public Result permissionUpdate(final String folderId) {
final JsonNode params = ctx().request().body().asJson();
if (!params.has("name") || !params.has("access")) {
return badRequest();
}
final String groupName = params.get("name").asText();
final Permission accessLevel = Permission.valueOf(
params.get("access").asText());
final Event event = inUserSession(new F.Function<Session, Event>() {
@Override
public final Event apply(Session session) throws RepositoryException,
IOException {
final FileStore.Manager fm = fileStoreImpl.getManager(session);
final FileStore.FileOrFolder fof = fm.getByIdentifier(folderId);
if (!(fof instanceof FileStoreImpl.Folder)) {
return null;
}
// Check this user has appropriate permissions
if (fof.getAccessLevel() != FileStore.Permission.RW) {
return null;
}
return FileStore.Events.update((FileStoreImpl.Folder) fof, session.getUserID());
}
});
if (event == null) {
return notFound();
}
// Try granting the permission
final Result result =
sessionFactory.inSession(new F.Function<Session, Result>() {
@Override
public Result apply(final Session session) throws Throwable {
final String id = event.info("id");
final GroupManager gm = new GroupManager(session);
final Group group = gm.find(groupName);
if (group == null)
return notFound();
final AorraAccessManager acm = (AorraAccessManager)
session.getAccessControlManager();
acm.grant(group.getPrincipal(),
session.getNodeByIdentifier(id).getPath(),
accessLevel.toJackrabbitPermission());
return null;
}
});
if (result != null)
return result;
fileStoreImpl.getEventManager().tell(event);
return groupPermission(folderId, groupName);
}
@SubjectPresent
public Result versionList(final String fileId) {
return fileBasedResult(fileId, new FileOp() {
@Override
public final Result apply(final Session session, final FileStore.File file)
throws RepositoryException {
final ArrayNode json = JsonNodeFactory.instance.arrayNode();
for (FileStore.File version : file.getVersions()) {
final User author = version.getAuthor();
final ObjectNode versionInfo = Json.newObject();
versionInfo.put("id", version.getIdentifier());
versionInfo.put("name", version.getName());
if (author != null) {
final ObjectNode authorInfo = Json.newObject();
authorInfo.put("id", author.getId());
authorInfo.put("name", author.getName());
authorInfo.put("email", author.getEmail());
versionInfo.put("author", authorInfo);
}
versionInfo.put("timestamp",
ISO8601Utils.format(
version.getModificationTime().getTime(), false,
TimeZone.getDefault()));
json.add(versionInfo);
}
return ok(json).as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result createFile() {
final JsonNode params = ctx().request().body().asJson();
if (!params.has("name") || params.get("name").asText().isEmpty()) {
return badRequest("File must have a name");
}
if (!params.has("parent")) {
return badRequest("File must have a parent folder");
}
return folderBasedResult(params.get("parent").asText(), new FolderOp() {
@Override
public Result apply(Session session, Folder folder) throws Throwable {
final JsonBuilder jb = new JsonBuilder();
final String name = params.get("name").asText();
final String mimeType = params.has("mime")
? params.get("mime").asText()
: getMimeType(name, "application/octet-stream");
final FileStore.File file =
folder.createFile(name, mimeType,
new ByteArrayInputStream(new byte[]{}));
return created(jb.toJsonShallow(file))
.as("application/json; charset=utf-8");
}
});
}
@SubjectPresent
public Result updateFile(final String fileID) {
final MultipartFormData body = request().body().asMultipartFormData();
if (body == null || body.getFiles().size() != 1) {
if (request().headers().containsKey("Content-Type")) {
if (request().body().asRaw() != null) {
return updateToFile(fileID, request().body().asRaw().asBytes());
} else if (request().body().asText() != null) {
return updateToFile(fileID, request().body().asText().getBytes());
}
}
return badRequest("Request must contain a single file to upload.")
.as("text/plain");
} else {
return uploadToFile(fileID, body.getFiles().get(0));
}
}
protected Result updateToFile(final String fileID, final byte[] buf) {
return fileBasedResult(fileID, new FileOp() {
@Override
public final Result apply(Session session, FileStore.File f)
throws RepositoryException, FileNotFoundException {
try {
final String mimeType = request().headers().get("Content-Type")[0];
final JsonBuilder jb = new JsonBuilder();
f.update(mimeType, new ByteArrayInputStream(buf));
session.save();
Logger.info(String.format(
"file %s content type %s uploaded to %s by %s",
f.getName(), mimeType,
f.getPath(), getUser()));
return ok(jb.toJsonShallow(f)).as("application/json; charset=utf-8");
} catch (ItemExistsException iee) {
return forbidden(iee.getMessage());
} catch (AccessDeniedException ade) {
return forbidden(
"Insufficient permissions to upload files to folder.");
}
}
});
}
protected Result uploadToFile(final String fileID,
final MultipartFormData.FilePart filePart) {
return fileBasedResult(fileID, new FileOp() {
@Override
public final Result apply(Session session, FileStore.File f)
throws RepositoryException, FileNotFoundException {
try {
final JsonBuilder jb = new JsonBuilder();
f.update(getMimeType(filePart),
new FileInputStream(filePart.getFile()));
session.save();
Logger.info(String.format(
"file %s content type %s uploaded to %s by %s",
filePart.getFilename(), getMimeType(filePart),
f.getPath(), getUser()));
return ok(jb.toJsonShallow(f)).as("application/json; charset=utf-8");
} catch (ItemExistsException iee) {
return forbidden(iee.getMessage());
} catch (AccessDeniedException ade) {
return forbidden(
"Insufficient permissions to upload files to folder.");
}
}
});
}
@SubjectPresent
public Result uploadToFolder(final String folderID) {
return folderBasedResult(folderID, new FolderOp() {
@Override
public final Result apply(Session session, FileStore.Folder folder)
throws RepositoryException {
final MultipartFormData body = request().body().asMultipartFormData();
if (body == null || body.getFiles().size() != 1) {
return badRequest("Request must contain a single file to upload.")
.as("text/plain");
}
final MultipartFormData.FilePart filePart = body.getFiles().get(0);
try {
final JsonBuilder jb = new JsonBuilder();
FileStore.File f = updateFileContents(folder, filePart);
session.save();
Logger.info(String.format(
"file %s content type %s uploaded to %s by %s",
filePart.getFilename(), getMimeType(filePart),
f.getPath(), getUser()));
return created(jb.toJsonShallow(f))
.as("application/json; charset=utf-8");
} catch (ItemExistsException iee) {
return forbidden(iee.getMessage());
} catch (AccessDeniedException ade) {
return forbidden(
"Insufficient permissions to upload files to folder.");
}
}
});
}
protected ArrayNode getUsersJson(Session session) throws RepositoryException {
final JsonBuilder jb = new JsonBuilder();
final ArrayNode json = JsonNodeFactory.instance.arrayNode();
final UserDAO dao = new UserDAO(session, jcrom);
for (final User user : dao.list()) {
json.add(jb.toJson(user, isAdmin(session, dao, user)));
}
return json;
}
protected UserDAO getUserDAO(Session session) {
return new UserDAO(session, jcrom);
}
private interface FofOp<T extends FileStore.FileOrFolder>
extends F.Function2<Session, T, Result> {}
private interface FolderOp extends FofOp<FileStore.Folder> {}
private interface FileOp extends FofOp<FileStore.File> {}
private interface FileVersionOp
extends F.Function3<Session, FileStore.File, FileStore.File, Result> {}
protected Result folderBasedResult(
final String folderId,
final FolderOp operation) {
return fofBasedResult(folderId, FileStore.Folder.class, operation);
}
protected Result fileBasedResult(
final String folderId,
final FileOp operation) {
return fofBasedResult(folderId, FileStore.File.class, operation);
}
public Result versionBasedResult(
final String fileId,
final String versionId,
final FileVersionOp operation) {
return fileBasedResult(fileId, new FileOp() {
@Override
public final Result apply(Session session, FileStore.File file)
throws Throwable {
final SortedSet<FileStore.File> versions = file.getVersions();
if (versionId.equals("latest")) {
return operation.apply(session, file, versions.last());
}
for (FileStore.File version : versions) {
if (version.getIdentifier().equals(versionId) ||
version.getName().equals(versionId)) {
return operation.apply(session, file, version);
}
}
return notFound(versionId + " is not a valid version for this file.");
}
});
}
protected <T extends FileStore.FileOrFolder> Result fofBasedResult(
final String fofId,
final Class<T> fofClass,
final FofOp<T> operation) {
final String typeName = fofClass.getSimpleName().toLowerCase();
return inUserSession(new F.Function<Session, Result>() {
@SuppressWarnings("unchecked")
@Override
public final Result apply(Session session) throws Throwable {
final FileStore.Manager fm = fileStoreImpl.getManager(session);
final FileStore.FileOrFolder fof = fm.getByIdentifier(fofId);
if (fof == null) {
return notFoundOfRequestedType();
} else if (!fofClass.isInstance(fof)) {
return badRequest(fofId+" is not a "+typeName+".")
.as("text/plain");
} else {
return operation.apply(session, (T) fof);
}
}
});
}
private FileStore.File updateFileContents(FileStore.Folder folder,
MultipartFormData.FilePart filePart) throws RepositoryException {
try {
final FileStore.FileOrFolder fof =
folder.getFileOrFolder(filePart.getFilename());
final FileStore.File f;
if (fof == null) {
f = folder.createFile(filePart.getFilename(),
getMimeType(filePart),
new FileInputStream(filePart.getFile()));
} else if (fof instanceof FileStore.File) {
throw new ItemExistsException(
"File already exists. Add a new version instead.");
} else {
throw new ItemExistsException("Item exists and is not a file.");
}
return f;
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
protected String getMimeType(MultipartFormData.FilePart filePart) {
return getMimeType(filePart.getFilename(), filePart.getContentType());
}
protected String getMimeType(String filename, String defaultMimeType) {
// prefer guessed mimetypes to fix an issue with xlsx file upload with firefox
// configure mimetypes in application.conf
final scala.Option<String> guessed = MimeTypes.forFileName(filename);
return guessed.nonEmpty() ? guessed.get() : defaultMimeType;
}
protected Result notFoundOfRequestedType() {
final NotFoundMessage nf = NotFoundMessage.from(request().acceptedTypes());
return notFound(nf.bytes()).as(nf.mimeType());
}
}