blob: 9754cda0de08a8abff5e20f784875d14cb1f4893 [file] [log] [blame]
package org.apache.taverna.robundle.manifest;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import org.apache.taverna.robundle.Bundle;
import org.apache.taverna.robundle.Bundles;
import org.junit.Test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestManifestJSON {
@Test
public void testHistory () throws IOException
{
Path tmpBundle = Files.createTempFile ("testbundle", "history");
// create history
try (Bundle bundle = Bundles.createBundle())
{
Bundles.closeAndSaveBundle (bundle, tmpBundle);
}
catch (IOException e)
{
fail ("failed to create bundle for history test: " + e.getMessage ());
}
// make sure it doesn't fail if there is no history
try (Bundle bundle = Bundles.openBundle (tmpBundle))
{
Manifest manifest = bundle.getManifest();
Path evolutionPath = bundle.getPath(".ro/evolution.ttl");
assertFalse ("did not expect a history file", Files.exists (evolutionPath));
assertEquals ("did not expect a history", 0, manifest.getHistory ().size ());
Files.createDirectories(evolutionPath.getParent());
Bundles.setStringValue(
evolutionPath,
"<manifest.json> < http://purl.org/pav/retrievedFrom> "
+ "<http://wf4ever.github.io/ro/bundle/2013-05-21/example/.ro/manifest.json> .");
manifest.getHistory().add(evolutionPath);
assertTrue ("expected a history file", Files.exists (evolutionPath));
assertTrue ("expected a history", manifest.getHistory ().size () > 0);
Bundles.closeBundle (bundle);
}
catch (IOException e)
{
fail ("failed to read bundle for history test: " + e.getMessage ());
}
// check if history is still there
try (Bundle bundle = Bundles.openBundleReadOnly (tmpBundle))
{
Manifest manifest = bundle.getManifest();
Path evolutionPath = bundle.getPath(".ro/evolution.ttl");
assertTrue ("expected a history file", Files.exists (evolutionPath));
assertEquals ("expected exactly one history", 1, manifest.getHistory ().size ());
Bundles.closeBundle (bundle);
}
catch (IOException e)
{
fail ("failed to read bundle for history test: " + e.getMessage ());
}
Files.delete (tmpBundle);
}
@Test
public void createBundle() throws Exception {
// Create bundle as in Example 3 of the specification
// http://wf4ever.github.io/ro/bundle/2013-05-21/
try (Bundle bundle = Bundles.createBundle()) {
Calendar createdOnCal = Calendar.getInstance(
TimeZone.getTimeZone("Z"), Locale.ENGLISH);
// "2013-03-05T17:29:03Z"
// Remember months are 0-based in java.util.Calendar!
createdOnCal.set(2013, 3 - 1, 5, 17, 29, 03);
createdOnCal.set(Calendar.MILLISECOND, 0);
FileTime createdOn = FileTime.fromMillis(createdOnCal
.getTimeInMillis());
Manifest manifest = bundle.getManifest();
manifest.setCreatedOn(createdOn);
Agent createdBy = new Agent("Alice W. Land");
createdBy.setUri(URI.create("http://example.com/foaf#alice"));
createdBy.setOrcid(URI
.create("http://orcid.org/0000-0002-1825-0097"));
manifest.setCreatedBy(createdBy);
Path evolutionPath = bundle.getPath(".ro/evolution.ttl");
Files.createDirectories(evolutionPath.getParent());
Bundles.setStringValue(
evolutionPath,
"<manifest.json> < http://purl.org/pav/retrievedFrom> "
+ "<http://wf4ever.github.io/ro/bundle/2013-05-21/example/.ro/manifest.json> .");
manifest.getHistory().add(evolutionPath);
Path jpeg = bundle.getPath("folder/soup.jpeg");
Files.createDirectory(jpeg.getParent());
Files.createFile(jpeg);
// register in manifest first
bundle.getManifest().getAggregation(jpeg);
URI blog = URI.create("http://example.com/blog/");
bundle.getManifest().getAggregation(blog);
Path readme = bundle.getPath("README.txt");
Files.createFile(readme);
PathMetadata readmeMeta = bundle.getManifest().getAggregation(
readme);
readmeMeta.setMediatype("text/plain; charset=\"utf-8\"");
Agent readmeCreatedby = new Agent("Bob Builder");
readmeCreatedby.setUri(URI.create("http://example.com/foaf#bob"));
readmeMeta.setCreatedBy(readmeCreatedby);
// 2013-02-12T19:37:32.939Z
createdOnCal.set(2013, 2 - 1, 12, 19, 37, 32);
createdOnCal.set(Calendar.MILLISECOND, 939);
createdOn = FileTime.fromMillis(createdOnCal.getTimeInMillis());
Files.setLastModifiedTime(readme, createdOn);
readmeMeta.setCreatedOn(createdOn);
PathMetadata comments = bundle.getManifest().getAggregation(
URI.create("http://example.com/comments.txt"));
comments.getOrCreateBundledAs()
.setURI(URI
.create("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644"));
comments.getOrCreateBundledAs().setFolder(
bundle.getPath("/folder/"));
comments.getOrCreateBundledAs().setFilename("external.txt");
PathAnnotation jpegAnn = new PathAnnotation();
jpegAnn.setAbout(jpeg);
Path soupProps = Bundles.getAnnotations(bundle).resolve(
"soup-properties.ttl");
Bundles.setStringValue(soupProps,
"</folder/soup.jpeg> <http://xmlns.com/foaf/0.1/depicts> "
+ "<http://example.com/menu/tomato-soup> .");
jpegAnn.setContent(soupProps);
// jpegAnn.setContent(URI.create("annotations/soup-properties.ttl"));
jpegAnn.setUri(URI
.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf"));
manifest.getAnnotations().add(jpegAnn);
PathAnnotation proxyAnn = new PathAnnotation();
proxyAnn.setAbout(comments.getBundledAs().getURI());
proxyAnn.setContent(URI
.create("http://example.com/blog/they-aggregated-our-file"));
manifest.getAnnotations().add(proxyAnn);
Path metaAnn = Bundles.getAnnotations(bundle).resolve(
"a-meta-annotation-in-this-ro.txt");
Bundles.setStringValue(metaAnn,
"This bundle contains an annotation about /folder/soup.jpeg");
PathAnnotation metaAnnotation = new PathAnnotation();
metaAnnotation.setAbout(bundle.getRoot());
metaAnnotation
.getAboutList()
.add(URI.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf"));
metaAnnotation.setContent(metaAnn);
manifest.getAnnotations().add(metaAnnotation);
Path jsonPath = bundle.getManifest().writeAsJsonLD();
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = Bundles.getStringValue(jsonPath);
//System.out.println(jsonStr);
JsonNode json = objectMapper.readTree(jsonStr);
checkManifestJson(json);
}
}
public void checkManifestJson(JsonNode json) {
JsonNode context = json.get("@context");
assertNotNull("Could not find @context", context);
assertTrue("@context SHOULD be an array", context.isArray());
assertTrue("@context SHOULD include a context", context.size() > 0);
JsonNode lastContext = context.get(context.size() - 1);
assertEquals(
"@context SHOULD include https://w3id.org/bundle/context as last item",
"https://w3id.org/bundle/context", lastContext.asText());
assertEquals("/", json.get("id").asText());
JsonNode manifest = json.get("manifest");
if (manifest.isValueNode()) {
assertEquals(
"manifest SHOULD be literal value \"manifest.json\" or list",
"manifest.json", manifest.asText());
} else {
assertTrue("manifest is neither literal or list",
manifest.isArray());
boolean found = false;
for (JsonNode n : manifest) {
found = n.asText().equals("manifest.json");
if (found) {
break;
}
}
;
assertTrue("Could not find 'manifest.json' in 'manifest' list: "
+ manifest, found);
}
assertEquals("2013-03-05T17:29:03Z", json.get("createdOn").asText());
JsonNode createdBy = json.get("createdBy");
assertNotNull("Could not find createdBy", createdBy);
assertEquals("http://example.com/foaf#alice", createdBy.get("uri")
.asText());
assertEquals("http://orcid.org/0000-0002-1825-0097",
createdBy.get("orcid").asText());
assertEquals("Alice W. Land", createdBy.get("name").asText());
JsonNode history = json.get("history");
if (history.isValueNode()) {
assertEquals("evolution.ttl", history.asText());
} else {
assertEquals("evolution.ttl", history.get(0).asText());
}
JsonNode aggregates = json.get("aggregates");
assertTrue("aggregates not a list", aggregates.isArray());
JsonNode soup = aggregates.get(0);
if (soup.isValueNode()) {
assertEquals("/folder/soup.jpeg", soup.asText());
} else {
assertEquals("/folder/soup.jpeg", soup.get("uri").asText());
}
JsonNode blog = aggregates.get(1);
if (blog.isValueNode()) {
assertEquals("http://example.com/blog/", blog.asText());
} else {
assertEquals("http://example.com/blog/", blog.get("uri").asText());
}
JsonNode readme = aggregates.get(2);
assertEquals("/README.txt", readme.get("uri").asText());
assertEquals("text/plain; charset=\"utf-8\"", readme.get("mediatype").asText());
assertEquals("2013-02-12T19:37:32.939Z", readme.get("createdOn")
.asText());
JsonNode readmeCreatedBy = readme.get("createdBy");
assertEquals("http://example.com/foaf#bob", readmeCreatedBy.get("uri")
.asText());
assertEquals("Bob Builder", readmeCreatedBy.get("name").asText());
JsonNode comments = aggregates.get(3);
assertEquals("http://example.com/comments.txt", comments.get("uri")
.asText());
JsonNode bundledAs = comments.get("bundledAs");
assertEquals("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644", bundledAs
.get("uri").asText());
assertEquals("/folder/", bundledAs.get("folder").asText());
assertEquals("external.txt", bundledAs.get("filename").asText());
JsonNode annotations = json.get("annotations");
assertTrue("annotations MUST be a list", annotations.isArray());
JsonNode ann0 = annotations.get(0);
assertEquals("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf",
ann0.get("uri").asText());
assertEquals("/folder/soup.jpeg", ann0.get("about").asText());
assertEquals("annotations/soup-properties.ttl", ann0.get("content")
.asText());
JsonNode ann1 = annotations.get(1);
assertNull(ann1.get("annotation"));
assertEquals("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644",
ann1.get("about").asText());
assertEquals("http://example.com/blog/they-aggregated-our-file", ann1
.get("content").asText());
JsonNode ann2 = annotations.get(2);
assertNull(ann2.get("annotation"));
JsonNode about = ann2.get("about");
assertTrue("about was not a list", about.isArray());
assertEquals("/", about.get(0).asText());
assertEquals("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf", about
.get(1).asText());
assertEquals("annotations/a-meta-annotation-in-this-ro.txt",
ann2.get("content").asText());
}
@Test
public void checkJsonFromSpec() throws Exception {
// Verify that our test confirms the existing spec example
ObjectMapper objectMapper = new ObjectMapper();
JsonNode json = objectMapper.readTree(getClass().getResource(
"/manifest.json"));
checkManifestJson(json);
}
}