package fi.otavanopisto.muikku.plugins.workspace;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import javax.transaction.Transactional;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import fi.otavanopisto.muikku.controller.SystemSettingsController;
import fi.otavanopisto.muikku.model.workspace.WorkspaceEntity;
import fi.otavanopisto.muikku.plugins.material.BinaryMaterialController;
import fi.otavanopisto.muikku.plugins.material.HtmlMaterialController;
import fi.otavanopisto.muikku.plugins.material.model.BinaryMaterial;
import fi.otavanopisto.muikku.plugins.material.model.HtmlMaterial;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterial;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceRootFolder;
import fi.otavanopisto.muikku.schooldata.WorkspaceEntityController;
import fi.otavanopisto.muikku.security.MuikkuPermissions;
import fi.otavanopisto.muikku.session.SessionController;
@MultipartConfig
@WebServlet("/materialAttachmentUploadServlet/*")
@Transactional
public class MaterialAttachmentUploadServlet extends HttpServlet {
private static final long serialVersionUID = 4661251499908326136L;
@Inject
private SystemSettingsController systemSettingsController;
@Inject
private WorkspaceMaterialController workspaceMaterialController;
@Inject
private WorkspaceEntityController workspaceEntityController;
@Inject
private HtmlMaterialController htmlMaterialController;
@Inject
private BinaryMaterialController binaryMaterialController;
@Inject
private SessionController sessionController;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String materialUrl = req.getPathInfo();
if (StringUtils.isBlank(materialUrl)) {
sendResponse(resp, "Missing material path", HttpServletResponse.SC_BAD_REQUEST);
return;
}
if (!sessionController.isLoggedIn()) {
sendResponse(resp, "Unauthorized", HttpServletResponse.SC_UNAUTHORIZED);
return;
}
Part file = req.getPart("upload");
if (file == null) {
sendResponse(resp, "Missing file", HttpServletResponse.SC_BAD_REQUEST);
return;
}
long fileSizeLimit = systemSettingsController.getUploadFileSizeLimit();
if (file.getSize() > fileSizeLimit) {
sendResponse(resp, "File too large", HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
return;
}
WorkspaceMaterial parentWorkspaceMaterial = workspaceMaterialController.findWorkspaceMaterialByRootPath(materialUrl);
if (parentWorkspaceMaterial == null) {
sendResponse(resp, "Material not found", HttpServletResponse.SC_NOT_FOUND);
return;
}
WorkspaceRootFolder workspaceRootFolder = workspaceMaterialController.findWorkspaceRootFolderByWorkspaceNode(parentWorkspaceMaterial);
if (workspaceRootFolder == null) {
sendResponse(resp, "Workspace root folder not found", HttpServletResponse.SC_NOT_FOUND);
return;
}
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceEntityById(workspaceRootFolder.getWorkspaceEntityId());
if (workspaceEntity == null) {
sendResponse(resp, "Workspace entity not found", HttpServletResponse.SC_NOT_FOUND);
return;
}
if (!sessionController.hasWorkspacePermission(MuikkuPermissions.MANAGE_WORKSPACE_MATERIALS, workspaceEntity)) {
sendResponse(resp, "Forbidden", HttpServletResponse.SC_FORBIDDEN);
return;
}
HtmlMaterial parentMaterial = htmlMaterialController.findHtmlMaterialById(parentWorkspaceMaterial.getMaterialId());
if (parentMaterial == null) {
sendResponse(resp, "Parent material is not html material", HttpServletResponse.SC_BAD_REQUEST);
return;
}
String license = null;
BinaryMaterial uploadedMaterial = binaryMaterialController.createBinaryMaterial(file.getSubmittedFileName(),
file.getContentType(),
IOUtils.toByteArray(file.getInputStream()),
license);
String uploadedUrl = null;
List<WorkspaceMaterial> parentWorkspaceMaterials = workspaceMaterialController.listWorkspaceMaterialsByMaterial(parentMaterial);
for (WorkspaceMaterial sharedWorkspaceMaterial : parentWorkspaceMaterials) {
WorkspaceMaterial uploadedWorkspaceMaterial = workspaceMaterialController.createWorkspaceMaterial(sharedWorkspaceMaterial, uploadedMaterial);
if (sharedWorkspaceMaterial.getId().equals(parentWorkspaceMaterial.getId())) {
uploadedUrl = uploadedWorkspaceMaterial.getUrlName();
}
}
if (StringUtils.isBlank(uploadedUrl)) {
sendResponse(resp, "Could not resolve uploaded file url", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
UploadMeta uploadMeta = new UploadMeta(file.getName(), 1, uploadedUrl);
resp.setContentType("application/json");
ServletOutputStream servletOutputStream = resp.getOutputStream();
try {
(new ObjectMapper()).writeValue(servletOutputStream, uploadMeta);
} finally {
servletOutputStream.flush();
}
}
private void sendResponse(HttpServletResponse resp, String message, int status) throws IOException {
resp.setStatus(status);
PrintWriter writer = resp.getWriter();
writer.write(message);
writer.flush();
}
public class UploadMeta {
public UploadMeta(String fileName, long uploaded, String url) {
super();
this.fileName = fileName;
this.uploaded = uploaded;
this.url = url;
}
public String getFileName() {
return fileName;
}
public long getUploaded() {
return uploaded;
}
public String getUrl() {
return url;
}
private String fileName;
private long uploaded;
private String url;
}
}