From 1b900dc2d09f3db6f4ec5a0441f76e1365cd3548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9da=20Housni=20Alaoui?= Date: Sat, 22 Aug 2015 19:00:27 +0200 Subject: [PATCH] https://github.com/threerings/getdown/issues/14 Add support for pack200 --- .../threerings/getdown/data/Application.java | 83 ++++++------------- .../com/threerings/getdown/data/Resource.java | 55 +++++++++--- .../com/threerings/getdown/util/FileUtil.java | 37 +++++++-- 3 files changed, 98 insertions(+), 77 deletions(-) diff --git a/src/main/java/com/threerings/getdown/data/Application.java b/src/main/java/com/threerings/getdown/data/Application.java index 7010907..b52f303 100644 --- a/src/main/java/com/threerings/getdown/data/Application.java +++ b/src/main/java/com/threerings/getdown/data/Application.java @@ -5,52 +5,6 @@ package com.threerings.getdown.data; -import java.awt.Color; -import java.awt.Rectangle; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.RandomAccessFile; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; -import java.nio.channels.OverlappingFileLockException; -import java.security.AllPermission; -import java.security.CodeSource; -import java.security.GeneralSecurityException; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Signature; -import java.security.cert.Certificate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map.Entry; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.swing.JApplet; - -import org.apache.commons.codec.binary.Base64; - import com.samskivert.io.StreamUtil; import com.samskivert.text.MessageUtil; import com.samskivert.util.ArrayUtil; @@ -58,13 +12,27 @@ import com.samskivert.util.RandomUtil; import com.samskivert.util.RunAnywhere; import com.samskivert.util.StringUtil; import com.threerings.getdown.launcher.RotatingBackgrounds; -import com.threerings.getdown.util.ConfigUtil; -import com.threerings.getdown.util.ConnectionUtil; -import com.threerings.getdown.util.FileUtil; -import com.threerings.getdown.util.LaunchUtil; -import com.threerings.getdown.util.MetaProgressObserver; -import com.threerings.getdown.util.ProgressObserver; -import com.threerings.getdown.util.VersionUtil; +import com.threerings.getdown.util.*; +import org.apache.commons.codec.binary.Base64; + +import javax.swing.*; +import java.awt.*; +import java.io.*; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.channels.OverlappingFileLockException; +import java.security.*; +import java.security.cert.Certificate; +import java.util.*; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.threerings.getdown.Log.log; @@ -626,10 +594,12 @@ public class Application _txtJvmArgs.clear(); // parse our code resources - if (ConfigUtil.getMultiValue(cdata, "code") == null) { + if (ConfigUtil.getMultiValue(cdata, "code") == null + && ConfigUtil.getMultiValue(cdata, "ucode") == null) { throw new IOException("m.missing_code"); } parseResources(cdata, "code", false, _codes); + parseResources(cdata, "ucode", true, _codes); // parse our non-code resources parseResources(cdata, "resource", false, _resources); @@ -639,6 +609,7 @@ public class Application for (String auxgroup : parseList(cdata, "auxgroups")) { ArrayList codes = new ArrayList(); parseResources(cdata, auxgroup + ".code", false, codes); + parseResources(cdata, auxgroup + ".ucode", true, codes); ArrayList rsrcs = new ArrayList(); parseResources(cdata, auxgroup + ".resource", false, rsrcs); parseResources(cdata, auxgroup + ".uresource", true, rsrcs); @@ -925,7 +896,7 @@ public class Application if (cpbuf.length() > 0) { cpbuf.append(File.pathSeparator); } - cpbuf.append(rsrc.getLocal().getAbsolutePath()); + cpbuf.append(rsrc.getFinalTarget().getAbsolutePath()); } ArrayList args = new ArrayList(); @@ -1030,7 +1001,7 @@ public class Application ArrayList jars = new ArrayList(); for (Resource rsrc : getActiveCodeResources()) { try { - jars.add(new URL("file", "", rsrc.getLocal().getAbsolutePath())); + jars.add(new URL("file", "", rsrc.getFinalTarget().getAbsolutePath())); } catch (Exception e) { e.printStackTrace(System.err); } diff --git a/src/main/java/com/threerings/getdown/data/Resource.java b/src/main/java/com/threerings/getdown/data/Resource.java index 1bbad19..15b2d8e 100644 --- a/src/main/java/com/threerings/getdown/data/Resource.java +++ b/src/main/java/com/threerings/getdown/data/Resource.java @@ -5,26 +5,23 @@ package com.threerings.getdown.data; +import com.samskivert.io.StreamUtil; +import com.samskivert.util.FileUtil; +import com.samskivert.util.StringUtil; +import com.threerings.getdown.util.ProgressObserver; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; - import java.net.URL; import java.security.MessageDigest; - -import java.util.Comparator; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import com.samskivert.io.StreamUtil; -import com.samskivert.util.FileUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.getdown.util.ProgressObserver; - import static com.threerings.getdown.Log.log; /** @@ -41,7 +38,17 @@ public class Resource _remote = remote; _local = local; _marker = new File(_local.getPath() + "v"); + _unpack = unpack; + _isJar = _local.getPath().endsWith(".jar"); + _isPacked200Jar = _local.getPath().endsWith(".jar.pack") || _local.getPath().endsWith(".jar.pack.gz"); + if(_unpack && _isJar){ + _unpacked = _local.getParentFile(); + } else if(_unpack && _isPacked200Jar){ + String jarExtension = ".jar"; + _unpacked = new File(_local.getParent(), + _local.getName().substring(0, _local.getName().lastIndexOf(jarExtension) + jarExtension.length())); + } } /** @@ -60,6 +67,24 @@ public class Resource return _local; } + /** + * Returns the location of the unpacked resource + */ + public File getUnpacked(){ + return _unpacked; + } + + /** + * Returns the final target of this resource, wheter it has been unpacked or not + */ + public File getFinalTarget(){ + if(shouldUnpack()){ + return getUnpacked(); + } else{ + return getLocal(); + } + } + /** * Returns the remote location of this resource. */ @@ -132,12 +157,16 @@ public class Resource public boolean unpack () { // sanity check - if (!_local.getPath().endsWith(".jar")) { + if (!_isJar && !_isPacked200Jar) { log.warning("Requested to unpack non-jar file '" + _local + "'."); return false; } try { - return FileUtil.unpackJar(new JarFile(_local), _local.getParentFile()); + if(_isJar){ + return FileUtil.unpackJar(new JarFile(_local), _unpacked); + } else{ + return com.threerings.getdown.util.FileUtil.unpackPacked200Jar(_local, _unpacked); + } } catch (IOException ioe) { log.warning("Failed to create JarFile from '" + _local + "': " + ioe); return false; @@ -266,8 +295,8 @@ public class Resource protected String _path; protected URL _remote; - protected File _local, _marker; - protected boolean _unpack; + protected File _local, _marker, _unpacked; + protected boolean _unpack, _isJar, _isPacked200Jar; /** Used to sort the entries in a jar file. */ protected static final Comparator ENTRY_COMP = diff --git a/src/main/java/com/threerings/getdown/util/FileUtil.java b/src/main/java/com/threerings/getdown/util/FileUtil.java index ab752d1..2f9f112 100644 --- a/src/main/java/com/threerings/getdown/util/FileUtil.java +++ b/src/main/java/com/threerings/getdown/util/FileUtil.java @@ -5,17 +5,14 @@ package com.threerings.getdown.util; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Reader; +import com.samskivert.io.StreamUtil; +import java.io.*; import java.util.ArrayList; import java.util.List; - -import com.samskivert.io.StreamUtil; +import java.util.jar.JarOutputStream; +import java.util.jar.Pack200; +import java.util.zip.GZIPInputStream; import static com.threerings.getdown.Log.log; @@ -96,4 +93,28 @@ public class FileUtil } return lines; } + + public static boolean unpackPacked200Jar(File packedJar, File target){ + InputStream packedJarIs = null; + FileOutputStream extractedJarFileOs = null; + JarOutputStream jarOutputStream = null; + try{ + extractedJarFileOs = new FileOutputStream(target); + jarOutputStream = new JarOutputStream(extractedJarFileOs); + packedJarIs = new FileInputStream(packedJar); + if(packedJar.getName().endsWith(".gz")){ + packedJarIs = new GZIPInputStream(packedJarIs); + } + Pack200.Unpacker unpacker = Pack200.newUnpacker(); + unpacker.unpack(packedJarIs, jarOutputStream); + return true; + } catch(IOException e){ + log.warning("Failed to unpack packed 200 jar file", "jar", packedJar, "error", e); + return false; + } finally { + StreamUtil.close(jarOutputStream); + StreamUtil.close(extractedJarFileOs); + StreamUtil.close(packedJarIs); + } + } }