Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
PluginClassLoader.java
1 package ij.io;
2 import java.io.*;
3 import java.net.*;
4 import java.util.*;
5 import java.util.zip.*;
6 import ij.IJ;
7 
20 public class PluginClassLoader extends ClassLoader {
21  protected String path;
22  protected Hashtable cache = new Hashtable();
23  protected Vector jarFiles;
24 
32  public PluginClassLoader(String path) {
33  this.path = path;
34  jarFiles = new Vector();
35  //find all JAR files on the path and subdirectories
36  File f = new File(path);
37  String[] list = f.list();
38  if (list==null)
39  return;
40  for (int i=0; i<list.length; i++) {
41  f=new File(path, list[i]);
42  if (f.isDirectory()) {
43  String[] innerlist = f.list();
44  if (innerlist==null) continue;
45  for (int j=0; j<innerlist.length; j++) {
46  File g = new File(f,innerlist[j]);
47  if (g.isFile()) addJAR(g);
48  }
49  } else
50  addJAR(f);
51  }
52  }
53 
54  private void addJAR(File f) {
55  if (f.getName().endsWith(".jar") || f.getName().endsWith(".zip"))
56  jarFiles.addElement(f);
57  }
58 
63  public URL getResource(String name) {
64  // try system loader first
65  URL res = super.getSystemResource(name);
66  if (res != null) return res;
67 
68  File resFile;
69 
70  //try plugins directory
71  try {
72  resFile = new File(path, name);
73  if (resFile.exists()) {
74  res = makeURL(resFile);
75  return res;
76  }
77  }
78  catch (Exception e) {}
79 
80  //try subfolders
81  resFile = new File(path);
82  String[] list = resFile.list();
83  if (list!=null) {
84  for (int i=0; i<list.length; i++) {
85  resFile = new File(path, list[i]);
86  if (resFile.isDirectory()) {
87  try {
88  File f = new File(path+list[i], name);
89  if (f.exists()) {
90  res = makeURL(f);
91  return res;
92  }
93  }
94  catch (Exception e) {}
95 
96  }
97  }
98  }
99 
100  //otherwise look in JAR files
101  byte [] resourceBytes;
102  for (int i=0; i<jarFiles.size(); i++) {
103  try {
104  File jf = (File)jarFiles.elementAt(i);
105  resourceBytes = loadFromJar(jf.getPath(), name);
106  if (resourceBytes != null) {
107  res = makeURL(name, jf);
108  return res;
109  }
110  }
111  catch (MalformedURLException e) {
112  IJ.error(e.toString());
113  }
114  catch (IOException e) {
115  IJ.error(e.toString());
116  }
117  }
118  return null;
119  }
120 
121  // make a URL from a file
122  private URL makeURL (File fil) throws MalformedURLException {
123  URL url = new URL("file","",fil.toString());
124  return url;
125  }
126 
127  // make a URL from a file within a JAR
128  private URL makeURL (String name, File jar) throws MalformedURLException {
129  StringBuffer filename = new StringBuffer("file:///");
130  filename.append(jar.toString());
131  filename.append("!/");
132  filename.append(name);
133  //filename.insert(0,'/');
134  String sf = filename.toString();
135  String sfu = sf.replace('\\','/');
136  URL url = new URL("jar","",sfu);
137  return url;
138  }
139 
144  public InputStream getResourceAsStream(String name) {
145  //try the system loader first
146  InputStream is = super.getSystemResourceAsStream(name);
147  if (is != null) return is;
148 
149  File resFile;
150 
151  //try plugins directory
152  resFile = new File(path, name);
153  try { // read the byte codes
154  is = new FileInputStream(resFile);
155  }
156  catch (Exception e) {}
157  if (is != null) return is;
158 
159  //try subdirectories
160  resFile = new File(path);
161  String[] list = resFile.list();
162  if (list!=null) {
163  for (int i=0; i<list.length; i++) {
164  resFile = new File(path, list[i]);
165  if (resFile.isDirectory()) {
166  try {
167  File f = new File(path+list[i], name);
168  is = new FileInputStream(f);
169  }
170  catch (Exception e) {}
171  if (is != null) return is;
172  }
173  }
174  }
175 
176  //look in JAR files
177  byte [] resourceBytes;
178  for (int i=0; i<jarFiles.size(); i++) {
179  try {
180  File jf = (File)jarFiles.elementAt(i);
181  resourceBytes = loadFromJar(jf.getPath(), name);
182  if (resourceBytes != null){
183  is = new ByteArrayInputStream(resourceBytes);
184  return is;
185  }
186  }
187  catch (Exception e) {
188  IJ.error(e.toString());
189  }
190  }
191  return null;
192  }
193 
198  public Class loadClass(String className) throws ClassNotFoundException {
199  return (loadClass(className, true));
200  }
201 
207  public synchronized Class loadClass(String className, boolean resolveIt) throws ClassNotFoundException {
208 
209  Class result;
210  byte[] classBytes;
211 
212  // try the local cache of classes
213  result = (Class)cache.get(className);
214  if (result != null) {
215  return result;
216  }
217 
218  // try the system class loader
219  try {
220  result = super.findSystemClass(className);
221  return result;
222  }
223  catch (Exception e) {}
224 
225  // Try to load it from plugins directory
226  classBytes = loadClassBytes(className);
227  //IJ.log("loadClass: "+ className + " "+ (classBytes!=null?""+classBytes.length:"null"));
228  if (classBytes==null) {
229  //IJ.log("ClassNotFoundException");
230  throw new ClassNotFoundException(className);
231  }
232 
233  // Define it (parse the class file)
234  result = defineClass(className, classBytes, 0, classBytes.length);
235  if (result == null) {
236  throw new ClassFormatError();
237  }
238 
239  //Resolve if necessary
240  if (resolveIt) resolveClass(result);
241 
242  cache.put(className, result);
243  return result;
244  }
245 
253  protected byte[] loadClassBytes(String name) {
254  byte [] classBytes = null;
255  classBytes = loadIt(path, name);
256  if (classBytes == null) {
257  classBytes = loadFromSubdirectory(path, name);
258  if (classBytes == null) {
259  // Attempt to get the class data from the JAR files.
260  for (int i=0; i<jarFiles.size(); i++) {
261  try {
262  File jf = (File)jarFiles.elementAt(i);
263  classBytes = loadClassFromJar(jf.getPath(), name);
264  if (classBytes != null)
265  return classBytes;
266  }
267  catch (Exception e) {
268  //no problem, try the next one
269  }
270  }
271  }
272  }
273  return classBytes;
274  }
275 
276  // Loads the bytes from file
277  private byte [] loadIt(String path, String classname) {
278  String filename = classname.replace('.','/');
279  filename += ".class";
280  File fullname = new File(path, filename);
281  //ij.IJ.write("loadIt: " + fullname);
282  try { // read the byte codes
283  InputStream is = new FileInputStream(fullname);
284  int bufsize = (int)fullname.length();
285  byte buf[] = new byte[bufsize];
286  is.read(buf, 0, bufsize);
287  is.close();
288  return buf;
289  } catch (Exception e) {
290  return null;
291  }
292  }
293 
294  private byte [] loadFromSubdirectory(String path, String name) {
295  File f = new File(path);
296  String[] list = f.list();
297  if (list!=null) {
298  for (int i=0; i<list.length; i++) {
299  //ij.IJ.write(path+" "+list[i]);
300  f=new File(path, list[i]);
301  if (f.isDirectory()) {
302  byte [] buf = loadIt(path+list[i], name);
303  if (buf!=null)
304  return buf;
305  }
306  }
307  }
308  return null;
309  }
310 
311  // Load class from a JAR file
312  byte[] loadClassFromJar(String jar, String className) {
313  String name = className.replace('.','/');
314  name += ".class";
315  return loadFromJar(jar, name);
316  }
317 
318  // Load class or resource from a JAR file
319  byte[] loadFromJar(String jar, String name) {
320  BufferedInputStream bis = null;
321  try {
322  ZipFile jarFile = new ZipFile(jar);
323  Enumeration entries = jarFile.entries();
324  while (entries.hasMoreElements()) {
325  ZipEntry entry = (ZipEntry) entries.nextElement();
326  if (entry.getName().equals(name)) {
327  bis = new BufferedInputStream(jarFile.getInputStream(entry));
328  int size = (int)entry.getSize();
329  byte[] data = new byte[size];
330  int b=0, eofFlag=0;
331  while ((size - b) > 0) {
332  eofFlag = bis.read(data, b, size - b);
333  if (eofFlag==-1) break;
334  b += eofFlag;
335  }
336  return data;
337  }
338  }
339  }
340  catch (Exception e) {}
341  finally {
342  try {if (bis!=null) bis.close();}
343  catch (IOException e) {}
344  }
345  return null;
346  }
347 
348 }