Introduce XML upload.
[gpl/argeo-suite.git] / knowledge / org.argeo.support.odk / src / org / argeo / support / odk / servlet / OdkSubmissionServlet.java
1 package org.argeo.support.odk.servlet;
2
3 import java.io.IOException;
4 import java.time.Instant;
5 import java.time.ZoneId;
6 import java.time.ZoneOffset;
7 import java.time.format.DateTimeFormatter;
8
9 import javax.jcr.ImportUUIDBehavior;
10 import javax.jcr.Node;
11 import javax.jcr.Repository;
12 import javax.jcr.RepositoryException;
13 import javax.jcr.Session;
14 import javax.jcr.nodetype.NodeType;
15 import javax.servlet.ServletException;
16 import javax.servlet.http.HttpServlet;
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpServletResponse;
19 import javax.servlet.http.Part;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.cms.servlet.ServletAuthUtils;
24 import org.argeo.entity.EntityNames;
25 import org.argeo.jcr.Jcr;
26 import org.argeo.jcr.JcrUtils;
27 import org.argeo.support.odk.OrxType;
28
29 /** Receives a form submission. */
30 public class OdkSubmissionServlet extends HttpServlet {
31         private static final long serialVersionUID = 7834401404691302385L;
32         private final static Log log = LogFactory.getLog(OdkSubmissionServlet.class);
33
34         private final static String XML_SUBMISSION_FILE = "xml_submission_file";
35
36         private DateTimeFormatter submissionNameFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmmssSSS")
37                         .withZone(ZoneId.from(ZoneOffset.UTC));
38
39         private Repository repository;
40
41         @Override
42         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
43                 resp.setContentType("text/xml; charset=utf-8");
44                 resp.setHeader("X-OpenRosa-Version", "1.0");
45                 resp.setDateHeader("Date", System.currentTimeMillis());
46                 resp.setIntHeader("X-OpenRosa-Accept-Content-Length", 1024 * 1024);
47
48                 Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req);
49
50                 try {
51                         Node submissions = JcrUtils.mkdirs(session,
52                                         "/" + EntityNames.FORM_BASE + "/" + EntityNames.SUBMISSIONS_BASE);
53                         Node submission = submissions.addNode(submissionNameFormatter.format(Instant.now()),
54                                         OrxType.submission.get());
55                         for (Part part : req.getParts()) {
56                                 if (log.isDebugEnabled())
57                                         log.debug("Part: " + part.getName() + ", " + part.getContentType());
58
59                                 if (part.getName().equals(XML_SUBMISSION_FILE)) {
60                                         Node xml = submission.addNode(XML_SUBMISSION_FILE, NodeType.NT_UNSTRUCTURED);
61                                         session.importXML(xml.getPath(), part.getInputStream(),
62                                                         ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
63
64 //                                      Part xmlSubmissionPart = req.getPart(XML_SUBMISSION_FILE);
65 //                                      if (xmlSubmissionPart == null)
66 //                                              throw new ServletException("No " + XML_SUBMISSION_FILE + " part");
67 //                              try (InputStream in = xmlSubmissionPart.getInputStream();) {
68 //                                      // pretty print
69 //                                      Transformer transformer = TransformerFactory.newInstance().newTransformer();
70 //                                      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
71 //                                      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
72 //                                      StreamResult result = new StreamResult(new StringWriter());
73 //                                      StreamSource source = new StreamSource(in);
74 //                                      transformer.transform(source, result);
75 //                                      String xmlString = result.getWriter().toString();
76 //                                      System.out.println(xmlString);
77 //                              } catch (TransformerException e) {
78 //                                      e.printStackTrace();
79 //                              }
80
81                                 } else {
82                                         JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream());
83                                 }
84                         }
85                         session.save();
86                 } catch (RepositoryException e) {
87                         e.printStackTrace();
88                         resp.setStatus(503);
89                         return;
90                 }
91
92                 resp.setStatus(201);
93                 resp.getWriter().write("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">"
94                                 + "<message>Form Received!</message>" + "</OpenRosaResponse>");
95
96         }
97
98         public void setRepository(Repository repository) {
99                 this.repository = repository;
100         }
101
102 }