Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: dba34835ace564905c9b09686e8b2db84534eb75 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*******************************************************************************
 * Copyright (c) 2000, 2004 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);
	}
	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;
			}
			return clazz;
		}
	}
	Class clazz = makeClass(name, resolve);
	if (clazz == null) {
		return delegateLoadClass(name);
	}
	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;
	}
	if (o instanceof Class) {
		return (Class) o;
	}
	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;
}
}

Back to the top