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