package javassist.android;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.content.Context;
import dalvik.system.DexClassLoader;
public class JarFile {
private static final String RESOURCE_CLASSES_DEX = "classes.dex";
private final DexClassLoader classLoader;
public JarFile(Context context, String path) throws FileNotFoundException, IOException {
this.classLoader = loadClasses(loadFile(context, path), context, new File(path).getName());
}
public Class<?> getClass(String classname) throws ClassNotFoundException {
if (null == this.classLoader) {
throw new ClassNotFoundException();
}
return this.classLoader.loadClass(classname);
}
private static DexClassLoader loadFile(Context context, String path) throws FileNotFoundException {
final File f = new File(path);
final String fileName = f.getName().toLowerCase();
if (!fileName.endsWith(".jar") && !fileName.endsWith(".zip") && !fileName.endsWith(".apk")) {
throw new UnsupportedOperationException("unsupported file type.");
}
if (!f.exists()) {
throw new FileNotFoundException(String.format("'%s' is not exist.", f.getAbsolutePath()));
}
return new DexClassLoader(
path,
context.getCacheDir().getAbsolutePath(),
context.getApplicationInfo().nativeLibraryDir,
context.getClassLoader());
}
private static DexClassLoader loadClasses(DexClassLoader jarLoader, Context context, String jarFileName) throws IOException {
final InputStream is = jarLoader.getResourceAsStream(RESOURCE_CLASSES_DEX);
if (null == is) {
return null;
}
final File dir = new File(context.getFilesDir(), jarFileName);
final File dexFile = new File(dir, RESOURCE_CLASSES_DEX);
try {
if (!dir.exists()) {
if (!dir.mkdirs()) {
throw new IOException(String.format("cannot make directory '%s'.", dir.getAbsolutePath()));
}
} else if (!dir.isDirectory()) {
throw new IllegalStateException(String.format("cannot make directory '%s'.", dir.getAbsolutePath()));
}
final FileOutputStream fos = new FileOutputStream(dexFile);
try {
final byte[] buffer = new byte[4096];
for (;;) {
final int n = is.read(buffer);
if (0 > n) {
break;
}
fos.write(buffer, 0, n);
}
fos.flush();
} finally {
fos.close();
}
return new DexClassLoader(
dexFile.getAbsolutePath(),
context.getCacheDir().getAbsolutePath(),
context.getApplicationInfo().nativeLibraryDir,
context.getClassLoader());
} finally {
final String[] files = dir.list();
if (null != files) {
for (String file : files) {
new File(dir, file).delete();
}
}
dir.delete();
is.close();
}
}
}