Refactor Argeo APIs
[gpl/argeo-suite.git] / org.argeo.app.servlet.odk / src / org / argeo / app / servlet / odk / OdkManifestServlet.java
index f296170778a381e05cfbf61a52751ee8bb12839a..e5e2de6ebce277a157341a023da1472a8b675695 100644 (file)
@@ -29,14 +29,18 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.io.output.NullOutputStream;
-import org.argeo.app.api.EntityMimeType;
+import org.argeo.api.app.EntityMimeType;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.WGS84PosName;
+import org.argeo.app.geo.GeoShapeUtils;
 import org.argeo.app.odk.OrxManifestName;
 import org.argeo.cms.auth.RemoteAuthUtils;
 import org.argeo.cms.servlet.ServletHttpRequest;
+import org.argeo.cms.servlet.ServletUtils;
+import org.argeo.cms.util.CsvWriter;
+import org.argeo.cms.util.DigestUtils;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
-import org.argeo.util.CsvWriter;
-import org.argeo.util.DigestUtils;
 
 /** Describe additional files. */
 public class OdkManifestServlet extends HttpServlet {
@@ -53,9 +57,9 @@ public class OdkManifestServlet extends HttpServlet {
                if (pathInfo.startsWith("//"))
                        pathInfo = pathInfo.substring(1);
 
-               String serverName = req.getServerName();
-               int serverPort = req.getServerPort();
-               String protocol = serverPort == 443 || req.isSecure() ? "https" : "http";
+               // we force HTTPS since ODK Collect will fail anyhow when sending http
+               // cf. https://forum.getodk.org/t/authentication-for-non-https-schems/32967/4
+               StringBuilder baseServer = ServletUtils.getRequestUrlBase(req, true);
 
                Session session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(req));
 
@@ -98,9 +102,8 @@ public class OdkManifestServlet extends HttpServlet {
                                                                writer.append("md5sum:" + DigestUtils.toHexString(out.getMessageDigest().digest()));
                                                                writer.append("</hash>");
                                                        }
-                                                       writer.append("<downloadUrl>" + protocol + "://" + serverName
-                                                                       + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort)
-                                                                       + "/api/odk/formManifest" + file.getPath() + "</downloadUrl>");
+                                                       writer.append("<downloadUrl>" + baseServer + "/api/odk/formManifest" + file.getPath()
+                                                                       + "</downloadUrl>");
                                                }
                                                writer.append("</mediaFile>");
                                        }
@@ -136,7 +139,14 @@ public class OdkManifestServlet extends HttpServlet {
                if (target.isNodeType(NodeType.NT_QUERY)) {
                        Query query = target.getSession().getWorkspace().getQueryManager().getQuery(target);
                        QueryResult queryResult = query.execute();
-                       String[] columnNames = queryResult.getColumnNames();
+                       List<String> columnNames = new ArrayList<>();
+                       for (String c : queryResult.getColumnNames()) {
+                               columnNames.add(c);
+                       }
+                       // TODO make it more configurable
+                       columnNames.add("display");
+                       columnNames.add("geometry");
+
                        if (EntityMimeType.XML.equals(mimeType)) {
                        } else if (EntityMimeType.CSV.equals(mimeType)) {
                                CsvWriter csvWriter = new CsvWriter(out, charset);
@@ -150,12 +160,24 @@ public class OdkManifestServlet extends HttpServlet {
                                                for (Value value : values) {
                                                        lst.add(value.getString());
                                                }
+                                               // display
+                                               lst.add(row.getValue("name").getString() + " (" + row.getValue("label").getString() + ")");
+                                               Node field = row.getNode("geopoint");
+                                               if (field != null && field.isNodeType(EntityType.geopoint.get())) {
+                                                       double lat = field.getProperty(WGS84PosName.lat.get()).getDouble();
+                                                       double lon = field.getProperty(WGS84PosName.lon.get()).getDouble();
+                                                       double alt = field.hasProperty(WGS84PosName.alt.get())
+                                                                       ? field.getProperty(WGS84PosName.alt.get()).getDouble()
+                                                                       : Double.NaN;
+                                                       String geoshape = GeoShapeUtils.geoPointToGeoShape(lon, lat, alt);
+                                                       lst.add(geoshape);
+                                               }
                                                csvWriter.writeLine(lst);
                                        }
                                } else {
                                        // corner case of an empty initial database
                                        List<String> lst = new ArrayList<>();
-                                       for (int i = 0; i < columnNames.length; i++)
+                                       for (int i = 0; i < columnNames.size(); i++)
                                                lst.add("-");
                                        csvWriter.writeLine(lst);
                                }