Added resolve()
Adapted from
org.apache.taverna.platform.execution.impl.local.T2ReferenceConverter
diff --git a/taverna-databundle/src/main/java/org/apache/taverna/databundle/DataBundles.java b/taverna-databundle/src/main/java/org/apache/taverna/databundle/DataBundles.java
index c491d13..0598e10 100644
--- a/taverna-databundle/src/main/java/org/apache/taverna/databundle/DataBundles.java
+++ b/taverna-databundle/src/main/java/org/apache/taverna/databundle/DataBundles.java
@@ -1,6 +1,4 @@
-package org.apache.taverna.databundle;
/*
- *
* 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
@@ -18,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*
-*/
-
+ */
+package org.apache.taverna.databundle;
import static java.nio.file.Files.createDirectories;
import static java.nio.file.Files.delete;
@@ -33,10 +31,12 @@
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
+import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.DirectoryIteratorException;
import java.nio.file.DirectoryStream;
@@ -49,15 +49,15 @@
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.UUID;
-import java.util.logging.Logger;
import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.taverna.robundle.Bundle;
+import org.apache.taverna.robundle.Bundles;
import org.apache.taverna.scufl2.api.container.WorkflowBundle;
import org.apache.taverna.scufl2.api.io.ReaderException;
import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
import org.apache.taverna.scufl2.api.io.WriterException;
-import org.apache.taverna.robundle.Bundle;
-import org.apache.taverna.robundle.Bundles;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -68,7 +68,6 @@
* The style of using this class is similar to that of {@link Files}. In fact, a
* data bundle is implemented as a set of {@link Path}s.
*
- * @author Stian Soiland-Reyes
*/
public class DataBundles extends Bundles {
private static final class OBJECT_MAPPER {
@@ -440,6 +439,73 @@
throw ex.getCause();
}
}
+
+ /**
+ * Deeply resolve a {@link Path} to JVM objects.
+ * <p>
+ * This method is intended for use with a particular input/output port from
+ * {@link #getPorts(Path)} or {@link #getPort(Path, String)}.
+ * <p>
+ * If the path is <code>null</code> or {@link #isMissing(Path)},
+ * <code>null</code> is returned.
+ * <p>
+ * If the path {@link #isValue(Path)}, its {@link #getStringValue(Path)} is
+ * returned (assuming an UTF-8 encoding). NOTE: Binary formats (e.g. PNG)
+ * will NOT be represented correctly as such a String and should be read
+ * directly with
+ * {@link Files#newInputStream(Path, java.nio.file.OpenOption...)}.
+ * <p>
+ * If the path {@link #isError(Path)}, the corresponding
+ * {@link ErrorDocument} is returned.
+ * <p>
+ * If the path {@link #isReference(Path)}, either a {@link File} or a
+ * {@link URL} is returned, depending on its protocol.
+ * <p>
+ * If the path {@link #isList(Path)}, a {@link List} is returned
+ * corresponding to resolving the paths from {@link #getList(Path)}. using
+ * this method. Thus a depth 2 path which elements are lists of values will
+ * effectively be returned as a <code>List<List<String>></code>,
+ * assuming no references, errors or empty slots.
+ * <p>
+ * If the path is neither of the above, the {@link Path} itself is returned.
+ *
+ * @param path Data bundle path to resolve
+ * @return <code>null</code>, a {@link String}, {@link ErrorDocument},
+ * {@link URL}, {@link File}, {@link Path} or {@link List}
+ * (containing any of these).
+ * @throws IOException
+ * If the path (or any of the path in a contained list) can't be
+ * accessed
+ */
+ public static Object resolve(Path path) throws IOException {
+ if (path == null) {
+ return null;
+ }
+ if (isMissing(path)) {
+ return null;
+ } else if (isValue(path)) {
+ return getStringValue(path);
+ } else if (isReference(path)) {
+ URI reference = getReference(path);
+ String scheme = reference.getScheme();
+ if ("file".equals(scheme)) {
+ return new File(reference);
+ } else {
+ return reference.toURL();
+ }
+ } else if (isList(path)) {
+ List<Path> list = getList(path);
+ List<Object> objectList = new ArrayList<Object>(list.size());
+ for (Path pathElement : list) {
+ objectList.add(resolve(pathElement));
+ }
+ return objectList;
+ } else if (isError(path)) {
+ return getError(path);
+ } else {
+ return path;
+ }
+ }
public static WorkflowBundleIO getWfBundleIO() {
if (wfBundleIO == null)
diff --git a/taverna-databundle/src/test/java/org/apache/taverna/databundle/TestDataBundles.java b/taverna-databundle/src/test/java/org/apache/taverna/databundle/TestDataBundles.java
index c5d692d..ed87bc7 100644
--- a/taverna-databundle/src/test/java/org/apache/taverna/databundle/TestDataBundles.java
+++ b/taverna-databundle/src/test/java/org/apache/taverna/databundle/TestDataBundles.java
@@ -23,9 +23,11 @@
import static org.junit.Assert.*;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
+import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
@@ -185,7 +187,7 @@
public void getInputs() throws Exception {
Path inputs = DataBundles.getInputs(dataBundle);
assertTrue(Files.isDirectory(inputs));
- // Second time should not fail because it already exists
+ // Second time should not fail because it alreadresolvy exists
inputs = DataBundles.getInputs(dataBundle);
assertTrue(Files.isDirectory(inputs));
assertEquals(dataBundle.getRoot(), inputs.getParent());
@@ -523,6 +525,55 @@
}
@Test
+ public void resolve() throws Exception {
+ Path inputs = DataBundles.getInputs(dataBundle);
+ Path list = DataBundles.getPort(inputs, "in1");
+ DataBundles.createList(list);
+ // 0 string value
+ DataBundles.setStringValue(DataBundles.newListItem(list), "test0");
+ // 1 http:// reference
+ URI reference = URI.create("http://example.com/");
+ DataBundles.setReference(DataBundles.newListItem(list), reference);
+ // 2 file:/// reference
+ Path tmpFile = Files.createTempFile("test", ".txt");
+ URI fileRef = tmpFile.toUri();
+ assertEquals("file", fileRef.getScheme());
+ DataBundles.setReference(DataBundles.newListItem(list), fileRef);
+ // 3 empty (null)
+ // 4 error
+ DataBundles.setError(DataBundles.getListItem(list, 4), "Example error", "1. Tried it\n2. Didn't work");
+
+
+
+
+ Object resolved = DataBundles.resolve(list);
+ assertTrue("Didn't resolve to a list", resolved instanceof List);
+
+ List resolvedList = (List) resolved;
+ assertEquals("Unexpected list size", 5, resolvedList.size());
+
+ assertTrue(resolvedList.get(0) instanceof String);
+ assertEquals("test0", resolvedList.get(0));
+
+ assertTrue(resolvedList.get(1) instanceof URL);
+ assertEquals(reference, ((URL)resolvedList.get(1)).toURI());
+
+ assertTrue(resolvedList.get(2) instanceof File);
+ assertEquals(tmpFile.toFile(), resolvedList.get(2));
+
+ assertNull(resolvedList.get(3));
+ assertTrue(resolvedList.get(4) instanceof ErrorDocument);
+ assertEquals("Example error", ((ErrorDocument)resolvedList.get(4)).getMessage());
+
+ }
+
+ @Test
+ public void resolveBreaksOnBinaries() throws Exception {
+ Path inputs = DataBundles.getInputs(dataBundle);
+ Path list = DataBundles.getPort(inputs, "in1");
+ }
+
+ @Test
public void setErrorArgs() throws Exception {
Path inputs = DataBundles.getInputs(dataBundle);
Path portIn1 = DataBundles.getPort(inputs, "in1");
@@ -765,6 +816,7 @@
Files.probeContentType(wf));
}
+ // TODO: Why was this ignored? Check with taverna-language-0.15.x RC emails
@Ignore
@Test
public void getWorkflowBundle() throws Exception {