Introduce XML upload.
[gpl/argeo-suite.git] / knowledge / org.argeo.support.odk / src / org / argeo / support / odk / servlet / OdkFormListServlet.java
1 package org.argeo.support.odk.servlet;
2
3 import java.io.IOException;
4 import java.io.Writer;
5 import java.time.ZoneId;
6 import java.time.ZoneOffset;
7 import java.time.format.DateTimeFormatter;
8 import java.util.Collections;
9 import java.util.HashSet;
10 import java.util.Set;
11
12 import javax.jcr.Node;
13 import javax.jcr.NodeIterator;
14 import javax.jcr.Property;
15 import javax.jcr.Repository;
16 import javax.jcr.RepositoryException;
17 import javax.jcr.Session;
18 import javax.jcr.query.Query;
19 import javax.jcr.query.QueryResult;
20 import javax.servlet.ServletException;
21 import javax.servlet.http.HttpServlet;
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.argeo.api.NodeConstants;
28 import org.argeo.cms.servlet.ServletAuthUtils;
29 import org.argeo.entity.EntityType;
30 import org.argeo.jcr.Jcr;
31 import org.argeo.jcr.JcrUtils;
32 import org.argeo.jcr.JcrxApi;
33 import org.argeo.support.odk.OdkForm;
34 import org.argeo.support.odk.OdkNames;
35 import org.argeo.support.odk.OrxListType;
36
37 /** Lists available forms. */
38 public class OdkFormListServlet extends HttpServlet {
39         private static final long serialVersionUID = 2706191315048423321L;
40         private final static Log log = LogFactory.getLog(OdkFormListServlet.class);
41
42         private Set<OdkForm> odkForms = Collections.synchronizedSet(new HashSet<>());
43
44         private DateTimeFormatter versionFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmm")
45                         .withZone(ZoneId.from(ZoneOffset.UTC));
46
47         private Repository repository;
48
49         @Override
50         protected void doGet(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
55                 String serverName = req.getServerName();
56                 int serverPort = req.getServerPort();
57                 String protocol = serverPort == 443 || req.isSecure() ? "https" : "http";
58
59                 String pathInfo = req.getPathInfo();
60
61                 Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, NodeConstants.SYS_WORKSPACE), req);
62 //              session = NodeUtils.openDataAdminSession(repository, NodeConstants.SYS_WORKSPACE);
63                 Writer writer = resp.getWriter();
64                 writer.append("<?xml version='1.0' encoding='UTF-8' ?>");
65                 writer.append("<xforms xmlns=\"http://openrosa.org/xforms/xformsList\">");
66                 boolean oldApproach = false;
67                 if (!oldApproach) {
68                         try {
69
70                                 Query query;
71                                 if (pathInfo == null) {
72 //                              query = session.getWorkspace().getQueryManager()
73 //                                              .createQuery("SELECT * FROM [nt:unstructured]", Query.JCR_SQL2);
74                                         query = session.getWorkspace().getQueryManager()
75                                                         .createQuery("SELECT * FROM [" + OrxListType.xform.get() + "]", Query.JCR_SQL2);
76                                 } else {
77                                         query = session.getWorkspace().getQueryManager()
78                                                         .createQuery(
79                                                                         "SELECT node FROM [" + OrxListType.xform.get()
80                                                                                         + "] AS node WHERE ISDESCENDANTNODE (node, '" + pathInfo + "')",
81                                                                         Query.JCR_SQL2);
82                                 }
83                                 QueryResult queryResult = query.execute();
84
85                                 NodeIterator nit = queryResult.getNodes();
86 //                              log.debug(session.getUserID());
87 //                              log.debug(session.getWorkspace().getName());
88 //                              NodeIterator nit = session.getRootNode().getNodes();
89 //                              while (nit.hasNext()) {
90 //                                      log.debug(nit.nextNode());
91 //                              }
92                                 while (nit.hasNext()) {
93                                         StringBuilder sb = new StringBuilder();
94                                         Node node = nit.nextNode();
95                                         if (node.isNodeType(OrxListType.xform.get())) {
96                                                 sb.append("<xform>");
97                                                 sb.append("<formID>"
98                                                                 + node.getNode(OdkNames.H_HTML + "/h:head/xforms:model/xforms:instance/xforms:data")
99                                                                                 .getProperty("id").getString()
100                                                                 + "</formID>");
101                                                 sb.append("<name>" + Jcr.getTitle(node) + "</name>");
102                                                 sb.append("<version>" + versionFormatter.format(JcrUtils.getModified(node)) + "</version>");
103 //                                              sb.append("<version>" + versionFormatter.format(JcrUtils.getModified(node)) + "</version>");
104                                                 sb.append("<hash>md5:" + JcrxApi.getChecksum(node, JcrxApi.MD5) + "</hash>");
105                                                 if (node.hasProperty(Property.JCR_DESCRIPTION))
106                                                         sb.append("<name>" + node.getProperty(Property.JCR_DESCRIPTION).getString() + "</name>");
107                                                 sb.append("<downloadUrl>" + protocol + "://" + serverName
108                                                                 + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form/"
109                                                                 + node.getPath() + "</downloadUrl>");
110                                                 sb.append("</xform>");
111                                         } else if (node.isNodeType(EntityType.formSet.get())) {
112                                                 sb.append("<xforms-group>");
113                                                 sb.append("<groupId>" + node.getPath() + "</groupId>");
114                                                 sb.append("<name>" + node.getProperty(Property.JCR_TITLE).getString() + "</name>");
115                                                 sb.append("<listUrl>" + protocol + "://" + serverName
116                                                                 + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/formList"
117                                                                 + node.getPath() + "</listUrl>");
118                                                 sb.append("</xforms-group>");
119                                         }
120                                         String str = sb.toString();
121                                         if (!str.equals("")) {
122                                                 if (log.isDebugEnabled())
123                                                         log.debug(str);
124                                                 writer.append(str);
125                                         }
126                                 }
127                         } catch (RepositoryException e) {
128                                 e.printStackTrace();
129                                 // TODO error message
130                                 // resp.sendError(500);
131                                 resp.sendError(503);
132                         } finally {
133                                 Jcr.logout(session);
134                         }
135
136                 } else {
137                         for (OdkForm form : odkForms) {
138                                 StringBuilder sb = new StringBuilder();
139                                 sb.append("<xform>");
140                                 sb.append("<formID>" + form.getFormId() + "</formID>");
141                                 sb.append("<name>" + form.getName() + "</name>");
142                                 sb.append("<version>" + form.getVersion() + "</version>");
143                                 sb.append("<hash>" + form.getHash(null) + "</hash>");
144                                 sb.append("<descriptionText>" + form.getDescription() + "</descriptionText>");
145                                 sb.append("<downloadUrl>" + protocol + "://" + serverName
146                                                 + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form/"
147                                                 + form.getFileName() + "</downloadUrl>");
148                                 sb.append("</xform>");
149                                 String str = sb.toString();
150                                 if (log.isDebugEnabled())
151                                         log.debug(str);
152                                 writer.append(str);
153                         }
154                 }
155                 writer.append("</xforms>");
156         }
157
158         public void addForm(OdkForm odkForm) {
159                 odkForms.add(odkForm);
160         }
161
162         public void removeForm(OdkForm odkForm) {
163                 odkForms.remove(odkForm);
164         }
165
166         public void setRepository(Repository repository) {
167                 this.repository = repository;
168         }
169
170 }