read/write resources using ROBundle instead of ODFdom

Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/commit/041a9f39
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/tree/041a9f39
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/diff/041a9f39

Branch: refs/heads/ucfpackage-robundle
Commit: 041a9f39c17df2b8bfd2f06a484555a0e8feac79
Parents: bb7f4d9
Author: Stian Soiland-Reyes <[email protected]>
Authored: Wed Dec 11 16:21:43 2013 +0000
Committer: Stian Soiland-Reyes <[email protected]>
Committed: Thu Jul 2 15:03:50 2015 +0100

----------------------------------------------------------------------
 .../taverna/scufl2/ucfpackage/UCFPackage.java   | 332 ++++++++-----------
 1 file changed, 143 insertions(+), 189 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/041a9f39/taverna-scufl2-ucfpackage/src/main/java/org/apache/taverna/scufl2/ucfpackage/UCFPackage.java
----------------------------------------------------------------------
diff --git 
a/taverna-scufl2-ucfpackage/src/main/java/org/apache/taverna/scufl2/ucfpackage/UCFPackage.java
 
b/taverna-scufl2-ucfpackage/src/main/java/org/apache/taverna/scufl2/ucfpackage/UCFPackage.java
index b806ffe..fcfc55f 100644
--- 
a/taverna-scufl2-ucfpackage/src/main/java/org/apache/taverna/scufl2/ucfpackage/UCFPackage.java
+++ 
b/taverna-scufl2-ucfpackage/src/main/java/org/apache/taverna/scufl2/ucfpackage/UCFPackage.java
@@ -24,9 +24,7 @@ package org.apache.taverna.scufl2.ucfpackage;
 import static java.io.File.createTempFile;
 import static java.util.logging.Level.INFO;
 
-import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -34,12 +32,16 @@ import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
 import java.net.URI;
 import java.nio.charset.Charset;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
+//import java.util.Map.Entry;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.xml.bind.JAXBContext;
@@ -54,9 +56,13 @@ import 
org.oasis_open.names.tc.opendocument.xmlns.container.Container;
 import 
org.oasis_open.names.tc.opendocument.xmlns.container.Container.RootFiles;
 import org.oasis_open.names.tc.opendocument.xmlns.container.ObjectFactory;
 import org.oasis_open.names.tc.opendocument.xmlns.container.RootFile;
+import org.purl.wf4ever.robundle.Bundle;
+import org.purl.wf4ever.robundle.Bundles;
+import org.purl.wf4ever.robundle.manifest.Manifest;
+import org.purl.wf4ever.robundle.manifest.PathMetadata;
+import org.purl.wf4ever.robundle.utils.RecursiveDeleteVisitor;
 import org.w3c.dom.Document;
 
-
 public class UCFPackage implements Cloneable {
        private static Logger logger = 
Logger.getLogger(UCFPackage.class.getName());
        private static final String CONTAINER_XML = "META-INF/container.xml";
@@ -67,19 +73,18 @@ public class UCFPackage implements Cloneable {
        public static final String MIME_RDF = "application/rdf+xml";
        public static final String MIME_EPUB = "application/epub+zip";
        public static final String MIME_WORKFLOW_BUNDLE = 
"application/vnd.taverna.workflow-bundle";
-       public static final String MIME_DATA_BUNDLE = 
"application/vnd.taverna.data-bundle";
-       public static final String MIME_WORKFLOW_RUN_BUNDLE = 
"application/vnd.taverna.workflow-run-bundle";
-       public static final String MIME_SERVICE_BUNDLE = 
"application/vnd.taverna.service-bundle";
 
        private static Charset ASCII = Charset.forName("ascii");
        private OdfPackage odfPackage;
        private static JAXBContext jaxbContext;
        private JAXBElement<Container> containerXml;
        private boolean createdContainerXml = false;
+    private Bundle bundle;
        private static ObjectFactory containerFactory = new ObjectFactory();
 
        public UCFPackage() throws IOException {
                try {
+                   bundle = Bundles.createBundle();
                        odfPackage = OdfPackage.create();
                        parseContainerXML();
                } catch (IOException e) {
@@ -95,10 +100,15 @@ public class UCFPackage implements Cloneable {
        }
 
        protected void open(File containerFile) throws IOException {
-               try (BufferedInputStream stream = new BufferedInputStream(
-                               new FileInputStream(containerFile))) {
-                       open(stream);
-               }
+           bundle = Bundles.openBundleReadOnly(containerFile.toPath());
+//
+//             BufferedInputStream stream = new BufferedInputStream(
+//                             new FileInputStream(containerFile));
+//             try {
+//                     open(stream);
+//             } finally {
+//                     stream.close();
+//             }
        }
 
        public UCFPackage(InputStream inputStream) throws IOException {
@@ -107,7 +117,7 @@ public class UCFPackage implements Cloneable {
 
        protected void open(InputStream inputStream) throws IOException {
                try {
-                       odfPackage = OdfPackage.loadPackage(inputStream);
+//                     odfPackage = OdfPackage.loadPackage(inputStream);
                        parseContainerXML();
                } catch (IOException e) {
                        throw e;
@@ -138,60 +148,31 @@ public class UCFPackage implements Cloneable {
        }
 
        public String getPackageMediaType() {
-               return odfPackage.getMediaType();
+           try {
+            return Bundles.getMimeType(bundle);
+        } catch (IOException e) {
+            return MIME_WORKFLOW_BUNDLE;
+        }
        }
 
        public void setPackageMediaType(String mediaType) {
-               if (mediaType == null || !mediaType.contains("/"))
-                       throw new IllegalArgumentException("Invalid media type "
-                                       + mediaType);
-               if (!ASCII.newEncoder().canEncode(mediaType))
-                       throw new IllegalArgumentException("Media type must be 
ASCII: "
-                                       + mediaType);
-               odfPackage.setMediaType(mediaType);
-       }
+               try {
+                                       Bundles.setMimeType(bundle, mediaType);
+                       } catch (IOException e) {
+                                       throw new RuntimeException("Can't set 
media type", e);
+                       }
+}
 
        public void save(File packageFile) throws IOException {
-               File tempFile = createTempFile("." + packageFile.getName(), 
".tmp",
-                               packageFile.getCanonicalFile().getParentFile());
-               prepareAndSave(tempFile);
-               boolean renamed = tempFile.renameTo(packageFile);
-               if (!renamed && packageFile.exists() && tempFile.exists()) {
-                       // Could happen on Windows
-                       if (!packageFile.delete())
-                               // Could have been permission problem
-                               throw new IOException("Could not delete 
existing "
-                                               + packageFile);
-                       renamed = tempFile.renameTo(packageFile);
-               }
-               if (!renamed)
-                       throw new IOException("Could not rename temp file " + 
tempFile
-                                       + " to " + packageFile);
-       }
-
-       protected void prepareAndSave(File tempFile) throws IOException {
-               if (getPackageMediaType() == null)
-                       throw new IllegalStateException("Package media type 
must be set");
+           prepareContainerXML();
 
-               // Write using temp file, and do rename in the end
-
-               try {
-                       prepareContainerXML();
-                       odfPackage.save(tempFile);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not save bundle to " + 
tempFile, e);
-               } finally {
-                       odfPackage.close();
-               }
-
-               try {
-                       open(tempFile);
-               } catch (Exception e) {
-                       throw new IOException("Could not reload package from " 
+ tempFile,
-                                       e);
-               }
+           Path source = bundle.getSource();
+           boolean deleteOnClose = bundle.isDeleteOnClose();
+           bundle.setDeleteOnClose(false);
+           Bundles.closeAndSaveBundle(bundle, packageFile.toPath());
+           // Re-open the original source (usually a tmpfile)
+           bundle = Bundles.openBundle(source);
+           bundle.setDeleteOnClose(deleteOnClose);
        }
 
        protected void prepareContainerXML() throws IOException {
@@ -271,27 +252,18 @@ public class UCFPackage implements Cloneable {
 
        public void addResource(String stringValue, String path, String 
mediaType)
                        throws IOException {
-               try {
-                       odfPackage.insert(stringValue.getBytes(UTF_8), path, 
mediaType);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not add " + path, e);
-               }
-               parseContainerXML();
+           Path bundlePath = bundle.getRoot().resolve(path);
+           Bundles.setStringValue(bundlePath, stringValue);
+           Manifest manifest = bundle.getManifest();
+           manifest.getAggregation(bundlePath).setMediatype(mediaType);
        }
 
        public void addResource(byte[] bytesValue, String path, String 
mediaType)
                        throws IOException {
-               try {
-                       odfPackage.insert(bytesValue, path, mediaType);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not add " + path, e);
-               }
-               if (path.equals(CONTAINER_XML))
-                       parseContainerXML();
+           Path bundlePath = bundle.getRoot().resolve(path);
+           Files.write(bundlePath, bytesValue);
+        Manifest manifest = bundle.getManifest();
+        manifest.getAggregation(bundlePath).setMediatype(mediaType);
        }
 
        public void addResource(Document document, String path, String 
mediaType)
@@ -309,59 +281,33 @@ public class UCFPackage implements Cloneable {
 
        public void addResource(InputStream inputStream, String path,
                        String mediaType) throws IOException {
-               try {
-                       odfPackage.insert(inputStream, path, mediaType);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not add " + path, e);
-               }
-               if (path.equals(CONTAINER_XML))
-                       parseContainerXML();
+           Path bundlePath = bundle.getRoot().resolve(path);
+           Files.copy(inputStream, bundlePath);
+        Manifest manifest = bundle.getManifest();
+        manifest.getAggregation(bundlePath).setMediatype(mediaType);
        }
 
        public void addResource(URI uri, String path, String mediaType)
                        throws IOException {
-               try {
-                       odfPackage.insert(uri, path, mediaType);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not add " + path, e);
-               }
-
-               if (path.equals(CONTAINER_XML))
-                       parseContainerXML();
+           Path bundlePath = bundle.getRoot().resolve(path);
+        Bundles.setReference(bundlePath, uri);
+        Manifest manifest = bundle.getManifest();
+        manifest.getAggregation(bundlePath).setMediatype(mediaType);
        }
 
        public String getResourceAsString(String path) throws IOException {
-               try {
-                       return new String(odfPackage.getBytes(path), UTF_8);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not get " + path, e);
-               }
+           Path bundlePath = bundle.getRoot().resolve(path);
+           return Bundles.getStringValue(bundlePath);
        }
 
        public byte[] getResourceAsBytes(String path) throws IOException {
-               try {
-                       return odfPackage.getBytes(path);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not get " + path, e);
-               }
+        Path bundlePath = bundle.getRoot().resolve(path);
+        return Files.readAllBytes(bundlePath);
        }
 
        public InputStream getResourceAsInputStream(String path) throws 
IOException {
-               try {
-                       return odfPackage.getInputStream(path);
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException("Could not get " + path, e);
-               }
+           Path bundlePath = bundle.getRoot().resolve(path);
+           return Files.newInputStream(bundlePath);
        }
 
        public Map<String, ResourceEntry> listResources() {
@@ -374,69 +320,57 @@ public class UCFPackage implements Cloneable {
 
        protected Map<String, ResourceEntry> listResources(String folderPath,
                        boolean recursive) {
-               if (!folderPath.isEmpty() && !folderPath.endsWith("/"))
-                       folderPath = folderPath + "/";
-               HashMap<String, ResourceEntry> content = new HashMap<>();
-
-               for (Entry<String, OdfFileEntry> entry : odfPackage
-                               .getManifestEntries().entrySet()) {
-                       String entryPath = entry.getKey();
-                       if (!entryPath.startsWith(folderPath))
-                               continue;
-                       String subPath = 
entryPath.substring(folderPath.length(),
-                                       entryPath.length());
-                       if (subPath.isEmpty())
-                               // The folder itself
-                               continue;
-                       int firstSlash = subPath.indexOf("/");
-                       if (!recursive && firstSlash > -1
-                                       && firstSlash < subPath.length() - 1)
-                               /*
-                                * Children of a folder (note that we'll 
include the folder
-                                * itself which ends in /)
-                                */
-                               continue;
-                       content.put(subPath, new 
ResourceEntry(entry.getValue()));
-               }
+           Path bundlePath = bundle.getRoot().resolve(folderPath);
+
+           HashMap<String, ResourceEntry> content = new HashMap<String, 
ResourceEntry>();
+           try (DirectoryStream<Path> ds = 
Files.newDirectoryStream(bundlePath)) {
+               for (Path path : ds) {
+                   content.put(path.toString(), new ResourceEntry(path));
+               }
+           } catch (IOException e) {
+            throw new RuntimeException("Can't list resources of "  
+folderPath, e);
+        }
                return content;
        }
 
        public void removeResource(String path) {
-               if (!odfPackage.contains(path))
-                       return;
-               if (path.endsWith("/"))
-                       for (ResourceEntry childEntry : 
listResources(path).values())
-                               removeResource(childEntry.getPath());
-               odfPackage.remove(path);
+           Path bundlePath = bundle.getRoot().resolve(path);
+           try {
+            RecursiveDeleteVisitor.deleteRecursively(bundlePath);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not delete " + path + " or its 
children", e);
+        }
        }
 
        public class ResourceEntry {
-               private final String path;
-               private final long size;
-               private String mediaType;
-               private String version;
-
-               protected ResourceEntry(OdfFileEntry odfEntry) {
-                       path = odfEntry.getPath();
-                       size = odfEntry.getSize();
-                       mediaType = odfEntry.getMediaType();
-                       version = odfEntry.getVersion();
-               }
+        private Path path;
 
-               public String getPath() {
-                       return path;
+               public ResourceEntry(Path path) {
+            this.path = path;
+        }
+
+        public String getPath() {
+                       return path.toString();
                }
 
                public long getSize() {
-                       return size;
+                       try {
+                return Files.size(path);
+            } catch (IOException e) {
+               throw new RuntimeException("Can't determine size of " + path, 
e);
+            }
                }
 
                public String getMediaType() {
-                       return mediaType;
+                       try {
+                return 
bundle.getManifest().getAggregation(path).getMediatype();
+            } catch (IOException e) {
+                throw new RuntimeException("Can't get media type for " + path, 
e);
+            }
                }
 
                public boolean isFolder() {
-                       return path.endsWith("/");
+                       return Files.isDirectory(path);
                }
 
                public UCFPackage getUcfPackage() {
@@ -444,6 +378,11 @@ public class UCFPackage implements Cloneable {
                }
 
                @Override
+               public String toString() {
+                   return getPath();
+               };
+
+               @Override
                public boolean equals(Object obj) {
                        if (!(obj instanceof ResourceEntry))
                                return false;
@@ -451,7 +390,8 @@ public class UCFPackage implements Cloneable {
 
                        if (!getUcfPackage().equals(other.getUcfPackage()))
                                return false;
-                       return getPath().equals(other.getPath());
+                       }
+                       return path.equals(other.path);
                }
 
                @Override
@@ -463,9 +403,23 @@ public class UCFPackage implements Cloneable {
                        return result;
                }
 
-               public String getVersion() {
-                       return version;
-               }
+        public String getVersion() {
+            URI conformsTo;
+            try {
+                conformsTo = 
bundle.getManifest().getAggregation(path).getConformsTo();
+            } catch (IOException e) {
+                throw new RuntimeException("Can't look up version for " + 
path, e);
+            }
+            if (conformsTo != null) {
+                URI scufl2Release = 
URI.create("http://ns.taverna.org.uk/2010/scufl2/";);
+                URI version = scufl2Release.relativize(conformsTo);
+                if (!version.isAbsolute()) {
+                    return version.toString();
+                }
+            }
+            return null;
+
+        }
        }
 
        public Map<String, ResourceEntry> listAllResources() {
@@ -555,19 +509,24 @@ public class UCFPackage implements Cloneable {
                        RootFile rf = (RootFile) anyOrRoot;
                        ResourceEntry entry = 
getResourceEntry(rf.getFullPath());
                        if (rf.getMediaType() != null
-                                       && rf.getMediaType() != entry.mediaType)
+                                       && rf.getMediaType() != 
entry.getMediaType()) {
                                // Override the mime type in the returned entry
-                               entry.mediaType = rf.getMediaType();
+                           PathMetadata aggr;
+                try {
+                    aggr = bundle.getManifest().getAggregation(entry.path);
+                } catch (IOException e) {
+                    throw new RuntimeException("Can't get aggregation for " + 
entry, e);
+                }
+                           aggr.setMediatype(rf.getMediaType());
+                       }
                        rootFiles.add(entry);
                }
                return rootFiles;
        }
 
        public ResourceEntry getResourceEntry(String path) {
-               OdfFileEntry odfFileEntry = 
odfPackage.getManifestEntries().get(path);
-               if (odfFileEntry == null)
-                       return null;
-               return new ResourceEntry(odfFileEntry);
+           Path bundlePath = bundle.getRoot().resolve(path);
+               return new ResourceEntry(bundlePath);
        }
 
        @SuppressWarnings("rawtypes")
@@ -592,22 +551,17 @@ public class UCFPackage implements Cloneable {
        }
 
        public void save(OutputStream output) throws IOException {
-               File tempFile = createTempFile("ucfpackage", ".tmp");
-               prepareAndSave(tempFile);
-
-               // Copy file to the output
-
-               // Note - Should use IOUtils, but we're trying to avoid 
external dependencies
-               try (InputStream inStream = new FileInputStream(tempFile)) {
-                       byte[] buffer = new byte[8192];
-                       int n = 0;
-                       do {
-                               output.write(buffer, 0, n);
-                               n = inStream.read(buffer);
-                       } while (n > -1);
-               } finally {
-                       tempFile.delete();
-               }
+        prepareContainerXML();
+        Path source = bundle.getSource();
+        boolean deleteOnClose = bundle.isDeleteOnClose();
+        bundle.setDeleteOnClose(false);
+        Bundles.closeBundle(bundle);
+
+        Files.copy(source, output);
+
+        // Re-open the original source (usually a tmpfile)
+        bundle = Bundles.openBundle(source);
+        bundle.setDeleteOnClose(deleteOnClose);
        }
 
        public OutputStream addResourceUsingOutputStream(String path,

Reply via email to