]> git.argeo.org Git - gpl/argeo-suite.git/blob - knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkSubmissionServlet.java
Use stack layout for tabbed area.
[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 import java.util.HashSet;
9 import java.util.Set;
10
11 import javax.jcr.ImportUUIDBehavior;
12 import javax.jcr.Node;
13 import javax.jcr.Property;
14 import javax.jcr.Repository;
15 import javax.jcr.RepositoryException;
16 import javax.jcr.Session;
17 import javax.jcr.nodetype.NodeType;
18 import javax.servlet.ServletException;
19 import javax.servlet.http.HttpServlet;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22 import javax.servlet.http.Part;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.argeo.api.NodeUtils;
27 import org.argeo.cms.auth.CmsSession;
28 import org.argeo.cms.servlet.ServletAuthUtils;
29 import org.argeo.jcr.Jcr;
30 import org.argeo.jcr.JcrUtils;
31 import org.argeo.suite.SuiteUtils;
32 import org.argeo.support.odk.OrxType;
33 import org.argeo.support.xforms.FormSubmissionListener;
34
35 /** Receives a form submission. */
36 public class OdkSubmissionServlet extends HttpServlet {
37 private static final long serialVersionUID = 7834401404691302385L;
38 private final static Log log = LogFactory.getLog(OdkSubmissionServlet.class);
39
40 private final static String XML_SUBMISSION_FILE = "xml_submission_file";
41
42 private DateTimeFormatter submissionNameFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmmssSSS")
43 .withZone(ZoneId.from(ZoneOffset.UTC));
44
45 private Repository repository;
46
47 private Set<FormSubmissionListener> submissionListeners = new HashSet<>();
48
49 @Override
50 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
51 resp.setContentType("text/xml; charset=utf-8");
52 resp.setHeader("X-OpenRosa-Version", "1.0");
53 resp.setDateHeader("Date", System.currentTimeMillis());
54 resp.setIntHeader("X-OpenRosa-Accept-Content-Length", 1024 * 1024);
55
56 Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req);
57
58 try {
59 // Node submissions = JcrUtils.mkdirs(session,
60 // "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE);
61 CmsSession cmsSession = ServletAuthUtils.getCmsSession(req);
62
63 ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
64 Thread.currentThread().setContextClassLoader(ServletAuthUtils.class.getClassLoader());
65 Session adminSession = null;
66 try {
67 // TODO centralise at a deeper level
68 adminSession = NodeUtils.openDataAdminSession(repository, null);
69 SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
70 } finally {
71 Jcr.logout(adminSession);
72 Thread.currentThread().setContextClassLoader(currentContextCl);
73 }
74
75 Node cmsSessionNode = SuiteUtils.getCmsSessionNode(session, cmsSession);
76 Node submission = cmsSessionNode.addNode(submissionNameFormatter.format(Instant.now()),
77 OrxType.submission.get());
78 for (Part part : req.getParts()) {
79 if (log.isDebugEnabled())
80 log.debug("Part: " + part.getName() + ", " + part.getContentType());
81
82 if (part.getName().equals(XML_SUBMISSION_FILE)) {
83 Node xml = submission.addNode(XML_SUBMISSION_FILE, NodeType.NT_UNSTRUCTURED);
84 session.importXML(xml.getPath(), part.getInputStream(),
85 ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
86
87 } else {
88 Node fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream());
89 String contentType = part.getContentType();
90 if (contentType != null) {
91 fileNode.addMixin(NodeType.MIX_MIMETYPE);
92 fileNode.setProperty(Property.JCR_MIMETYPE, contentType);
93
94 }
95 if (part.getName().endsWith(".jpg") || part.getName().endsWith(".png")) {
96 // TODO meta data and thumbnails
97 }
98 }
99 }
100 session.save();
101 for (FormSubmissionListener submissionListener : submissionListeners) {
102 submissionListener.formSubmissionReceived(submission);
103 }
104 } catch (RepositoryException e) {
105 e.printStackTrace();
106 resp.setStatus(503);
107 return;
108 } finally {
109 Jcr.logout(session);
110 }
111
112 resp.setStatus(201);
113 resp.getWriter().write("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">"
114 + "<message>Form Received!</message>" + "</OpenRosaResponse>");
115
116 }
117
118 public void setRepository(Repository repository) {
119 this.repository = repository;
120 }
121
122 public synchronized void addSubmissionListener(FormSubmissionListener listener) {
123 submissionListeners.add(listener);
124 }
125
126 public synchronized void removeSubmissionListener(FormSubmissionListener listener) {
127 submissionListeners.remove(listener);
128 }
129 }