X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.app.servlet.odk%2Fsrc%2Forg%2Fargeo%2Fapp%2Fservlet%2Fodk%2FOdkSubmissionServlet.java;h=3740805f1216a7aff661f559f10a7cdd15e8b1d1;hb=d6c9d33b61e475914d3f8d7534374ed30eca8150;hp=25d00f45f4176bc0902706f9d75a3a5b148a9dd9;hpb=6c42d7ee01c29a184390a3fd789ebdf5cde84a00;p=gpl%2Fargeo-suite.git diff --git a/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkSubmissionServlet.java b/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkSubmissionServlet.java index 25d00f4..3740805 100644 --- a/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkSubmissionServlet.java +++ b/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkSubmissionServlet.java @@ -1,6 +1,8 @@ package org.argeo.app.servlet.odk; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.time.Instant; import java.time.ZoneId; import java.time.ZoneOffset; @@ -12,7 +14,6 @@ import javax.jcr.ImportUUIDBehavior; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.Repository; -import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; import javax.servlet.ServletException; @@ -21,14 +22,16 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; +import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.CmsSession; -import org.argeo.app.core.SuiteUtils; +import org.argeo.app.image.ImageProcessor; +import org.argeo.app.jcr.SuiteJcrUtils; import org.argeo.app.odk.OrxType; import org.argeo.app.xforms.FormSubmissionListener; -import org.argeo.api.cms.CmsLog; import org.argeo.cms.auth.RemoteAuthRequest; import org.argeo.cms.auth.RemoteAuthUtils; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.jcr.acr.JcrContent; import org.argeo.cms.servlet.ServletHttpRequest; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrUtils; @@ -52,29 +55,31 @@ public class OdkSubmissionServlet extends HttpServlet { resp.setContentType("text/xml; charset=utf-8"); resp.setHeader("X-OpenRosa-Version", "1.0"); resp.setDateHeader("Date", System.currentTimeMillis()); - resp.setIntHeader("X-OpenRosa-Accept-Content-Length", 1024 * 1024); + + // should be set in HEAD? Let's rather use defaults. + // resp.setIntHeader("X-OpenRosa-Accept-Content-Length", 1024 * 1024); RemoteAuthRequest request = new ServletHttpRequest(req); Session session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), request); - try { - CmsSession cmsSession = RemoteAuthUtils.getCmsSession(request); + CmsSession cmsSession = RemoteAuthUtils.getCmsSession(request); - Session adminSession = null; - try { - // TODO centralise at a deeper level - adminSession = CmsJcrUtils.openDataAdminSession(repository, null); - SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession); - } finally { - Jcr.logout(adminSession); - } + Session adminSession = null; + try { + // TODO centralise at a deeper level + adminSession = CmsJcrUtils.openDataAdminSession(repository, null); + SuiteJcrUtils.getOrCreateCmsSessionNode(adminSession, cmsSession); + } finally { + Jcr.logout(adminSession); + } - Node cmsSessionNode = SuiteUtils.getCmsSessionNode(session, cmsSession); + try { + Node cmsSessionNode = SuiteJcrUtils.getCmsSessionNode(session, cmsSession); Node submission = cmsSessionNode.addNode(submissionNameFormatter.format(Instant.now()), OrxType.submission.get()); for (Part part : req.getParts()) { - if (log.isDebugEnabled()) - log.debug("Part: " + part.getName() + ", " + part.getContentType()); + if (log.isTraceEnabled()) + log.trace("Part: " + part.getName() + ", " + part.getContentType()); if (part.getName().equals(XML_SUBMISSION_FILE)) { Node xml = submission.addNode(XML_SUBMISSION_FILE, NodeType.NT_UNSTRUCTURED); @@ -82,7 +87,22 @@ public class OdkSubmissionServlet extends HttpServlet { ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); } else { - Node fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream()); + Node fileNode; + if (part.getName().endsWith(".jpg")) { + // Fix metadata + Path temp = Files.createTempFile("image", ".jpg"); + try { + ImageProcessor imageProcessor = new ImageProcessor(() -> part.getInputStream(), + () -> Files.newOutputStream(temp)); + imageProcessor.process(); + fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), + Files.newInputStream(temp)); + } finally { + Files.deleteIfExists(temp); + } + } else { + fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream()); + } String contentType = part.getContentType(); if (contentType != null) { fileNode.addMixin(NodeType.MIX_MIMETYPE); @@ -94,12 +114,22 @@ public class OdkSubmissionServlet extends HttpServlet { } } } + session.save(); - for (FormSubmissionListener submissionListener : submissionListeners) { - submissionListener.formSubmissionReceived(submission); + try { + for (FormSubmissionListener submissionListener : submissionListeners) { + submissionListener.formSubmissionReceived(JcrContent.nodeToContent(submission)); + } + } catch (Exception e) { + log.error("Cannot save submision, cancelling...", e); + submission.remove(); + session.save(); + resp.setStatus(503); + return; } - } catch (RepositoryException e) { - e.printStackTrace(); + + } catch (Exception e) { + log.error("Cannot save submision", e); resp.setStatus(503); return; } finally {