RDFToManifest { public void readTo(InputStream manifestResourceAsStream, Manifest manifest, URI manifestResourceBaseURI) throws IOException, RiotException { OntModel model = new RDFToManifest().getOntModel(); model.add(jsonLdAsJenaModel(manifestResourceAsStream, manifestResourceBaseURI)); URI root = manifestResourceBaseURI.resolve("/"); Individual researchObj = findRO(model, root); if (researchObj == null) throw new IOException("root ResearchObject not found - " + "Not a valid RO Bundle manifest"); for (Individual manifestResource : listObjectProperties(researchObj, ore.isDescribedBy)) { String uriStr = manifestResource.getURI(); if (uriStr == null) { logger.warning("Skipping manifest without URI: " + manifestResource); continue; } Path path = manifest.getBundle().getFileSystem().provider() .getPath(URI.create(uriStr)); manifest.getManifest().add(path); } List<Agent> creators = getAgents(root, researchObj, pav.createdBy); if (!creators.isEmpty()) { manifest.setCreatedBy(creators.get(0)); if (creators.size() > 1) { logger.warning("Ignoring additional createdBy agents"); } } RDFNode created = researchObj.getPropertyValue(pav.createdOn); manifest.setCreatedOn(literalAsFileTime(created)); List<Path> history = new ArrayList<Path> (); for (Individual histItem : listObjectProperties (researchObj, prov.AQ.has_provenance)) { history.add(Bundles.uriToBundlePath(manifest.getBundle(), relativizeFromBase(histItem.getURI(), root))); } manifest.setHistory(history); List<Agent> authors = getAgents(root, researchObj, pav.authoredBy); if (!authors.isEmpty()) { manifest.setAuthoredBy(authors); } RDFNode authored = researchObj.getPropertyValue(pav.authoredOn); manifest.setAuthoredOn(literalAsFileTime(authored)); RDFNode retrievedNode = researchObj.getPropertyValue(pav.retrievedFrom); if (retrievedNode != null) { try { manifest.setRetrievedFrom(new URI(retrievedNode.asResource().getURI())); } catch (URISyntaxException ex) { logger.log(Level.WARNING, "Error creating URI for retrievedFrom: " + retrievedNode.asResource().getURI(), ex); } } List<Agent> retrievers = getAgents(root, researchObj, pav.retrievedBy); if (!retrievers.isEmpty()) { manifest.setRetrievedBy(retrievers.get(0)); if (retrievers.size() > 1) { logger.warning("Ignoring additional retrievedBy agents"); } } RDFNode retrieved = researchObj.getPropertyValue(pav.retrievedOn); manifest.setRetrievedOn(literalAsFileTime(retrieved)); for (Individual standard : listObjectProperties(researchObj, ro.conformsTo)) { if (standard.isURIResource()) { URI uri; try { uri = new URI(standard.getURI()); } catch (URISyntaxException ex) { logger.log(Level.WARNING, "Invalid URI for conformsTo: " + standard, ex); continue; } if (! manifest.getConformsTo().contains(uri)) { manifest.getConformsTo().add(uri); } } } for (Individual aggrResource : listObjectProperties(researchObj, ore.aggregates)) { String uriStr = aggrResource.getURI(); if (uriStr == null) { logger.warning("Skipping aggregation without URI: " + aggrResource); continue; } PathMetadata meta = manifest.getAggregation(relativizeFromBase( uriStr, root)); Set<Individual> proxies = listObjectProperties(aggrResource, bundle.hasProxy); if (proxies.isEmpty()) { proxies = listObjectProperties(aggrResource, bundle.bundledAs); } if (!proxies.isEmpty()) { Individual proxy = proxies.iterator().next(); String proxyUri = null; if (proxy.getURI() != null) { proxyUri = proxy.getURI(); } else if (proxy.getSameAs() != null) { proxyUri = proxy.getSameAs().getURI(); } Proxy proxyInManifest = meta.getOrCreateBundledAs(); if (proxyUri != null) { proxyInManifest.setURI(relativizeFromBase(proxyUri, root)); } RDFNode eName = proxy.getPropertyValue(ro.entryName); if (eName != null && eName.isLiteral()) { proxyInManifest.setFilename(eName.asLiteral().getString());; } RDFNode folder = proxy.getPropertyValue(bundle.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); proxyInManifest.setFolder(folderPath); } } creators = getAgents(root, aggrResource, pav.createdBy); if (!creators.isEmpty()) { meta.setCreatedBy(creators.get(0)); if (creators.size() > 1) { logger.warning("Ignoring additional createdBy agents for " + meta); } } meta.setCreatedOn(literalAsFileTime(aggrResource .getPropertyValue(pav.createdOn))); RDFNode retrievedAggrNode = aggrResource.getPropertyValue(pav.retrievedFrom); if (retrievedAggrNode != null) { try { meta.setRetrievedFrom(new URI(retrievedAggrNode.asResource().getURI())); } catch (URISyntaxException ex) { logger.log(Level.WARNING, "Error creating URI for retrievedFrom: " + retrievedAggrNode.asResource().getURI(), ex); } } List<Agent> retrieversAggr = getAgents(root, aggrResource, pav.retrievedBy); if (!retrieversAggr.isEmpty()) { meta.setRetrievedBy(retrieversAggr.get(0)); if (retrieversAggr.size() > 1) { logger.warning("Ignoring additional retrievedBy agents for " + meta); } } RDFNode retrievedAggr = aggrResource.getPropertyValue(pav.retrievedOn); meta.setRetrievedOn(literalAsFileTime(retrievedAggr)); for (Individual standard : listObjectProperties(aggrResource, ro.conformsTo)) { if (standard.getURI() != null) { meta.setConformsTo(relativizeFromBase(standard.getURI(), root)); } } RDFNode mediaType = aggrResource.getPropertyValue(DCTerms.format); if (mediaType != null && mediaType.isLiteral()) { meta.setMediatype(mediaType.asLiteral().getLexicalForm()); } } for (Individual ann : listObjectProperties(researchObj, bundle.hasAnnotation)) { for (Individual body : listObjectProperties( model.getOntResource(ann), oa.hasBody)) { if (! body.isURIResource()) { logger.warning("Can't find annotation body for anonymous " + body); continue; } PathAnnotation pathAnn = new PathAnnotation(); pathAnn.setContent(relativizeFromBase(body.getURI(), root)); if (ann.getURI() != null) pathAnn.setUri(relativizeFromBase(ann.getURI(), root)); else if (ann.getSameAs() != null && ann.getSameAs().getURI() != null) pathAnn.setUri(relativizeFromBase(ann.getSameAs().getURI(), root)); for (Individual target : listObjectProperties(ann, oa.hasTarget)) if (target.getURI() != null) pathAnn.getAboutList().add( relativizeFromBase(target.getURI(), root)); manifest.getAnnotations().add(pathAnn); } } }  void readTo(InputStream manifestResourceAsStream, Manifest manifest,
			URI manifestResourceBaseURI);  }
@Test public void manifestFromSpec() throws Exception { try (Bundle ro = Bundles.createBundle(); InputStream json = getClass().getResourceAsStream("/manifest.json")) { assertNotNull("Can't find manifest.json", json); Manifest manifest = new Manifest(ro); URI baseURI = ro.getPath(".ro/manifest.json").toUri(); new RDFToManifest().readTo(json, manifest, baseURI); assertEquals(Arrays.asList(ro.getPath("/.ro/manifest.json")), manifest.getManifest()); assertEquals(URI.create("http: manifest.getRetrievedFrom()); assertEquals(Instant.parse("2013-03-05T17:29:03Z"), manifest.getRetrievedOn().toInstant()); Agent retrievedBy = manifest.getRetrievedBy(); assertEquals("John P. Smith", retrievedBy.getName()); assertEquals(URI.create("http: retrievedBy.getUri()); assertEquals(URI.create("http: retrievedBy.getOrcid()); assertEquals(Instant.parse("2013-03-05T17:29:03Z"), manifest.getCreatedOn().toInstant()); Agent createdBy = manifest.getCreatedBy(); assertEquals("Alice W. Land", createdBy.getName()); assertEquals(URI.create("http: createdBy.getUri()); assertEquals(URI.create("http: createdBy.getOrcid()); assertEquals(Arrays.asList(ro.getPath(".ro/evolution.ttl")), manifest.getHistory()); Set<URI> aggregatedUris = manifest.getAggregates().stream() .map(PathMetadata::getUri) .collect(Collectors.toSet()); assertTrue(aggregatedUris.contains(URI.create("/folder/soup.jpeg"))); assertTrue(aggregatedUris.contains(URI.create("http: assertTrue(aggregatedUris.contains(URI.create("/README.txt"))); assertTrue(aggregatedUris.contains(URI.create("http: assertEquals(4, manifest.getAggregates().size()); PathMetadata soup = manifest.getAggregation(ro.getPath("folder/soup.jpeg")); assertEquals(URI.create("http: soup.getRetrievedFrom()); assertEquals(Instant.parse("2013-03-05T17:29:04Z"), soup.getRetrievedOn().toInstant()); Agent peter = soup.getRetrievedBy(); assertEquals("Peter L. Jones", peter.getName()); assertEquals(URI.create("http: peter.getUri()); assertEquals(URI.create("http: peter.getOrcid()); PathMetadata blog = manifest.getAggregation(URI.create("http: assertNull(blog.getRetrievedFrom()); assertNull(blog.getRetrievedBy()); assertNull(blog.getRetrievedOn()); assertNull(blog.getCreatedBy()); assertNull(blog.getCreatedOn()); assertNull(blog.getBundledAs()); PathMetadata readme = manifest.getAggregation(ro.getPath("/README.txt")); assertEquals("text/plain; charset=\"utf-8\"", readme.getMediatype()); assertEquals("Bob Builder", readme.getCreatedBy().getName()); assertEquals(URI.create("http: PathMetadata comments = manifest.getAggregation(URI.create("http: Proxy bundledAs = comments.getBundledAs(); assertEquals(URI.create("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644"), bundledAs.getURI()); assertEquals(ro.getPath("folder"), bundledAs.getFolder()); assertEquals("external.txt", bundledAs.getFilename()); assertEquals(3, manifest.getAnnotations().size()); PathAnnotation ann1 = manifest.getAnnotation(URI.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf")).get(); assertEquals(URI.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf"), ann1.getUri()); assertEquals(URI.create("/folder/soup.jpeg"), ann1.getAbout()); assertEquals(URI.create("annotations/soup-properties.ttl"), ann1.getContent()); PathAnnotation ann2 = manifest.getAnnotations(URI.create("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644")).get(0); assertEquals(URI.create("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644"), ann2.getAbout()); assertEquals(URI.create("http: ann2.getContent()); PathAnnotation ann3 = manifest.getAnnotations(ro.getRoot()).get(0); assertEquals(ann3, manifest.getAnnotations(URI.create("/")).get(0)); assertEquals(ann3, manifest.getAnnotations(ro.getRoot().toUri()).get(0)); assertEquals(ann3, manifest.getAnnotations(URI.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf")).get(0)); assertEquals(URI.create("annotations/a-meta-annotation-in-this-ro.txt"), ann3.getContent()); assertEquals(2, ann3.getAboutList().size()); assertTrue(ann3.getAboutList().contains(URI.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf"))); assertTrue(ann3.getAboutList().contains(URI.create("/"))); } }
@Test public void multipleConformsTo() throws Exception { try (Bundle ro = Bundles.createBundle(); InputStream json = getClass().getResourceAsStream("/bag-of-bags-manifest.json")) { assertNotNull("Can't find bag-of-bags-manifest.json", json); Manifest manifest = new Manifest(ro); URI baseURI = ro.getPath("metadata/manifest.json").toUri(); new RDFToManifest().readTo(json, manifest, baseURI); assertEquals(URI.create("https: manifest.getCreatedBy().getUri()); assertEquals(1, manifest.getAuthoredBy().size()); Agent author = manifest.getAuthoredBy().get(0); assertEquals("Stian Soiland-Reyes", author.getName()); assertEquals(URI.create("mbox:stain@apache.org"), author.getUri()); assertEquals(URI.create("https: author.getOrcid()); assertEquals(1, manifest.getAggregates().size()); PathMetadata a1 = manifest.getAggregates().get(0); URI uri = URI.create("http: assertEquals(uri, a1.getUri()); assertEquals(a1, manifest.getAggregation(uri)); assertEquals(URI.create("https: a1.getConformsTo()); Proxy bundledAs = a1.getBundledAs(); assertNotNull(bundledAs); assertEquals(ro.getPath("data"), bundledAs.getFolder()); assertEquals("bag1.zip", a1.getBundledAs().getFilename()); } }