home *** CD-ROM | disk | FTP | other *** search
- package com.bitmechanic.gsp;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.text.SimpleDateFormat;
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Vector;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipFile;
-
- public class GspClassLoader extends ClassLoader implements GspReloadingClassLoader {
- private Hashtable currentClassloaders;
- private Hashtable reloadableClasses;
- private Vector classLoaders;
- private static boolean debug;
- private static boolean debugTracing;
- private static ClassLoader parentLoader;
- private Vector repository;
- private static final SimpleDateFormat traceDateFormat = new SimpleDateFormat("[dd/MM/yyyy HH:mm:ss zz]");
- public static int generationCounter;
-
- protected GspClassLoader() {
- this.classLoaders = new Vector();
- this.currentClassloaders = new Hashtable();
- }
-
- public GspClassLoader(File var1) {
- this(new File[]{var1});
- }
-
- public GspClassLoader(File[] var1) {
- this.currentClassloaders = new Hashtable();
- this.reloadableClasses = new Hashtable();
- this.classLoaders = new Vector();
- parentLoader = this.getClass().getClassLoader();
- GspInternalClassLoader var2 = new GspInternalClassLoader(this, this);
- this.classLoaders.addElement(var2);
- this.repository = new Vector(var1.length);
-
- for(int var3 = 0; var3 < var1.length; ++var3) {
- File var4 = var1[var3];
- if (!var4.exists()) {
- throw new IllegalArgumentException("Repository " + var4.getAbsolutePath() + " doesn't exist!");
- }
-
- if (!var4.canRead()) {
- throw new IllegalArgumentException("Don't have read access for file " + var4.getAbsolutePath());
- }
-
- if (!var4.isDirectory() && !var4.getName().endsWith(".jar") && !var4.getName().endsWith(".zip")) {
- throw new IllegalArgumentException(var4.getAbsolutePath() + " is not a " + "directory or zip/jar file.");
- }
-
- this.repository.addElement(var4);
- }
-
- }
-
- private ClassCacheEntry getCurrentClassCacheEntry(String var1) {
- GspInternalClassLoader var2 = this.getCurrentClassloader(var1);
- return var2.getClassCacheEntry(var1);
- }
-
- private Class getNewClass(String var1, byte[] var2, int var3, int var4, ClassCacheEntry var5) {
- GspInternalClassLoader var6 = this.getNewClassloader(var1);
- Class var7 = var6.defineClass(var1, var2, var3, var4, var5);
- var5.loadedClass = var7;
- return var7;
- }
-
- private GspInternalClassLoader getCurrentClassloader(String var1) {
- Integer var2 = (Integer)this.currentClassloaders.get(var1);
- int var3 = 0;
- if (var2 != null) {
- var3 = var2;
- }
-
- return (GspInternalClassLoader)this.classLoaders.elementAt(var3);
- }
-
- private GspInternalClassLoader getNewClassloader(String var1) {
- Integer var2 = (Integer)this.currentClassloaders.get(var1);
- int var3 = -1;
- if (var2 != null) {
- var3 = var2;
- }
-
- ++var3;
- this.currentClassloaders.put(var1, new Integer(var3));
- Vector var5 = this.classLoaders;
- synchronized(var5){}
-
- GspInternalClassLoader var4;
- try {
- if (var3 >= this.classLoaders.size()) {
- GspInternalClassLoader var7 = new GspInternalClassLoader(this, this);
- this.classLoaders.addElement(var7);
- var4 = var7;
- return var4;
- }
-
- var4 = (GspInternalClassLoader)this.classLoaders.elementAt(var3);
- } catch (Throwable var9) {
- throw var9;
- }
-
- return var4;
- }
-
- private void storeExternalClassDef(String var1, ClassCacheEntry var2) {
- GspInternalClassLoader var3 = this.getCurrentClassloader(var1);
- var3.storeExternalClassDef(var1, var2);
- }
-
- protected synchronized boolean shouldReloadClass(ClassCacheEntry var1) {
- if (var1.isSystemClass()) {
- if (this.reloadableClasses.get(var1.loadedClass.getName()) != null) {
- return true;
- } else {
- this.debugTrace(var1.loadedClass.getName() + " is from system : can't reload.");
- return false;
- }
- } else {
- return var1.origin.lastModified() > var1.lastModified;
- }
- }
-
- protected synchronized boolean shouldReload(String var1) {
- ClassCacheEntry var2 = this.getCurrentClassCacheEntry(var1);
- this.debugTrace("Should we reload " + var1 + "?");
- if (var2 == null) {
- this.debugTrace(var1 + " wasn't even loaded.");
- return false;
- } else {
- boolean var3 = this.shouldReloadClass(var2);
- this.debugTrace(var2.origin.lastModified() + " > " + var2.lastModified + " : " + (var3 ? " yes." : " no."));
- return var3;
- }
- }
-
- private void trace(String var1) {
- if (debug) {
- System.err.println("gcl#" + Integer.toString(generationCounter) + ": " + var1);
- }
-
- }
-
- private void debugTrace(String var1) {
- if (debugTracing) {
- System.err.println("gcl#" + Integer.toString(generationCounter) + ": " + var1);
- }
-
- }
-
- public synchronized Class publicLoadClass(String var1, boolean var2) throws ClassNotFoundException {
- return this.loadClass(var1, var2);
- }
-
- protected synchronized Class loadClass(String var1, boolean var2) throws ClassNotFoundException {
- Class var3 = null;
- this.debugTrace("Asked to load " + var1);
- ClassCacheEntry var4 = this.getCurrentClassCacheEntry(var1);
- if (var4 != null && var4.loadedClass != null) {
- var3 = var4.loadedClass;
- this.debugTrace("Loaded class " + var1 + " from cache.");
- if (var2) {
- ((ClassLoader)this).resolveClass(var3);
- }
-
- if (!this.shouldReloadClass(var4)) {
- return var3;
- }
- }
-
- try {
- if (this.reloadableClasses.get(var1) != null) {
- var3 = this.reloadClass(var1, var2);
- }
- } catch (ClassNotFoundException var7) {
- var3 = null;
- }
-
- if (var3 != null) {
- return var3;
- } else {
- try {
- if (parentLoader != null) {
- var3 = parentLoader.loadClass(var1);
- if (var3 != null) {
- this.debugTrace("loaded from parent classloader:" + var1);
- } else {
- this.debugTrace("couldn't load from parent classloader:" + var1);
- }
- } else {
- var3 = this.loadSystemClass(var1, var2);
- if (var3 != null) {
- this.debugTrace("loaded from system classloader:" + var1);
- } else {
- this.debugTrace("couldn't load from system classloader:" + var1);
- }
- }
-
- if (var3 != null) {
- ClassCacheEntry var5 = new ClassCacheEntry();
- var5.origin = null;
- var5.loadedClass = var3;
- var5.lastModified = Long.MAX_VALUE;
- this.storeExternalClassDef(var1, var5);
- return var3;
- }
- } catch (ClassNotFoundException var6) {
- this.debugTrace("class " + var1 + " not found by system/parent classloader");
- }
-
- return this.reloadClass(var1, var2);
- }
- }
-
- public void setReloadClass(String var1) {
- this.debugTrace("setting to reloadable: " + var1);
- this.reloadableClasses.put(var1, "true");
- }
-
- private Class reloadClass(String var1, boolean var2) throws ClassNotFoundException {
- Enumeration var3 = this.repository.elements();
- Object var4 = null;
- ClassCacheEntry var5 = new ClassCacheEntry();
-
- while(var3.hasMoreElements()) {
- File var7 = (File)var3.nextElement();
-
- byte[] var6;
- try {
- if (var7.isDirectory()) {
- var6 = this.loadClassFromDirectory(var7, var1, var5);
- } else {
- var6 = this.loadClassFromZipfile(var7, var1, var5);
- }
- } catch (IOException var9) {
- this.trace(((Throwable)var9).toString());
- var6 = null;
- }
-
- if (var6 != null) {
- if (var7.isFile()) {
- this.debugTrace("Loaded class " + var1 + " from zip file " + var7.getName());
- } else {
- this.debugTrace("Loaded class " + var1 + " from directory " + var7.getName());
- }
-
- Class var10 = this.getNewClass(var1, var6, 0, var6.length, var5);
- this.debugTrace("Defined class " + var1);
- if (var2) {
- ((ClassLoader)this).resolveClass(var10);
- this.debugTrace("Resolved class " + var1);
- }
-
- return var10;
- }
- }
-
- this.debugTrace(var1 + " not found in repository");
- throw new ClassNotFoundException(var1 + " not found");
- }
-
- private Class loadSystemClass(String var1, boolean var2) throws NoClassDefFoundError, ClassNotFoundException {
- Class var3 = ((ClassLoader)this).findSystemClass(var1);
- this.debugTrace("Loaded class " + var1 + " from system.");
- if (var2) {
- ((ClassLoader)this).resolveClass(var3);
- }
-
- return var3;
- }
-
- private boolean securityAllowsClass(String var1) {
- try {
- SecurityManager var2 = System.getSecurityManager();
- if (var2 == null) {
- return true;
- } else {
- int var3 = var1.lastIndexOf(46);
- String var4 = var3 > -1 ? var1.substring(0, var3) : "";
- var2.checkPackageDefinition(var4);
- return true;
- }
- } catch (SecurityException var5) {
- return false;
- }
- }
-
- private byte[] loadClassFromDirectory(File var1, String var2, ClassCacheEntry var3) throws IOException {
- String var4 = var2.replace('.', File.separatorChar) + ".class";
- if (!Character.isJavaIdentifierStart(var4.charAt(0))) {
- int var5;
- for(var5 = 1; !Character.isJavaIdentifierStart(var4.charAt(var5)); ++var5) {
- }
-
- var4 = var4.substring(var5);
- }
-
- File var12 = new File(var1, var4);
- if (var12.exists()) {
- var3.origin = var12;
- FileInputStream var6 = new FileInputStream(var12);
-
- byte[] var7;
- try {
- var7 = this.loadBytesFromStream(var6, (int)var12.length());
- } finally {
- ((InputStream)var6).close();
- }
-
- return var7;
- } else {
- return null;
- }
- }
-
- private byte[] loadClassFromZipfile(File var1, String var2, ClassCacheEntry var3) throws IOException {
- String var4 = var2.replace('.', '/') + ".class";
- ZipFile var5 = new ZipFile(var1);
-
- B var6;
- try {
- ZipEntry var9 = var5.getEntry(var4);
- if (var9 == null) {
- var6 = null;
- return (byte[])var6;
- }
-
- var3.origin = var1;
- var6 = this.loadBytesFromStream(var5.getInputStream(var9), (int)var9.getSize());
- } finally {
- var5.close();
- }
-
- return (byte[])var6;
- }
-
- private byte[] loadBytesFromStream(InputStream var1, int var2) throws IOException {
- byte[] var3 = new byte[var2];
-
- int var4;
- for(int var5 = 0; var2 > 0 && (var4 = var1.read(var3, var5, var2)) != -1; var2 -= var4) {
- var5 += var4;
- }
-
- return var3;
- }
-
- public InputStream getResourceAsStream(String var1) {
- InputStream var2 = ClassLoader.getSystemResourceAsStream(var1);
- if (var2 == null) {
- Enumeration var3 = this.repository.elements();
-
- while(var3.hasMoreElements()) {
- File var4 = (File)var3.nextElement();
- if (var4.isDirectory()) {
- var2 = this.loadResourceFromDirectory(var4, var1);
- } else {
- var2 = this.loadResourceFromZipfile(var4, var1);
- }
-
- if (var2 != null) {
- break;
- }
- }
- } else {
- this.debugTrace("Loaded resource " + var1 + " from system.");
- }
-
- return var2;
- }
-
- private InputStream loadResourceFromDirectory(File var1, String var2) {
- String var3 = var2.replace('/', File.separatorChar);
- File var4 = new File(var1, var3);
- if (var4.exists()) {
- try {
- this.debugTrace("Loaded resource " + var2 + " from directory" + var1.getName());
- return new FileInputStream(var4);
- } catch (FileNotFoundException var6) {
- ((Throwable)var6).printStackTrace();
- return null;
- }
- } else {
- return null;
- }
- }
-
- private InputStream loadResourceFromZipfile(File var1, String var2) {
- try {
- ZipFile var3 = new ZipFile(var1);
- ZipEntry var4 = var3.getEntry(var2);
- if (var4 != null) {
- this.debugTrace("Loaded resource " + var2 + " from zip file" + var1.getName());
- return var3.getInputStream(var4);
- } else {
- return null;
- }
- } catch (IOException var5) {
- this.trace(((Throwable)var5).toString());
- return null;
- }
- }
-
- public URL getResource(String var1) {
- URL var2 = ClassLoader.getSystemResource(var1);
- if (var2 != null) {
- this.debugTrace("Loaded resource " + var1 + " from system.");
- return var2;
- } else {
- Enumeration var3 = this.repository.elements();
-
- while(var3.hasMoreElements()) {
- File var4 = (File)var3.nextElement();
- if (var4.isDirectory()) {
- String var5 = var1.replace('/', File.separatorChar);
- File var6 = new File(var4, var5);
- if (var6.exists()) {
- this.debugTrace("Loaded resource " + var1 + " from directory " + var4.getName());
-
- try {
- return new URL("file://" + var6.getAbsolutePath());
- } catch (MalformedURLException var8) {
- ((Throwable)var8).printStackTrace();
- return null;
- }
- }
- }
- }
-
- return null;
- }
- }
- }
-