package com.alimama.quanjingmonitor.tt;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
/**
* 从指定目录、jar文件加载类</p>
*
* 使用:通过下面的方式扩展当前加载器
* ClassLoader cld=new DynaClassLoader(Thread.currentThread().getContextClassLoader());
* cld.addEtries(****);
* Thread.currentThread().setContextClassLoader();
*/
public class DynaClassLoader extends ClassLoader {
//类资源,目录或者是jar
private List<File> entries = new ArrayList<File>();
/**
* @param parent
* @param entries
*/
public DynaClassLoader(ClassLoader parent, File[] entries) {
super(parent);
this.entries.addAll(Arrays.asList(entries));
}
/**
* @param parent
*/
public DynaClassLoader(ClassLoader parent) {
super(parent);
}
/**
* @param fs
*/
public void addEtries(File[] fs) {
this.entries.addAll(Arrays.asList(fs));
}
public void clear() {
this.entries.clear();
}
/**
* @param fs
*/
public void addEtry(File fs) {
this.entries.add(fs);
}
public String toString() {
String buf = "";
for (File file : entries) {
buf += file.getAbsolutePath() + ";";
}
return buf;
}
/**
* 加载class
* <p/>
* todo 是否需做缓存、仔细仿照父loadClass的过程、使用参数b
*/
protected Class loadClass(String name, boolean b)
throws ClassNotFoundException {
//优先从父加载器获取
Class clazz = null;
try {
clazz = super.loadClass(name, b);
if (clazz != null) {
return clazz;
}
} catch (ClassNotFoundException e) {
}
//System.out.println("DynaClassLoader:load class->" + name);
int dotIndex = name.indexOf(".");
String separator = File.separator;
if (separator.equals("\\")) {
separator = "\\\\";
}
String fileName;
if (dotIndex != -1) {
fileName = new StringBuilder().append(name.replaceAll("\\.", separator)).append(".class").toString();
} else {
fileName = new StringBuilder().append(name).append(".class").toString();
}
InputStream is = getLocalResourceAsStream(fileName);
if (is == null) {
throw new ClassNotFoundException(name);
}
try {
Class loadedClass = readClass(name, is);
is.close();
if (loadedClass != null) {
return loadedClass;
} else {
throw new ClassNotFoundException(name);
}
} catch (Exception e) {
throw new ClassNotFoundException(name);
} finally {
try {
is.close();
} catch (IOException e) {
}
}
}
private Class readClass(String className, InputStream is) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] bytes = new byte[1024 * 10];
int readBytes;
while ((readBytes = bis.read(bytes)) != -1) {
os.write(bytes, 0, readBytes);
}
byte[] b = os.toByteArray();
return defineClass(className, b, 0, b.length);
}
/**
*
* @param name
* @return
*/
private URL getLocalResource(String name) {
for (int i = 0; i < entries.size(); i++) {
File entry = entries.get(i);
if (entry.isDirectory() && entry.exists()) {
File f = new File(entry, name);
if (f.exists()) {
URL url;
try {
url = f.toURI().toURL();
} catch (MalformedURLException ex) {
continue;
}
return url;
}
} else if (entry.isFile() && entry.exists()) {
URL url = null;
try {
ZipFile zf = new ZipFile(entry);
name = name.replaceAll("\\\\", "/");
ZipEntry zipEntry = zf.getEntry(name);
if (zipEntry == null) {
continue;
}
String url_0_ = entry.getAbsolutePath().replaceAll("\\\\", "/");
if (!url_0_.startsWith("/")) {
url_0_ = new StringBuilder().append("/").append(url_0_).toString();
}
url = new URL(new StringBuilder().append("jar:file://").append(url_0_).append("!/").append(name).toString());
} catch (ZipException zipexception) {
zipexception.printStackTrace();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
return url;
}
}
return null;
}
private InputStream getLocalResourceAsStream(String name) {
URL res = getLocalResource(name);
if (res == null) {
return null;
}
InputStream inputstream = null;
try {
inputstream = res.openStream();
} catch (IOException ex) {
ex.printStackTrace();
}
return inputstream;
}
/**
* 加载数据流
*/
public InputStream getResourceAsStream(String name) {
InputStream _super = super.getResourceAsStream(name);
return _super != null ? _super : getLocalResourceAsStream(name);
}
/**
* 加载资源
*/
public URL getResource(String name) {
URL resource = super.getResource(name);
return resource != null ? resource : getLocalResource(name);
}
}