JAL-3224 New version of getdown which will cope with unpacking .tgz resources, specif...
[jalview.git] / getdown / src / getdown / core / src / main / java / com / threerings / getdown / data / Resource.java
index 3e2f446..adc2d4f 100644 (file)
@@ -7,6 +7,8 @@ package com.threerings.getdown.data;
 
 import java.io.*;
 import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.MessageDigest;
 import java.util.Collections;
 import java.util.Comparator;
@@ -16,6 +18,10 @@ import java.util.Locale;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+
 import com.threerings.getdown.util.FileUtil;
 import com.threerings.getdown.util.ProgressObserver;
 import com.threerings.getdown.util.StringUtil;
@@ -139,11 +145,14 @@ public class Resource implements Comparable<Resource>
         _marker = new File(lpath + "v");
 
         _attrs = attrs;
+        _isTgz = isTgz(lpath);
         _isJar = isJar(lpath);
         _isPacked200Jar = isPacked200Jar(lpath);
         boolean unpack = attrs.contains(Attr.UNPACK);
         if (unpack && _isJar) {
             _unpacked = _local.getParentFile();
+        } else if(unpack && _isTgz) {
+            _unpacked = _local.getParentFile();
         } else if(unpack && _isPacked200Jar) {
             String dotJar = ".jar", lname = _local.getName();
             String uname = lname.substring(0, lname.lastIndexOf(dotJar) + dotJar.length());
@@ -298,13 +307,20 @@ public class Resource implements Comparable<Resource>
     public void unpack () throws IOException
     {
         // sanity check
-        if (!_isJar && !_isPacked200Jar) {
-            throw new IOException("Requested to unpack non-jar file '" + _local + "'.");
+        if (!_isJar && !_isPacked200Jar && !_isTgz) {
+            throw new IOException("Requested to unpack non-jar/tgz file '" + _local + "'.");
         }
         if (_isJar) {
             try (JarFile jar = new JarFile(_local)) {
                 FileUtil.unpackJar(jar, _unpacked, _attrs.contains(Attr.CLEAN));
             }
+        } else if (_isTgz) {
+            try (InputStream fi = Files.newInputStream(_local.toPath());
+                         InputStream bi = new BufferedInputStream(fi);
+                         InputStream gzi = new GzipCompressorInputStream(bi);
+                         TarArchiveInputStream tgz = new TarArchiveInputStream(gzi)) {
+                    FileUtil.unpackTgz(tgz, _unpacked, _attrs.contains(Attr.CLEAN));
+            }
         } else {
             FileUtil.unpackPacked200Jar(_local, _unpacked);
         }
@@ -370,6 +386,11 @@ public class Resource implements Comparable<Resource>
     {
         return path.endsWith(".jar") || path.endsWith(".jar_new");
     }
+    
+    protected static boolean isTgz (String path)
+    {
+        return path.endsWith(".tgz") || path.endsWith(".tgz_new");
+    }
 
     protected static boolean isPacked200Jar (String path)
     {
@@ -381,7 +402,7 @@ public class Resource implements Comparable<Resource>
     protected URL _remote;
     protected File _local, _localNew, _marker, _unpacked;
     protected EnumSet<Attr> _attrs;
-    protected boolean _isJar, _isPacked200Jar;
+    protected boolean _isJar, _isPacked200Jar, _isTgz;
 
     /** Used to sort the entries in a jar file. */
     protected static final Comparator<JarEntry> ENTRY_COMP = new Comparator<JarEntry>() {