blob: 5c05a9cf652b68ec874af1afdb9dd10349a7581f [file] [log] [blame]
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);
}
}