Introduce XML upload.
[gpl/argeo-suite.git] / knowledge / org.argeo.support.odk / src / org / argeo / support / odk / servlet / OdkSubmissionServlet.java
index e5f5a3ffa6310cda67599c417f98d6b5f94246fa..862ff3665d9c2341ce2cc8c900a560b9b90db18a 100644 (file)
@@ -1,24 +1,30 @@
 package org.argeo.support.odk.servlet;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
 
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.Node;
 import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.Part;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.servlet.ServletAuthUtils;
+import org.argeo.entity.EntityNames;
+import org.argeo.jcr.Jcr;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.support.odk.OrxType;
 
 /** Receives a form submission. */
 public class OdkSubmissionServlet extends HttpServlet {
@@ -27,41 +33,68 @@ public class OdkSubmissionServlet extends HttpServlet {
 
        private final static String XML_SUBMISSION_FILE = "xml_submission_file";
 
+       private DateTimeFormatter submissionNameFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmmssSSS")
+                       .withZone(ZoneId.from(ZoneOffset.UTC));
+
        private Repository repository;
 
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-               for (Part part : req.getParts()) {
-                       if (log.isDebugEnabled())
-                               log.debug("Part: " + part.getName() + ", " + part.getContentType());
-               }
-               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();
-               }
-
                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);
+
+               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()),
+                                       OrxType.submission.get());
+                       for (Part part : req.getParts()) {
+                               if (log.isDebugEnabled())
+                                       log.debug("Part: " + part.getName() + ", " + part.getContentType());
+
+                               if (part.getName().equals(XML_SUBMISSION_FILE)) {
+                                       Node xml = submission.addNode(XML_SUBMISSION_FILE, NodeType.NT_UNSTRUCTURED);
+                                       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());
+                               }
+                       }
+                       session.save();
+               } catch (RepositoryException e) {
+                       e.printStackTrace();
+                       resp.setStatus(503);
+                       return;
+               }
+
                resp.setStatus(201);
                resp.getWriter().write("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">"
                                + "<message>Form Received!</message>" + "</OpenRosaResponse>");
 
        }
-       
+
        public void setRepository(Repository repository) {
                this.repository = repository;
        }