Log out session in ODK submission servlet.
[gpl/argeo-suite.git] / knowledge / org.argeo.support.odk / src / org / argeo / support / odk / servlet / OdkSubmissionServlet.java
index 862ff3665d9c2341ce2cc8c900a560b9b90db18a..70a80c0cdb7e67732f5fa37ea17364bc1c761783 100644 (file)
@@ -5,9 +5,12 @@ import java.time.Instant;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.jcr.ImportUUIDBehavior;
 import javax.jcr.Node;
+import javax.jcr.Property;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -20,11 +23,14 @@ import javax.servlet.http.Part;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeUtils;
+import org.argeo.cms.auth.CmsSession;
 import org.argeo.cms.servlet.ServletAuthUtils;
-import org.argeo.entity.EntityNames;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.suite.SuiteUtils;
 import org.argeo.support.odk.OrxType;
+import org.argeo.support.xforms.FormSubmissionListener;
 
 /** Receives a form submission. */
 public class OdkSubmissionServlet extends HttpServlet {
@@ -38,6 +44,8 @@ public class OdkSubmissionServlet extends HttpServlet {
 
        private Repository repository;
 
+       private Set<FormSubmissionListener> submissionListeners = new HashSet<>();
+
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                resp.setContentType("text/xml; charset=utf-8");
@@ -48,9 +56,24 @@ public class OdkSubmissionServlet extends HttpServlet {
                Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req);
 
                try {
-                       Node submissions = JcrUtils.mkdirs(session,
-                                       "/" + EntityNames.FORM_BASE + "/" + EntityNames.SUBMISSIONS_BASE);
-                       Node submission = submissions.addNode(submissionNameFormatter.format(Instant.now()),
+//                     Node submissions = JcrUtils.mkdirs(session,
+//                                     "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE);
+                       CmsSession cmsSession = ServletAuthUtils.getCmsSession(req);
+
+                       ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
+                       Thread.currentThread().setContextClassLoader(ServletAuthUtils.class.getClassLoader());
+                       Session adminSession = null;
+                       try {
+                               // TODO centralise at a deeper level
+                               adminSession = NodeUtils.openDataAdminSession(repository, null);
+                               SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
+                       } finally {
+                               Jcr.logout(adminSession);
+                               Thread.currentThread().setContextClassLoader(currentContextCl);
+                       }
+
+                       Node cmsSessionNode = SuiteUtils.getCmsSessionNode(session, cmsSession);
+                       Node submission = cmsSessionNode.addNode(submissionNameFormatter.format(Instant.now()),
                                        OrxType.submission.get());
                        for (Part part : req.getParts()) {
                                if (log.isDebugEnabled())
@@ -61,32 +84,29 @@ public class OdkSubmissionServlet extends HttpServlet {
                                        session.importXML(xml.getPath(), part.getInputStream(),
                                                        ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
 
-//                                     Part xmlSubmissionPart = req.getPart(XML_SUBMISSION_FILE);
-//                                     if (xmlSubmissionPart == null)
-//                                             throw new ServletException("No " + XML_SUBMISSION_FILE + " part");
-//                             try (InputStream in = xmlSubmissionPart.getInputStream();) {
-//                                     // pretty print
-//                                     Transformer transformer = TransformerFactory.newInstance().newTransformer();
-//                                     transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-//                                     transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-//                                     StreamResult result = new StreamResult(new StringWriter());
-//                                     StreamSource source = new StreamSource(in);
-//                                     transformer.transform(source, result);
-//                                     String xmlString = result.getWriter().toString();
-//                                     System.out.println(xmlString);
-//                             } catch (TransformerException e) {
-//                                     e.printStackTrace();
-//                             }
-
                                } else {
-                                       JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream());
+                                       Node fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream());
+                                       String contentType = part.getContentType();
+                                       if (contentType != null) {
+                                               fileNode.addMixin(NodeType.MIX_MIMETYPE);
+                                               fileNode.setProperty(Property.JCR_MIMETYPE, contentType);
+
+                                       }
+                                       if (part.getName().endsWith(".jpg") || part.getName().endsWith(".png")) {
+                                               // TODO meta data and thumbnails
+                                       }
                                }
                        }
                        session.save();
+                       for (FormSubmissionListener submissionListener : submissionListeners) {
+                               submissionListener.formSubmissionReceived(submission);
+                       }
                } catch (RepositoryException e) {
                        e.printStackTrace();
                        resp.setStatus(503);
                        return;
+               } finally {
+                       Jcr.logout(session);
                }
 
                resp.setStatus(201);
@@ -99,4 +119,11 @@ public class OdkSubmissionServlet extends HttpServlet {
                this.repository = repository;
        }
 
+       public synchronized void addSubmissionListener(FormSubmissionListener listener) {
+               submissionListeners.add(listener);
+       }
+
+       public synchronized void removeSubmissionListener(FormSubmissionListener listener) {
+               submissionListeners.remove(listener);
+       }
 }