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