X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=knowledge%2Forg.argeo.support.odk%2Fsrc%2Forg%2Fargeo%2Fsupport%2Fodk%2FOdkUtils.java;fp=knowledge%2Forg.argeo.support.odk%2Fsrc%2Forg%2Fargeo%2Fsupport%2Fodk%2FOdkUtils.java;h=0e73295b6f3d6c3f1ab7744d3b9bf9290160781f;hp=4c106a29b2a7dfd007ce2cb6cead390a34a09ce4;hb=384e41caf78222c53e5cf365bb93310e5b28462b;hpb=65030067b0125a4399f58b897b78debded2984d3 diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java index 4c106a2..0e73295 100644 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java +++ b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java @@ -3,9 +3,13 @@ package org.argeo.support.odk; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; import javax.jcr.ImportUUIDBehavior; import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; @@ -13,6 +17,7 @@ import javax.jcr.nodetype.NodeType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.entity.EntityType; +import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrUtils; import org.argeo.jcr.JcrxApi; import org.argeo.util.DigestUtils; @@ -25,9 +30,11 @@ public class OdkUtils { if (!formBase.isNodeType(EntityType.formSet.get())) throw new IllegalArgumentException( "Parent path " + formBase + " must be of type " + EntityType.formSet.get()); - Node form = JcrUtils.getOrAdd(formBase, name, OrxListType.xform.get(), NodeType.MIX_SIMPLE_VERSIONABLE); + Node form = JcrUtils.getOrAdd(formBase, name, OrxListName.xform.get(), NodeType.MIX_VERSIONABLE); String previousCsum = JcrxApi.getChecksum(form, JcrxApi.MD5); + String previousFormId = Jcr.get(form, OrxListName.formID.get()); + String previousFormVersion = Jcr.get(form, OrxListName.version.get()); Session s = formBase.getSession(); // String res = "/odk/apafSession.odk.xml"; @@ -35,6 +42,65 @@ public class OdkUtils { s.importXML(form.getPath(), in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); // } + // manage instances + // NodeIterator instances = + // form.getNodes("h:html/h:head/xforms:model/xforms:instance"); + NodeIterator instances = form.getNode("h:html/h:head/xforms:model").getNodes("xforms:instance"); + Node primaryInstance = null; + while (instances.hasNext()) { + Node instance = instances.nextNode(); + if (primaryInstance == null) { + primaryInstance = instance; + } else {// secondary instances + String instanceId = instance.getProperty("id").getString(); + URI instanceUri = null; + if (instance.hasProperty("src")) + try { + instanceUri = new URI(instance.getProperty("src").getString()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Instance " + instanceId + " has a badly formatted URI", e); + } + if (instanceUri != null) { + if ("jr".equals(instanceUri.getScheme())) { + String type = instanceUri.getHost(); + if ("file".equals(type)) { + Node manifest = JcrUtils.getOrAdd(form, OrxManifestName.manifest.name(), + OrxManifestName.manifest.get()); + Node file = JcrUtils.getOrAdd(manifest, instanceId); + String path = instanceUri.getPath(); + if (!path.endsWith(".xml")) + throw new IllegalArgumentException("File uri " + instanceUri + " must end with .xml"); + path = path.substring(0, path.length() - ".xml".length()); + Node target = file.getSession().getNode(path); + if (target.isNodeType(NodeType.MIX_REFERENCEABLE)) { + file.setProperty(Property.JCR_ID, target); + if (file.hasProperty(Property.JCR_PATH)) + file.getProperty(Property.JCR_PATH).remove(); + } else { + file.setProperty(Property.JCR_PATH, target.getPath()); + if (file.hasProperty(Property.JCR_ID)) + file.getProperty(Property.JCR_ID).remove(); + } + } + } + } + } + } + + if (primaryInstance == null) + throw new IllegalArgumentException("No primary instance found in " + form); + if (!primaryInstance.hasNodes()) + throw new IllegalArgumentException("No data found in primary instance of " + form); + NodeIterator primaryInstanceChildren = primaryInstance.getNodes(); + Node data = primaryInstanceChildren.nextNode(); + if (primaryInstanceChildren.hasNext()) + throw new IllegalArgumentException("More than one data found in primary instance of " + form); + String formId = data.getProperty("id").getString(); + if (previousFormId != null && !formId.equals(previousFormId)) + log.warn("Form id of " + form + " changed from " + previousFormId + " to " + formId); + form.setProperty(OrxListName.formID.get(), formId); + String formVersion = data.getProperty("version").getString(); + if (previousCsum == null)// save before checksuming s.save(); String newCsum; @@ -45,6 +111,7 @@ public class OdkUtils { if (previousCsum == null) { JcrxApi.addChecksum(form, newCsum); JcrUtils.updateLastModified(form); + form.setProperty(OrxListName.version.get(), formVersion); s.save(); s.getWorkspace().getVersionManager().checkpoint(form.getPath()); if (log.isDebugEnabled()) @@ -57,6 +124,12 @@ public class OdkUtils { log.debug("Unmodified form " + form); return; } else { + if (formVersion.equals(previousFormVersion)) { + s.refresh(false); + throw new IllegalArgumentException("Form " + form + " has been changed but version " + formVersion + + " has not been changed, discarding changes..."); + } + form.setProperty(OrxListName.version.get(), formVersion); JcrxApi.addChecksum(form, newCsum); JcrUtils.updateLastModified(form); s.save();