X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=knowledge%2Forg.argeo.support.odk%2Fsrc%2Forg%2Fargeo%2Fsupport%2Fodk%2Fservlet%2FOdkManifestServlet.java;h=3510e06ee154b50e7426c38773f01fe8107cd15c;hb=752a7b2614895002a3d184be166ef4162caf0d05;hp=54620a3a97902c31bdf24d1d02c59dfe8866fb52;hpb=dc577c6d2be1fe28e5c2720ae3cea3d329ec690b;p=gpl%2Fargeo-suite.git diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java index 54620a3..3510e06 100644 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java +++ b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java @@ -1,26 +1,40 @@ package org.argeo.support.odk.servlet; import java.io.IOException; +import java.io.OutputStream; import java.io.Writer; -import java.nio.charset.StandardCharsets; - +import java.nio.charset.Charset; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Property; -import javax.jcr.PropertyIterator; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.Value; import javax.jcr.nodetype.NodeType; +import javax.jcr.query.Query; +import javax.jcr.query.QueryResult; +import javax.jcr.query.Row; +import javax.jcr.query.RowIterator; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.output.NullOutputStream; import org.argeo.cms.servlet.ServletAuthUtils; +import org.argeo.entity.EntityMimeType; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; import org.argeo.support.odk.OrxManifestName; +import org.argeo.util.CsvWriter; import org.argeo.util.DigestUtils; /** Describe additional files. */ @@ -31,7 +45,6 @@ public class OdkManifestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - resp.setContentType("text/xml; charset=utf-8"); resp.setHeader("X-OpenRosa-Version", "1.0"); resp.setDateHeader("Date", System.currentTimeMillis()); @@ -48,35 +61,46 @@ public class OdkManifestServlet extends HttpServlet { try { Node node = session.getNode(pathInfo); if (node.isNodeType(OrxManifestName.manifest.get())) { + resp.setContentType(EntityMimeType.XML.toHttpContentType()); Writer writer = resp.getWriter(); writer.append(""); writer.append(""); NodeIterator nit = node.getNodes(); - while (nit.hasNext()) { + children: while (nit.hasNext()) { Node file = nit.nextNode(); if (file.isNodeType(OrxManifestName.mediaFile.get())) { - writer.append(""); + EntityMimeType mimeType = EntityMimeType + .find(file.getProperty(Property.JCR_MIMETYPE).getString()); + Charset charset = Charset.forName(file.getProperty(Property.JCR_ENCODING).getString()); if (file.isNodeType(NodeType.NT_ADDRESS)) { - Node target = file.getProperty(Property.JCR_ID).getNode(); + Node target; + try { + target = file.getProperty(Property.JCR_ID).getNode(); + } catch (ItemNotFoundException e) { + // TODO remove old manifests + continue children; + } + writer.append(""); writer.append(""); -// writer.append(target.getPath().substring(1) + ".xml"); - writer.append(target.getName() + ".xml"); + // Work around bug in ODK Collect not supporting paths + // writer.append(target.getPath().substring(1) + ".xml"); + writer.append(target.getIdentifier() + "." + mimeType.getDefaultExtension()); writer.append(""); - StringBuilder xml = new StringBuilder(); - xml.append(""); - toSimpleXml(target, xml); - String fileCsum = DigestUtils.digest(DigestUtils.MD5, - xml.toString().getBytes(StandardCharsets.UTF_8)); - writer.append(""); - writer.append("md5sum:" + fileCsum); - writer.append(""); + MessageDigest messageDigest = MessageDigest.getInstance(DigestUtils.MD5); + // TODO cache a temp file ? + try (DigestOutputStream out = new DigestOutputStream(new NullOutputStream(), + messageDigest)) { + writeMediaFile(out, target, mimeType, charset); + writer.append(""); + writer.append("md5sum:" + DigestUtils.encodeHexString(out.getMessageDigest().digest())); + writer.append(""); + } // try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { // session.exportDocumentView(target.getPath(), out, true, false); // String fileCsum = DigestUtils.digest(DigestUtils.MD5, out.toByteArray()); -//// JcrxApi.addChecksum(file, fileCsum); // writer.append(""); // writer.append("md5sum:" + fileCsum); // writer.append(""); @@ -91,15 +115,13 @@ public class OdkManifestServlet extends HttpServlet { writer.append(""); } else if (node.isNodeType(OrxManifestName.mediaFile.get())) { + EntityMimeType mimeType = EntityMimeType.find(node.getProperty(Property.JCR_MIMETYPE).getString()); + Charset charset = Charset.forName(node.getProperty(Property.JCR_ENCODING).getString()); + resp.setContentType(mimeType.toHttpContentType(charset)); if (node.isNodeType(NodeType.NT_ADDRESS)) { Node target = node.getProperty(Property.JCR_ID).getNode(); - StringBuilder xml = new StringBuilder(); - xml.append(""); - toSimpleXml(target, xml); - System.out.println(xml); - resp.getOutputStream().write(xml.toString().getBytes(StandardCharsets.UTF_8)); - resp.flushBuffer(); + writeMediaFile(resp.getOutputStream(), target, mimeType, charset); // try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { // session.exportDocumentView(target.getPath(), out, true, false); // System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8)); @@ -113,47 +135,51 @@ public class OdkManifestServlet extends HttpServlet { } } catch (RepositoryException e) { throw new JcrException(e); + } catch (NoSuchAlgorithmException e) { + throw new ServletException(e); } finally { Jcr.logout(session); } } - private static void toSimpleXml(Node node, StringBuilder sb) throws RepositoryException { - sb.append('<'); - String nodeName = node.getName(); - int colIndex = nodeName.indexOf(':'); - if (colIndex > 0) { - nodeName = nodeName.substring(colIndex + 1); - } - sb.append(nodeName); - PropertyIterator pit = node.getProperties(); - properties: while (pit.hasNext()) { - Property p = pit.nextProperty(); - if (p.isMultiple()) - continue properties; - String propertyName = p.getName(); - int pcolIndex = propertyName.indexOf(':'); - if (pcolIndex > 0) - continue properties; - sb.append(' '); - sb.append(propertyName); - sb.append('='); - sb.append('\"').append(p.getString()).append('\"'); - } - - if (node.hasNodes()) { - sb.append('>'); - NodeIterator children = node.getNodes(); - while (children.hasNext()) { - toSimpleXml(children.nextNode(), sb); + protected void writeMediaFile(OutputStream out, Node target, EntityMimeType mimeType, Charset charset) + throws RepositoryException, IOException { + if (target.isNodeType(NodeType.NT_QUERY)) { + Query query = target.getSession().getWorkspace().getQueryManager().getQuery(target); + QueryResult queryResult = query.execute(); + String[] columnNames = queryResult.getColumnNames(); + if (EntityMimeType.XML.equals(mimeType)) { + } else if (EntityMimeType.CSV.equals(mimeType)) { + CsvWriter csvWriter = new CsvWriter(out, charset); + csvWriter.writeLine(columnNames); + RowIterator rit = queryResult.getRows(); + while (rit.hasNext()) { + Row row = rit.nextRow(); + Value[] values = row.getValues(); + List lst = new ArrayList<>(); + for (Value value : values) { + lst.add(value.getString()); + } + csvWriter.writeLine(lst); + } } - sb.append("'); } else { - sb.append("/>"); + if (EntityMimeType.XML.equals(mimeType)) { + target.getSession().exportDocumentView(target.getPath(), out, true, false); + } else if (EntityMimeType.CSV.equals(mimeType)) { + CsvWriter csvWriter = new CsvWriter(out, charset); + csvWriter.writeLine(new String[] { "name", "label" }); + NodeIterator children = target.getNodes(); + while (children.hasNext()) { + Node child = children.nextNode(); + String label = Jcr.getTitle(child); + csvWriter.writeLine(new String[] { child.getIdentifier(), label }); + } + } + } + } public void setRepository(Repository repository) {