mirror of
https://github.com/pxb1988/dex2jar.git
synced 2024-11-23 05:10:11 +00:00
add d2j-j6 to generate dex2jar for jdk6
--HG-- branch : 2.x
This commit is contained in:
parent
11e2582498
commit
8b011b7308
57
d2j-j6/README.md
Normal file
57
d2j-j6/README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# j6 Generate dex2jar for jdk6
|
||||
dex2jar 2.0 change the compile jdk to version 1.7, but there still requirement for running dex2jar on jdk6. this project is try make dex2jar runnable on jdk6.
|
||||
|
||||
## jdk7 vs jdk6
|
||||
|
||||
### the major version of class file is changed
|
||||
jdk6 can not run class file build for jdk7
|
||||
|
||||
### new package java.nio.file
|
||||
jdk7 add the java.nio.file package for file processing, and dex2jar heavy based on it,
|
||||
|
||||
#### Related new Class
|
||||
* java.nio.file.\*\*
|
||||
|
||||
#### Related new method
|
||||
* File.toPath()
|
||||
|
||||
|
||||
### try-with-resource
|
||||
This is a good improvement for coding, i can' stop using it.
|
||||
the AutoCloseable interface is used for close the resource, and addSuppressed/getSuppressed is Throwable is used for save the Exception during close resource.
|
||||
|
||||
#### Related new Class
|
||||
* java.lang.AutoCloseable
|
||||
|
||||
#### Related new method
|
||||
* Throwable.addSuppressed()
|
||||
* Throwable.getSuppressed()
|
||||
|
||||
### other improvement
|
||||
|
||||
#### Related new Class
|
||||
* java.nio.charset.StandardCharsets
|
||||
|
||||
## Solution
|
||||
* For each missing class, create a new class with prefixed 'pxb.' in this project.
|
||||
* For each missing method, create a static method in this project and use the d2j-jar-weave feature of dex2jar to static weave the code into the origianl jar.
|
||||
```
|
||||
r Ljava/io/File;.toPath=Lj6/Files;.toPath(Ljava/io/File;)Ljava/lang/Object;
|
||||
r Ljava/lang/Throwable;.addSuppressed(Ljava/lang/Throwable;)=Lj6/Thro;.addSuppressed(Ljava/lang/Throwable;Ljava/lang/Throwable;)V;
|
||||
r [Ljava/lang/Throwable;.getSuppressed()=Lj6/Thro;.getSuppressed(Ljava/lang/Throwable;)[Ljava/lang/Throwable;
|
||||
```
|
||||
* Replace the following reference in original jar by the tool jarjar
|
||||
```
|
||||
rule java.nio.file.** pxb.@0
|
||||
rule java.nio.charset.StandardCharsets pxb.java.nio.charset.StandardCharsets
|
||||
rule java.lang.AutoCloseable java.io.Closeable
|
||||
```
|
||||
* Modify the version of all .class file to java6
|
||||
|
||||
## Test
|
||||
this the following VM have been tested (only the cmd d2j-dex2jar)
|
||||
|
||||
* Oracle jdk 1.6.0_45, on 64bit linux
|
||||
* Dalvik VM on android 4.4.2 armv7a with '-Xmx512m' to increase memory
|
||||
|
||||
|
56
d2j-j6/build.gradle
Normal file
56
d2j-j6/build.gradle
Normal file
@ -0,0 +1,56 @@
|
||||
configurations {
|
||||
jarjar
|
||||
proguard
|
||||
}
|
||||
dependencies {
|
||||
compile project(':dex-tools')
|
||||
jarjar 'com.googlecode.jarjar:jarjar:1.3'
|
||||
proguard 'net.sf.proguard:proguard-base:5.2.1'
|
||||
}
|
||||
task allinone(type: Jar, dependsOn: jar) {
|
||||
archiveName = 'all-in-one.jar'
|
||||
def deps = configurations.runtime
|
||||
def depClasses = { deps.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
from(depClasses) {
|
||||
exclude 'META-INF/**'
|
||||
}
|
||||
from(sourceSets.main.output)
|
||||
manifest {
|
||||
attributes 'Main-Class': 'com.googlecode.dex2jar.tools.Dex2jarCmd'
|
||||
attributes("Implementation-Title": project.name,
|
||||
"Implementation-Version": project.version,
|
||||
"Build-Time": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||
"Revision": System.env.BUILD_REVISION?System.env.BUILD_REVISION:System.env.MERCURIAL_REVISION?System.env.MERCURIAL_REVISION:"HEAD",
|
||||
"Build-Number": System.env.BUILD_NUMBER?System.env.BUILD_NUMBER:"-1",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
task j6version(type: JavaExec, dependsOn: allinone) {
|
||||
classpath sourceSets.main.runtimeClasspath
|
||||
main='com.googlecode.dex2jar.tools.ClassVersionSwitch'
|
||||
args=["6","$allinone.destinationDir/$allinone.archiveName", "$allinone.destinationDir/j6.jar"]
|
||||
}
|
||||
|
||||
task j6weave(type: JavaExec, dependsOn: j6version) {
|
||||
classpath sourceSets.main.runtimeClasspath
|
||||
main='com.googlecode.dex2jar.tools.JarWeaverCmd'
|
||||
args=["-c", "$projectDir/j6-weave.txt", "$allinone.destinationDir/j6.jar", "-o", "$allinone.destinationDir/weaved.jar"]
|
||||
}
|
||||
|
||||
task j6jarjar(type: JavaExec, dependsOn: j6weave) {
|
||||
classpath configurations.jarjar
|
||||
main='com.tonicsystems.jarjar.Main'
|
||||
args=["process", "$projectDir/jarjar-rules.txt", "$allinone.destinationDir/weaved.jar", "$projectDir/build/dex2jar-for-jdk6.jar"]
|
||||
}
|
||||
|
||||
task j6proguard(type: JavaExec, dependsOn: j6jarjar) {
|
||||
classpath=configurations.proguard
|
||||
main='proguard.ProGuard'
|
||||
args=['-injars', "$projectDir/build/dex2jar-for-jdk6.jar" , '-outjars',"$projectDir/build/dex2jar-for-jdk6-obfuscated.jar", "-printmapping", "$projectDir/build/dex2jar-for-jdk6-mapping.txt", "@$projectDir/proguard.txt"]
|
||||
}
|
||||
|
||||
task jdk6 {
|
||||
dependsOn j6jarjar
|
||||
dependsOn j6proguard
|
||||
}
|
4
d2j-j6/j6-weave.txt
Normal file
4
d2j-j6/j6-weave.txt
Normal file
@ -0,0 +1,4 @@
|
||||
#
|
||||
r Ljava/io/File;.toPath=Lj6/Files;.toPath(Ljava/io/File;)Ljava/lang/Object;
|
||||
r Ljava/lang/Throwable;.addSuppressed(Ljava/lang/Throwable;)=Lj6/Thro;.addSuppressed(Ljava/lang/Throwable;Ljava/lang/Throwable;)V;
|
||||
r [Ljava/lang/Throwable;.getSuppressed()=Lj6/Thro;.getSuppressed(Ljava/lang/Throwable;)[Ljava/lang/Throwable;
|
3
d2j-j6/jarjar-rules.txt
Normal file
3
d2j-j6/jarjar-rules.txt
Normal file
@ -0,0 +1,3 @@
|
||||
rule java.nio.file.** pxb.@0
|
||||
rule java.nio.charset.StandardCharsets pxb.java.nio.charset.StandardCharsets
|
||||
rule java.lang.AutoCloseable java.io.Closeable
|
9
d2j-j6/proguard.txt
Normal file
9
d2j-j6/proguard.txt
Normal file
@ -0,0 +1,9 @@
|
||||
-libraryjars <java.home>/lib/rt.jar
|
||||
-keepattributes AnnotationDefault,RuntimeVisible*Annotations,Signature
|
||||
-repackageclasses d2j
|
||||
-allowaccessmodification
|
||||
#-dontobfuscate
|
||||
-keep public class com.googlecode.dex2jar.tools.Dex2jarCmd {public static void main(java.lang.String[]);}
|
||||
-keep,allowobfuscation public class com.googlecode.dex2jar.tools.Dex2jarCmd {@com.googlecode.dex2jar.tools.BaseCmd$Opt <fields>;}
|
||||
|
||||
-dontwarn **
|
11
d2j-j6/src/main/java/j6/Files.java
Normal file
11
d2j-j6/src/main/java/j6/Files.java
Normal file
@ -0,0 +1,11 @@
|
||||
package j6;
|
||||
|
||||
import pxb.java.nio.file.spi.FileSystemProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Files {
|
||||
public static Object toPath(File file) throws Throwable {
|
||||
return new FileSystemProvider.DefPath(file);
|
||||
}
|
||||
}
|
28
d2j-j6/src/main/java/j6/Thro.java
Normal file
28
d2j-j6/src/main/java/j6/Thro.java
Normal file
@ -0,0 +1,28 @@
|
||||
package j6;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Thro {
|
||||
|
||||
static Map<Throwable, List<Throwable>> aa = new HashMap<>();
|
||||
|
||||
public static void addSuppressed(Throwable a, Throwable b) {
|
||||
List<Throwable> list = aa.get(a);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
aa.put(a, list);
|
||||
}
|
||||
list.add(b);
|
||||
}
|
||||
|
||||
public static Throwable[] getSuppressed(Throwable a) {
|
||||
List<Throwable> list = aa.remove(a);
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
return list.toArray(new Throwable[list.size()]);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package pxb.java.nio.charset;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class StandardCharsets {
|
||||
public static Charset UTF_8 = Charset.forName("UTF-8");
|
||||
public static Charset ISO_8859_1 = Charset.forName("iso-8859-1");
|
||||
}
|
4
d2j-j6/src/main/java/pxb/java/nio/file/CopyOption.java
Normal file
4
d2j-j6/src/main/java/pxb/java/nio/file/CopyOption.java
Normal file
@ -0,0 +1,4 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
public interface CopyOption {
|
||||
}
|
7
d2j-j6/src/main/java/pxb/java/nio/file/FileSystem.java
Normal file
7
d2j-j6/src/main/java/pxb/java/nio/file/FileSystem.java
Normal file
@ -0,0 +1,7 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
public abstract class FileSystem implements Closeable {
|
||||
public abstract Path getPath(String first, String... more);
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
|
||||
public enum FileVisitResult {
|
||||
CONTINUE,TERMINATE,SKIP_SUBTREE, SKIP_SIBLINGS;
|
||||
}
|
19
d2j-j6/src/main/java/pxb/java/nio/file/FileVisitor.java
Normal file
19
d2j-j6/src/main/java/pxb/java/nio/file/FileVisitor.java
Normal file
@ -0,0 +1,19 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
import java.io.IOException;
|
||||
import pxb.java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
public interface FileVisitor<T> {
|
||||
|
||||
FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
|
||||
throws IOException;
|
||||
|
||||
FileVisitResult visitFile(T file, BasicFileAttributes attrs)
|
||||
throws IOException;
|
||||
|
||||
FileVisitResult visitFileFailed(T file, IOException exc)
|
||||
throws IOException;
|
||||
|
||||
FileVisitResult postVisitDirectory(T dir, IOException exc)
|
||||
throws IOException;
|
||||
}
|
71
d2j-j6/src/main/java/pxb/java/nio/file/Files.java
Normal file
71
d2j-j6/src/main/java/pxb/java/nio/file/Files.java
Normal file
@ -0,0 +1,71 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
|
||||
import pxb.java.nio.file.attribute.FileAttribute;
|
||||
import pxb.java.nio.file.spi.FileSystemProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class Files {
|
||||
public static Path write(Path path, byte[] bytes, OpenOption... options)
|
||||
throws IOException {
|
||||
path._write(bytes);
|
||||
return path;
|
||||
}
|
||||
|
||||
public static byte[] readAllBytes(Path path) throws IOException {
|
||||
return path._readAllBytes();
|
||||
}
|
||||
|
||||
public static boolean isDirectory(Path path, LinkOption... options) {
|
||||
return path._isDirectory();
|
||||
}
|
||||
|
||||
public static boolean exists(Path path, LinkOption... options) {
|
||||
return path._exists();
|
||||
}
|
||||
|
||||
public static OutputStream newOutputStream(Path path, OpenOption... options)
|
||||
throws IOException {
|
||||
return path._newOutputStream();
|
||||
}
|
||||
|
||||
public static InputStream newInputStream(Path path, OpenOption... options)
|
||||
throws IOException {
|
||||
return path._newInputStream();
|
||||
}
|
||||
|
||||
public static boolean deleteIfExists(Path path) throws IOException {
|
||||
return path._deleteIfExists();
|
||||
}
|
||||
|
||||
public static Path createDirectories(Path dir, FileAttribute... attrs)
|
||||
throws IOException {
|
||||
return dir._createDirectories();
|
||||
}
|
||||
|
||||
public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
|
||||
throws IOException {
|
||||
start._walkFileTree(visitor);
|
||||
return start;
|
||||
}
|
||||
|
||||
public static Path createTempFile(String prefix,
|
||||
String suffix,
|
||||
FileAttribute<?>... attrs) throws IOException {
|
||||
File f = File.createTempFile(prefix, suffix);
|
||||
return new FileSystemProvider.DefPath(f, null);
|
||||
}
|
||||
|
||||
public static Path copy(Path source, Path target, CopyOption... options) throws IOException {
|
||||
InputStream is = source._newInputStream();
|
||||
OutputStream os = target._newOutputStream();
|
||||
FileSystemProvider.copy(is, os);
|
||||
is.close();
|
||||
os.close();
|
||||
return target;
|
||||
}
|
||||
}
|
4
d2j-j6/src/main/java/pxb/java/nio/file/LinkOption.java
Normal file
4
d2j-j6/src/main/java/pxb/java/nio/file/LinkOption.java
Normal file
@ -0,0 +1,4 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
public interface LinkOption {
|
||||
}
|
4
d2j-j6/src/main/java/pxb/java/nio/file/OpenOption.java
Normal file
4
d2j-j6/src/main/java/pxb/java/nio/file/OpenOption.java
Normal file
@ -0,0 +1,4 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
public interface OpenOption {
|
||||
}
|
39
d2j-j6/src/main/java/pxb/java/nio/file/Path.java
Normal file
39
d2j-j6/src/main/java/pxb/java/nio/file/Path.java
Normal file
@ -0,0 +1,39 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface Path {
|
||||
|
||||
Path resolve(String other);
|
||||
|
||||
Path getFileName();
|
||||
|
||||
Path getParent();
|
||||
|
||||
File toFile();
|
||||
|
||||
String toString();
|
||||
|
||||
byte[] _readAllBytes() throws IOException;
|
||||
|
||||
OutputStream _newOutputStream() throws IOException;
|
||||
|
||||
boolean _isDirectory();
|
||||
|
||||
Path _createDirectories() throws IOException;
|
||||
|
||||
boolean _deleteIfExists();
|
||||
|
||||
boolean _exists();
|
||||
|
||||
void _write(byte[] b) throws IOException;
|
||||
|
||||
void _walkFileTree(FileVisitor<? super Path> visitor) throws IOException;
|
||||
|
||||
Path relativize(Path other);
|
||||
|
||||
InputStream _newInputStream() throws IOException;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package pxb.java.nio.file;
|
||||
|
||||
import pxb.java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SimpleFileVisitor<T> implements FileVisitor<T> {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
|
||||
throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
|
||||
throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(T file, IOException exc)
|
||||
throws IOException {
|
||||
throw exc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(T dir, IOException exc)
|
||||
throws IOException {
|
||||
if (exc != null)
|
||||
throw exc;
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package pxb.java.nio.file.attribute;
|
||||
|
||||
public interface BasicFileAttributes {
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package pxb.java.nio.file.attribute;
|
||||
|
||||
public interface FileAttribute<T> {
|
||||
}
|
@ -0,0 +1,486 @@
|
||||
package pxb.java.nio.file.spi;
|
||||
|
||||
import pxb.java.nio.file.FileSystem;
|
||||
import pxb.java.nio.file.FileVisitor;
|
||||
import pxb.java.nio.file.Path;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public abstract class FileSystemProvider {
|
||||
public static void copy(InputStream is, OutputStream os) throws IOException {
|
||||
byte[] xml = new byte[10 * 1024];
|
||||
for (int c = is.read(xml); c > 0; c = is.read(xml)) {
|
||||
os.write(xml, 0, c);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] readFile(File in) throws IOException {
|
||||
InputStream is = new FileInputStream(in);
|
||||
byte[] xml = new byte[is.available()];
|
||||
is.read(xml);
|
||||
is.close();
|
||||
return xml;
|
||||
}
|
||||
|
||||
public static byte[] readIs(InputStream is) throws IOException {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
copy(is, os);
|
||||
return os.toByteArray();
|
||||
}
|
||||
|
||||
public static void writeFile(byte[] data, File out) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(out);
|
||||
fos.write(data);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
public static FileSystemProvider ZIP = new ZipFSP();
|
||||
public static FileSystemProvider DEF = new DirFSP();
|
||||
|
||||
public static List<FileSystemProvider> installedProviders() {
|
||||
return Arrays.asList(ZIP, DEF);
|
||||
}
|
||||
|
||||
public abstract String getScheme();
|
||||
|
||||
public abstract FileSystem newFileSystem(Path path, Map<String, ?> env) throws IOException;
|
||||
|
||||
|
||||
static class CreatZipFS extends FileSystem {
|
||||
ZipOutputStream zos;
|
||||
|
||||
class CreateZipPath implements Path {
|
||||
String path;
|
||||
String displayName;
|
||||
|
||||
public CreateZipPath(String s, String displayName) {
|
||||
this.path = s;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolve(String other) {
|
||||
if (path.endsWith("/")) {
|
||||
return new CreateZipPath(path + other, null);
|
||||
}
|
||||
return new CreateZipPath(path + "/" + other, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFileName() {
|
||||
int t = path.length() - 1;
|
||||
if (path.endsWith("/")) {
|
||||
t--;
|
||||
}
|
||||
int i = path.lastIndexOf('/', t);
|
||||
if (i > 0) {
|
||||
return new CreateZipPath(path, path.substring(i + 1, t + 1));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return displayName != null ? displayName : path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getParent() {
|
||||
int i = path.lastIndexOf('/', path.length() - 2);
|
||||
if (i > 0) {
|
||||
return new CreateZipPath(path.substring(0, i), null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File toFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] _readAllBytes() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream _newOutputStream() throws IOException {
|
||||
ZipEntry e = new ZipEntry(path.substring(1));
|
||||
zos.putNextEntry(e);
|
||||
return new FilterOutputStream(zos) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
zos.closeEntry();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _isDirectory() {
|
||||
return path.endsWith("/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path _createDirectories() throws IOException {
|
||||
createDir0(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _deleteIfExists() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _exists() {
|
||||
return exists(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _write(byte[] b) throws IOException {
|
||||
OutputStream os = _newOutputStream();
|
||||
os.write(b);
|
||||
os.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _walkFileTree(FileVisitor<? super Path> visitor) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path relativize(Path other) {
|
||||
CreateZipPath p0 = (CreateZipPath) other;
|
||||
String display = path.substring(p0.path.length());
|
||||
return new CreateZipPath(p0.path, display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream _newInputStream() throws IOException {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean createDir0(String path) throws IOException {
|
||||
int x = path.lastIndexOf('/', path.length() - 2);
|
||||
if (x > 0) {
|
||||
String n = path.substring(0, x + 1);
|
||||
createDir0(n);
|
||||
}
|
||||
if (!path.contains(path)) {
|
||||
files.add(path);
|
||||
ZipEntry zipEntry = new ZipEntry(path);
|
||||
zos.putNextEntry(zipEntry);
|
||||
zos.closeEntry();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Set<String> files = new HashSet<>();
|
||||
|
||||
private boolean exists(String path) {
|
||||
return files.contains(path);
|
||||
}
|
||||
|
||||
public CreatZipFS(ZipOutputStream zipFile) {
|
||||
this.zos = zipFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
zos.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(String first, String... more) {
|
||||
return new CreateZipPath(first, null);
|
||||
}
|
||||
}
|
||||
|
||||
static class ReadZipPath implements Path {
|
||||
ZipFile zipFile;
|
||||
String path;
|
||||
String displayName;
|
||||
|
||||
public ReadZipPath(ZipFile zipFile, String path) {
|
||||
this(zipFile, path, null);
|
||||
}
|
||||
|
||||
public ReadZipPath(ZipFile zipFile, String path, String substring) {
|
||||
this.zipFile = zipFile;
|
||||
this.path = path;
|
||||
this.displayName = substring;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolve(String other) {
|
||||
if (path.endsWith("/")) {
|
||||
return new ReadZipPath(zipFile, path + other);
|
||||
} else {
|
||||
return new ReadZipPath(zipFile, path + "/" + other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFileName() {
|
||||
int t = path.length() - 1;
|
||||
if (path.endsWith("/")) {
|
||||
t--;
|
||||
}
|
||||
int i = path.lastIndexOf('/', t);
|
||||
if (i > 0) {
|
||||
return new ReadZipPath(zipFile, path, path.substring(i + 1, t + 1));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getParent() {
|
||||
int t = path.length() - 1;
|
||||
if (path.endsWith("/")) {
|
||||
t--;
|
||||
}
|
||||
int i = path.lastIndexOf('/', t);
|
||||
return i > 0 ? new ReadZipPath(zipFile, path.substring(0, i + 1), null) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File toFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return displayName != null ? displayName : path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] _readAllBytes() throws IOException {
|
||||
ZipEntry e = zipFile.getEntry(path);
|
||||
return e != null ? readIs(zipFile.getInputStream(e)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream _newOutputStream() throws FileNotFoundException {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _isDirectory() {
|
||||
ZipEntry e = zipFile.getEntry(path);
|
||||
return e != null && e.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path _createDirectories() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _deleteIfExists() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _exists() {
|
||||
ZipEntry e = zipFile.getEntry(path);
|
||||
return e != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _write(byte[] b) throws IOException {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _walkFileTree(FileVisitor<? super Path> visitor) throws IOException {
|
||||
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
|
||||
ZipEntry zipEntry = e.nextElement();
|
||||
ReadZipPath readZipPath = new ReadZipPath(zipFile, zipEntry.getName());
|
||||
if (zipEntry.isDirectory()) {
|
||||
visitor.preVisitDirectory(readZipPath, null);
|
||||
visitor.postVisitDirectory(readZipPath, null);
|
||||
} else {
|
||||
visitor.visitFile(readZipPath, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path relativize(Path other) {
|
||||
ReadZipPath p0 = (ReadZipPath) other;
|
||||
String display = path.substring(p0.path.length());
|
||||
return new ReadZipPath(zipFile, p0.path, display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream _newInputStream() throws IOException {
|
||||
ZipEntry e = zipFile.getEntry(path);
|
||||
return e != null ? zipFile.getInputStream(e) : null;
|
||||
}
|
||||
}
|
||||
|
||||
static class ReadZipFS extends FileSystem {
|
||||
ZipFile zipFile;
|
||||
|
||||
public ReadZipFS(ZipFile zipFile) {
|
||||
this.zipFile = zipFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
zipFile.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(String first, String... more) {
|
||||
return new ReadZipPath(zipFile, first);
|
||||
}
|
||||
}
|
||||
|
||||
static class ZipFSP extends FileSystemProvider {
|
||||
|
||||
@Override
|
||||
public String getScheme() {
|
||||
return "zip";
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystem newFileSystem(Path path, Map<String, ?> env) throws IOException {
|
||||
if (env != null && "true".equals(env.get("create"))) {
|
||||
return new CreatZipFS(new ZipOutputStream(path._newOutputStream()));
|
||||
} else {
|
||||
return new ReadZipFS(new ZipFile(((DefPath) path).file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class DefPath implements Path {
|
||||
File file;
|
||||
String displayName;
|
||||
|
||||
public DefPath(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public DefPath(File file, String name) {
|
||||
this.file = file;
|
||||
this.displayName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return displayName != null ? displayName : file.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolve(String other) {
|
||||
return new DefPath(new File(file, other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFileName() {
|
||||
return new DefPath(file, file.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getParent() {
|
||||
return new DefPath(file.getParentFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File toFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] _readAllBytes() throws IOException {
|
||||
return readFile(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream _newOutputStream() throws FileNotFoundException {
|
||||
return new BufferedOutputStream(new FileOutputStream(file));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _isDirectory() {
|
||||
return file.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path _createDirectories() {
|
||||
file.mkdirs();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _deleteIfExists() {
|
||||
return file.exists() && file.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean _exists() {
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _write(byte[] b) throws IOException {
|
||||
OutputStream os = _newOutputStream();
|
||||
os.write(b);
|
||||
os.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _walkFileTree(FileVisitor<? super Path> visitor) throws IOException {
|
||||
walk0(this, visitor);
|
||||
}
|
||||
|
||||
public static void walk0(DefPath dir, FileVisitor<? super Path> visitor) throws IOException {
|
||||
visitor.preVisitDirectory(dir, null);
|
||||
File[] fs = dir.file.listFiles();
|
||||
if (fs != null) {
|
||||
for (File f : fs) {
|
||||
if (f.isDirectory()) {
|
||||
walk0(new DefPath(f, null), visitor);
|
||||
} else {
|
||||
visitor.visitFile(new DefPath(f, null), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitor.postVisitDirectory(dir, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path relativize(Path other) {
|
||||
DefPath p0 = (DefPath) other;
|
||||
String display = file.getAbsolutePath().substring(p0.file.getAbsolutePath().length());
|
||||
return new DefPath(p0.file, display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream _newInputStream() throws FileNotFoundException {
|
||||
return new BufferedInputStream(new FileInputStream(file));
|
||||
}
|
||||
}
|
||||
|
||||
static class DirFSP extends FileSystemProvider {
|
||||
|
||||
@Override
|
||||
public String getScheme() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystem newFileSystem(Path path, Map<String, ?> env) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
rootProject.name = 'dex2jar'
|
||||
include ':dex-reader-api',':dex-reader', ':dex-writer', ':dex-translator', ':dex-ir', ':dex-tools', ':d2j-smali', ':d2j-base-cmd', ':d2j-jasmin'
|
||||
include ':dex-reader-api',':dex-reader', ':dex-writer', ':dex-translator', ':dex-ir', ':dex-tools', ':d2j-smali', ':d2j-base-cmd', ':d2j-jasmin', ':d2j-j6'
|
||||
|
Loading…
Reference in New Issue
Block a user