package org.apache.axis2.tools.idea; | |
import java.io.*; | |
import java.net.URL; | |
import java.net.URLClassLoader; | |
import java.util.ArrayList; | |
import java.util.zip.ZipEntry; | |
import java.util.zip.ZipInputStream; | |
/* | |
* Copyright 2004,2005 The Apache Software Foundation. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
* | |
*/ | |
/** | |
* Author : Deepal Jayasinghe | |
* Date: Jul 22, 2005 | |
* Time: 2:25:59 PM | |
*/ | |
public class PluginClassLoader extends URLClassLoader { | |
//urls which gives to create the classLoader | |
private URL[] urls; | |
//To keep jar files inside /lib directory in the main jar | |
private ArrayList lib_jars_list; | |
/** | |
* PluginClassLoader is exetend form URLClassLoader , and the constructor | |
* has not overide the super constroctor , but has done some stuff to find out | |
* jar fils inside /lib director | |
* | |
* @param urls <code>URL</code> | |
* @param parent parent classloader <code>ClassLoader</code> | |
*/ | |
public PluginClassLoader(URL[] urls, ClassLoader parent) { | |
super(urls, parent); | |
this.urls = urls; | |
lib_jars_list = new ArrayList(); | |
findLibJars(); | |
} | |
/** | |
* This just search for jar files inside /lib dirctory and if there are any then those | |
* will be added to the arraylit (only the name of the jar file) | |
*/ | |
private void findLibJars() { | |
/** | |
* though the URL array can contains one or more urls , I have only consider the | |
* first one , that is this classLoader is only for Axis2 stuff and the classloader | |
* is created by Deployment , so there wont be any chance to have more the one urls for | |
* the URL array list | |
*/ | |
File file = new File(urls[0].getFile()); | |
try { | |
ZipInputStream zin = new ZipInputStream(new FileInputStream(file)); | |
ZipEntry entry; | |
String entryName = ""; | |
while ((entry = zin.getNextEntry()) != null) { | |
entryName = entry.getName(); | |
/** | |
* id the entry name start with /lib and end with .jar | |
* then those entry name will be added to the arraylist | |
*/ | |
if (entryName != null && (entryName.startsWith("lib/") || | |
entryName.startsWith("Lib/")) && | |
entryName.endsWith(".jar")) { | |
lib_jars_list.add(entryName); | |
} | |
} | |
zin.close(); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
/** | |
* @param name <code>String</code> Name of the file to be loaded | |
* @return <code>Class</code> return a class object if it found else | |
* will return null or classNotfoun exeption | |
* <p/> | |
* The method has ovride in the following way | |
* 1. called the super class and check to see wether the class is there | |
* if the class is found then return that , else if super returns ClassNotfoundExeption | |
* 2. Check wether the entry corresponding to the class name exsit in one of jar files | |
* in /lib director | |
* 3. If it is there get the byte array out of that and creat a Class object out of that | |
* by calling "defineClass()" , if it sucssed then return that else | |
* 4. Throw classNotfound exeption | |
* @throws ClassNotFoundException | |
*/ | |
protected Class findClass(final String name) | |
throws ClassNotFoundException { | |
Class cla = null; | |
try { | |
boolean foundClass = false; | |
try { | |
cla = super.findClass(name); | |
foundClass = true; | |
return cla; | |
} catch (ClassNotFoundException e) { | |
foundClass = false; | |
} | |
if (!foundClass) { | |
byte raw[] = getBytes(name); | |
cla = defineClass(name, raw, 0, raw.length); | |
foundClass = true; | |
return cla; | |
} | |
if (!foundClass) { | |
throw new ClassNotFoundException("Class Not found : " + name); | |
} | |
} catch (Exception e) { | |
} | |
return null; | |
} | |
/** | |
* Read jar file (/lib) one by one , then for each file craete <code>ZipInputStream</code> | |
* that and check to see wether there is any entry eith given name if it found then | |
* Creat ByteArrayOutPutStream and get the class bytes to that . | |
* after goning throgh each and evry jar file if there is no entry with given name | |
* will throug a ClassNotFound execption | |
* | |
* @param filename <code>String</code> Name of the file to be loaded (Class Name) | |
* @return bytt[] | |
* @throws java.io.IOException <code>Exception</code> | |
*/ | |
private byte[] getBytes(String filename) throws Exception { | |
String completeFileName = filename; | |
/** | |
* Replacing org.apache. -> org/apache/... | |
*/ | |
completeFileName = completeFileName.replace('.', '/').concat(".class"); | |
byte raw[] = null; | |
for (int i = 0; i < lib_jars_list.size(); i++) { | |
String libjar_name = (String) lib_jars_list.get(i); | |
InputStream in = this.getResourceAsStream(libjar_name); | |
try { | |
ZipInputStream zin = new ZipInputStream(in); | |
ZipEntry entry; | |
String entryName = ""; | |
while ((entry = zin.getNextEntry()) != null) { | |
entryName = entry.getName(); | |
if (entryName != null && | |
entryName.endsWith(completeFileName)) { | |
byte data[] = new byte[2048]; | |
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
int count; | |
while ((count = zin.read(data, 0, 2048)) != -1) { | |
out.write(data, 0, count); | |
} | |
raw = out.toByteArray(); | |
out.close(); | |
zin.close(); | |
return raw; | |
} | |
} | |
} catch (IOException e) { | |
throw e; | |
} | |
} | |
throw new ClassNotFoundException("Class Not found : " + filename); | |
} | |
} | |