package com.idega.core.ldap.client.cbutil;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.zip.ZipException;
/**
* Title: test
* Description: See if we can get this crappy IDE to work properly just once.
* Copyright: Copyright (c) 2001
* Company:
* @author Chris Betts
* @version 1.0
*/
public class CBClassLoader extends ClassLoader
{
/**
* a cached list of classes to speed the return of twice loaded classes.
*/
protected Hashtable classes = new Hashtable();
protected Hashtable lowerCaseClasses = new Hashtable();
/**
* The resource loader provides the interface to a group of zip files.
*/
protected CBResourceLoader resourceLoader;
/**
* Constructor - note that that the class is useless until at least one resource file has been
* registered with it using the addResource() method.
*/
public CBClassLoader(CBResourceLoader loader)
{
CBUtility.log("Started CBClassLoader", 7);
this.resourceLoader = loader;
}
/**
* Translates the '.' seperators of Class package names into the \ seperators needed for
* the internal directory structure of the zip file.
*/
protected String translateClassName(String name)
{
if (name.endsWith(".class")) {
name = name.replace('.','/');
}
else {
name = name.replace('.','/') + ".class";
}
CBUtility.log("looking for class: " + name, 8);
return name;
}
/**
* This sample function for reading class implementations reads
* them from the local file system
*/
private byte[] getClassFromResourceFiles(String className)
throws ZipException
{
className = translateClassName(className);
return this.resourceLoader.getResource(className);
}
/**
* This is a simple version for external clients since they
* will always want the class resolved before it is returned
* to them.
*/
public Class findClass(String className) throws ClassNotFoundException
{
return (findClass(className, true));
}
/**
* This is the required version of findClass which is called
* both from findClass above and from the internal function
* loadClass of the parent.
*/
public synchronized Class findClass(String className, boolean resolveIt)
throws ClassNotFoundException
{
Class result;
byte classData[];
CBUtility.log(" >>>>>> Load class : "+className,8);
/* Check our local cache of classes */
Object local = this.classes.get(className);
if (local != null)
{
if (local instanceof String && "".equals(local))
{
CBUtility.log(" >>>>>> ignoring '" + className + "' (failed to load previously).", 8);
throw new ClassNotFoundException("ignoring class '" + className + "' (failed to load previously).");
}
CBUtility.log(" >>>>>> returning cached result.", 8);
return (Class)local;
}
/* Check with the primordial class loader */
try {
result = super.findSystemClass(className);
CBUtility.log(" >>>>>> returning system class (in CLASSPATH).", 8);
return result;
} catch (ClassNotFoundException e) {
CBUtility.log(" >>>>>> Not a system class - looking in zip files.", 8);
}
/* Try to load it from our repository */
try
{
classData = getClassFromResourceFiles(className);
}
catch (ZipException e)
{
this.classes.put(className, ""); // stick a dummy entry in as a warning to others...
this.lowerCaseClasses.put(className.toLowerCase(), "");
throw new ClassNotFoundException("Error getting className: '" + className + "' : " + e);
}
if (classData == null)
{
this.classes.put(className, ""); // stick a dummy entry in as a warning to others...
this.lowerCaseClasses.put(className.toLowerCase(), "");
throw new ClassNotFoundException();
}
/* Define it (parse the class file) */
result = defineClass(className, classData, 0, classData.length);
if (result == null) {
this.classes.put(className, ""); // stick a dummy entry in as a warning to others...
this.lowerCaseClasses.put(className.toLowerCase(), "");
throw new ClassFormatError();
}
if (resolveIt) {
resolveClass(result);
}
this.classes.put(className, result);
this.lowerCaseClasses.put(className.toLowerCase(), result);
CBUtility.log(" >>>>>> Returning newly loaded zipped class. " + className, 8);
return result;
}
public URL getResource(String name)
{
URL bloop = super.getResource(name);
return bloop;
}
/**
* Returns a 'jar url' to the specified resource.
* @param name the name of the resource to look for (e.g. 'HelpSet.hs')
* @return the url of the resource, (e.g. 'jar:file:myjarfile.jar!/HelpSet.hs'.
* - this will be null if the resource cannot be found in the known
* jar file.
*/
protected URL findResource(String name)
{
CBUtility.log("CLASSLOADER MAGIC: looking for: " + name,8);
CBJarResource container = this.resourceLoader.getJarContainingResource(name);
CBUtility.log("CLASSLOADER MAGIC: found container: " + ((container==null)?"null":container.getZipFileName()), 8);
if (container==null) {
return null;
}
String zipFile = container.getZipFileName();
String url = "jar:file:" + zipFile + "!/" + name;
CBUtility.log("CLASSLOADER MAGIC: constructed url: " + url, 8);
try
{
return new URL(url);
}
catch (MalformedURLException e)
{
CBUtility.log("Unable to construct url: " +url + "\n -> due to " + e, 1);
return null;
}
}
public String toString()
{
return "CBClassLoader";
}
public InputStream getResourceAsStream(String name)
{
return super.getResourceAsStream(name);
}
}