Переглянути джерело

fix: PackageScanner - can scan executable zips (so it works inside launch4j applications)

Mariusz Sieroń 6 роки тому
батько
коміт
12f434dc05

+ 56 - 0
assira/src/main/java/net/ranides/assira/io/ZipReader.java

@@ -0,0 +1,56 @@
+package net.ranides.assira.io;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.JarInputStream;
+import java.util.zip.ZipInputStream;
+
+public class ZipReader {
+
+    public static JarInputStream openJAR(InputStream istream) throws IOException {
+        return new JarInputStream(new ZipInputStream2(istream));
+    }
+
+    public static ZipInputStream openZIP(InputStream istream) {
+        return new ZipInputStream(new ZipInputStream2(istream));
+    }
+
+    private static class ZipInputStream2 extends FilterInputStream {
+
+        public static final byte[] ZIP_LOCAL = { 0x50, 0x4b, 0x03, 0x04 };
+
+        protected int ip;
+
+        protected int op;
+
+        public ZipInputStream2(InputStream is) {
+            super(is);
+        }
+
+        public int read() throws IOException {
+            while(ip < ZIP_LOCAL.length) {
+                int c = super.read();
+                if (c == ZIP_LOCAL[ip]) {
+                    ip++;
+                } else {
+                    ip = 0;
+                }
+            }
+            return op < ZIP_LOCAL.length ? ZIP_LOCAL[op++] : super.read();
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            if (op == ZIP_LOCAL.length) {
+                return super.read(b, off, len);
+            }
+            int count = 0;
+            while (count < Math.min(len, ZIP_LOCAL.length)) {
+                b[count++] = (byte)read();
+            }
+            return count;
+        }
+    }
+
+}

+ 2 - 1
assira/src/main/java/net/ranides/assira/reflection/util/PackageScanner.java

@@ -25,6 +25,7 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import net.ranides.assira.collection.iterators.ForwardSpliterator;
+import net.ranides.assira.io.ZipReader;
 import net.ranides.assira.text.StringUtils;
 import net.ranides.assira.io.uri.URIUtils;
 import net.ranides.assira.trace.ExceptionUtils;
@@ -102,7 +103,7 @@ public final class PackageScanner {
         private Spliterator<String> forJAR(String uri) {
             try {
                 String jar = StringUtils.between(uri, ":", "!");
-                return new JARSpliterator(new JarInputStream(new FileInputStream(jar)));
+                return new JARSpliterator(ZipReader.openJAR(new FileInputStream(jar)));
             } catch (IOException cause) {
                 throw ExceptionUtils.rethrow(cause);
             }