parse bundledAs and folder info

.. in particular for aggregated URIs as in bag-of-bags-manifest.json
diff --git a/taverna-robundle/src/main/java/org/apache/taverna/robundle/manifest/RDFToManifest.java b/taverna-robundle/src/main/java/org/apache/taverna/robundle/manifest/RDFToManifest.java
index 2976234..f0517eb 100644
--- a/taverna-robundle/src/main/java/org/apache/taverna/robundle/manifest/RDFToManifest.java
+++ b/taverna-robundle/src/main/java/org/apache/taverna/robundle/manifest/RDFToManifest.java
@@ -29,7 +29,9 @@
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -93,8 +95,9 @@
 	private static final String PROV_AQ_RDF = "/ontologies/prov-aq.rdf";
 	private static final String PROV_O = "http://www.w3.org/ns/prov-o#";
 	private static final String PROV_O_RDF = "/ontologies/prov-o.rdf";
-	@SuppressWarnings("unused")
+
 	private static final String RO = "http://purl.org/wf4ever/ro#";
+	private static final String RO_OWL = "/ontologies/ro.owl";
 
 	private static <T> ClosableIterable<T> iterate(ExtendedIterator<T> iterator) {
 		return new ClosableIterable<T>(iterator);
@@ -167,6 +170,12 @@
 
 	private ObjectProperty alternateOf;
 
+	private ObjectProperty bundledAs;
+
+	private DatatypeProperty entryName;
+
+	private OntModel ro;
+
 	public RDFToManifest() {
 		loadOntologies();
 	}
@@ -258,7 +267,8 @@
 		hasProxy = ontModel.getObjectProperty(BUNDLE + "hasProxy");
 		hasAnnotation = ontModel.getObjectProperty(BUNDLE + "hasAnnotation");
 		inFolder = ontModel.getObjectProperty(BUNDLE + "inFolder");
-		checkNotNull(hasProxy, hasAnnotation, inFolder);
+		bundledAs = ontModel.getObjectProperty(BUNDLE + "bundledAs");
+		checkNotNull(hasProxy, hasAnnotation, inFolder, bundledAs);
 		bundle = ontModel;
 	}
 
@@ -315,6 +325,7 @@
 		loadPAV();
 		loadPROVAQ();
 		loadOA();
+		loadRO();
 		loadBundle();
 	}
 
@@ -394,9 +405,13 @@
 		prov = ontModel;
 	}
 
-	@SuppressWarnings("deprecation")
-	private static void setPathProxy(PathMetadata meta, URI proxy) {
-		meta.setProxy(proxy);
+	protected synchronized void loadRO() {
+		if (ro != null)
+			return;
+		OntModel ontModel = loadOntologyFromClasspath(RO_OWL, RO);
+		entryName = ontModel.getDatatypeProperty(RO + "entryName");
+		checkNotNull(ontModel, entryName);
+		ro = ontModel;
 	}
 
 	public void readTo(InputStream manifestResourceAsStream, Manifest manifest,
@@ -511,11 +526,14 @@
 			PathMetadata meta = manifest.getAggregation(relativizeFromBase(
 					uriStr, root));
 
-			// hasProxy
 			Set<Individual> proxies = listObjectProperties(aggrResource,
 					hasProxy);
+			if (proxies.isEmpty()) {
+				// FIXME: Jena does not follow OWL properties paths from hasProxy
+				proxies = listObjectProperties(aggrResource, bundledAs);
+			}
 			if (!proxies.isEmpty()) {
-				// We can only deal with the first one
+				// Should really only be one anyway
 				Individual proxy = proxies.iterator().next();
 
 				String proxyUri = null;
@@ -525,9 +543,28 @@
 					proxyUri = proxy.getSameAs().getURI();
 				}
 
+				Proxy proxyInManifest = meta.getOrCreateBundledAs();
 				if (proxyUri != null) {
-					setPathProxy(meta, relativizeFromBase(proxyUri, root));
+					proxyInManifest.setURI(relativizeFromBase(proxyUri, root));
 				}
+
+				RDFNode eName = proxy.getPropertyValue(entryName);
+				if (eName != null && eName.isLiteral()) {
+					proxyInManifest.setFilename(eName.asLiteral().getString());;
+				}
+				RDFNode folder = proxy.getPropertyValue(inFolder);
+				if (folder != null && folder.isURIResource()) {
+					URI folderUri = URI.create(folder.asResource().getURI());
+					if (! folderUri.resolve("/").equals(manifest.getBaseURI())) {
+						logger.warning("Invalid bundledAs folder, outside base URI of RO: " + folderUri);
+						continue;
+					}
+					Path folderPath = Paths.get(folderUri);
+					// Note: folder need NOT exist in zip file, so we don't need to do
+					// Files.createDirectories(folderPath);
+					proxyInManifest.setFolder(folderPath);
+				}
+
 			}
 
 			// createdBy
diff --git a/taverna-robundle/src/test/java/org/apache/taverna/robundle/manifest/TestRDFToManifest.java b/taverna-robundle/src/test/java/org/apache/taverna/robundle/manifest/TestRDFToManifest.java
index 7ebc5ad..12fd543 100644
--- a/taverna-robundle/src/test/java/org/apache/taverna/robundle/manifest/TestRDFToManifest.java
+++ b/taverna-robundle/src/test/java/org/apache/taverna/robundle/manifest/TestRDFToManifest.java
@@ -79,7 +79,6 @@
 					author.getUri());
 			assertEquals(URI.create("https://orcid.org/0000-0001-9842-9718"),
 					author.getOrcid());
-
 			
 			// FIXME: The BDBag got this wrong and used "uri" instead of "content", and so
 			// data/README accidentally became the ID of the annotation.
@@ -108,11 +107,11 @@
 
 			
 			Proxy bundledAs = a1.getBundledAs();
-			// FIXME: Why is there no bundledAs?
-//			assertNotNull(bundledAs);
-//			assertEquals(ro.getPath("data"), 
-//					bundledAs.getFolder());			
-//			assertEquals("bag1.zip", a1.getBundledAs().getFilename());
+			assertNotNull(bundledAs);
+			// FIXME: Why is there no bundledAs data?
+			assertEquals(ro.getPath("data"), 
+					bundledAs.getFolder());			
+			assertEquals("bag1.zip", a1.getBundledAs().getFilename());
 
 			// TODO: Enable fetching based on bundledAs URI?
 			//ro.getRoot().resolve("data/bag1.zip")