blob: df0a5a0876df1dfe21f33d309f5e94dfcb4cbdd6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.eval.target;
import java.util.*;
/**
* A code snippet class loader is a class loader that loads code snippet classes and global
* variable classes.
*/
public class CodeSnippetClassLoader extends ClassLoader {
/**
* Whether the code snippet support classes should be given by the IDE
* or should be found on disk.
*/
static boolean DEVELOPMENT_MODE = false;
Hashtable loadedClasses = new Hashtable();
/**
* Asks the class loader that loaded this class to load the given class.
* @throws a ClassNotFoundException if it could not be loaded.
*/
private Class delegateLoadClass(String name) throws ClassNotFoundException {
ClassLoader myLoader = getClass().getClassLoader();
if (myLoader == null) {
return Class.forName(name);
} else {
return myLoader.loadClass(name);
}
}
/**
* Loads the given class. If the class is known to this runner, returns it.
* If only the class definition is known to this runner, makes it a class and returns it.
* Otherwise delegates to the real class loader.
*/
protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (DEVELOPMENT_MODE) {
try {
return delegateLoadClass(name);
} catch (ClassNotFoundException e) {
Class clazz = makeClass(name, resolve);
if (clazz == null) {
throw e;
} else {
return clazz;
}
}
} else {
Class clazz = makeClass(name, resolve);
if (clazz == null) {
return delegateLoadClass(name);
} else {
return clazz;
}
}
}
/**
* Loads the given class either from the stored class definition or from the system.
* Returns the existing class if it has already been loaded.
* Returns null if no class definition can be found.
*/
Class loadIfNeeded(String className) {
Class clazz = null;
if (!supportsHotCodeReplacement()) {
clazz = findLoadedClass(className);
}
if (clazz == null) {
try {
clazz = loadClass(className, true);
} catch (NoClassDefFoundError e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return clazz;
}
/**
* Makes the class definition known by this code snippet runner a real class and
* returns it.
* Returns null if there is no class definition.
*/
private Class makeClass(String name, boolean resolve) {
Object o = this.loadedClasses.get(name);
if (o == null) {
return null;
} else {
if (o instanceof Class) {
return (Class) o;
} else {
byte[] classDefinition = (byte[]) o;
Class clazz = defineClass(null, classDefinition, 0, classDefinition.length);
if (resolve) {
resolveClass(clazz);
}
this.loadedClasses.put(name, clazz);
return clazz;
}
}
}
/**
* Stores the given class definition for the given class.
*/
void storeClassDefinition(String className, byte[] classDefinition) {
Object clazz = this.loadedClasses.get(className);
if (clazz == null || supportsHotCodeReplacement()) {
this.loadedClasses.put(className, classDefinition);
}
}
/**
* Returns whether this class loader supports Hot Code Replacement.
*/
protected boolean supportsHotCodeReplacement() {
return false;
}
}