File Source: PluginClassLoader.java
/*
P/P * Method: com.dmdirc.plugins.PluginClassLoader__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 package com.dmdirc.plugins;
24
25 import com.dmdirc.util.resourcemanager.ResourceManager;
26
27 import java.io.IOException;
28
29 public class PluginClassLoader extends ClassLoader {
30 /** The plugin Info object for the plugin we are loading. */
31 final PluginInfo pluginInfo;
32
33 /**
34 * Create a new PluginClassLoader.
35 *
36 * @param info PluginInfo this classloader will be for
37 */
38 public PluginClassLoader(final PluginInfo info) {
/*
P/P * Method: void com.dmdirc.plugins.PluginClassLoader(PluginInfo)
*
* Postconditions:
* this.pluginInfo == info
* init'ed(this.pluginInfo)
*/
39 super();
40 pluginInfo = info;
41 }
42
43 /**
44 * Create a new PluginClassLoader.
45 *
46 * @param info PluginInfo this classloader will be for
47 * @param parent Parent ClassLoader
48 */
49 private PluginClassLoader(final PluginInfo info, final PluginClassLoader parent) {
/*
P/P * Method: void com.dmdirc.plugins.PluginClassLoader(PluginInfo, PluginClassLoader)
*
* Postconditions:
* this.pluginInfo == info
* init'ed(this.pluginInfo)
*/
50 super(parent);
51 pluginInfo = info;
52 }
53
54 /**
55 * Get a PluginClassLoader that is a subclassloader of this one.
56 *
57 * @param info PluginInfo the new classloader will be for
58 * @return A classloader configured with this one as its parent
59 */
60 public PluginClassLoader getSubClassLoader(final PluginInfo info) {
/*
P/P * Method: PluginClassLoader getSubClassLoader(PluginInfo)
*
* Postconditions:
* return_value == &new PluginClassLoader(getSubClassLoader#1)
* new PluginClassLoader(getSubClassLoader#1) num objects == 1
* return_value.pluginInfo == info
* init'ed(return_value.pluginInfo)
*/
61 return (new PluginClassLoader(info, this));
62 }
63
64 /**
65 * Load the plugin with the given className
66 *
67 * @param name Class Name of plugin
68 * @return plugin class
69 * @throws ClassNotFoundException if the class to be loaded could not be found.
70 */
71 @Override
72 public Class<?> loadClass(final String name) throws ClassNotFoundException {
/*
P/P * Method: Class loadClass(String)
*
* Preconditions:
* (soft) com/dmdirc/plugins/GlobalClassLoader.me.resourcesList != null
* (soft) name != null
* (soft) com/dmdirc/plugins/GlobalClassLoader.me != null
* (soft) init'ed(this.pluginInfo.myResourceManager)
* (soft) this.pluginInfo != null
* (soft) init'ed(this.pluginInfo.metaData)
* (soft) this.pluginInfo.url != null
*
* Postconditions:
* init'ed(com/dmdirc/plugins/GlobalClassLoader.me)
* init'ed(return_value)
* init'ed(this.pluginInfo.myResourceManager)
* new GlobalClassLoader(getGlobalClassLoader#1) num objects == 0
* init'ed(new GlobalClassLoader(getGlobalClassLoader#1).resourcesList)
* new HashMap(GlobalClassLoader#1) num objects == 0
*/
73 return loadClass(name, true);
74 }
75
76 /**
77 * Have we already loaded the given class name?
78 *
79 * @param name Name to check.
80 * @param checkGlobal Should we check if the GCL has loaded it aswell?
81 * @return True if the specified class is loaded, false otherwise
82 */
83 public boolean isClassLoaded(final String name, final boolean checkGlobal) {
84 // Don't duplicate a class
/*
P/P * Method: bool isClassLoaded(String, bool)
*
* Preconditions:
* (soft) init'ed(com/dmdirc/plugins/GlobalClassLoader.me)
*
* Postconditions:
* com/dmdirc/plugins/GlobalClassLoader.me == One-of{old com/dmdirc/plugins/GlobalClassLoader.me, &new GlobalClassLoader(getGlobalClassLoader#1)}
* init'ed(com/dmdirc/plugins/GlobalClassLoader.me)
* init'ed(return_value)
* new GlobalClassLoader(getGlobalClassLoader#1) num objects <= 1
* init'ed(new GlobalClassLoader(getGlobalClassLoader#1).resourcesList)
* new HashMap(GlobalClassLoader#1) num objects <= 1
*/
85 final Class existing = findLoadedClass(name);
86 final boolean gcl = (checkGlobal) ? GlobalClassLoader.getGlobalClassLoader().isClassLoaded(name) : false;
87 return (existing != null || gcl);
88 }
89
90 /**
91 * Load the plugin with the given className
92 *
93 * @param name Class Name of plugin
94 * @param askGlobal Ask the gobal class loaded for this class if we can't find it?
95 * @return plugin class
96 * @throws ClassNotFoundException if the class to be loaded could not be found.
97 */
98 @Override
99 public Class<?> loadClass(final String name, final boolean askGlobal) throws ClassNotFoundException {
/*
P/P * Method: Class loadClass(String, bool)
*
* Preconditions:
* (soft) com/dmdirc/plugins/GlobalClassLoader.me.resourcesList != null
* (soft) name != null
* (soft) com/dmdirc/plugins/GlobalClassLoader.me != null
* (soft) init'ed(this.pluginInfo.myResourceManager)
* (soft) this.pluginInfo != null
* (soft) init'ed(this.pluginInfo.metaData)
* (soft) this.pluginInfo.url != null
*
* Presumptions:
* com.dmdirc.plugins.PluginClassLoader:defineClass(...)@156 != null
* com.dmdirc.plugins.PluginClassLoader:getParent(...).pluginInfo.url@103 != null
* com.dmdirc.plugins.PluginClassLoader:getParent(...).pluginInfo@103 != null
* com.dmdirc.plugins.PluginClassLoader:getParent(...)@103 != null
* com.dmdirc.util.resourcemanager.ResourceManager:getResourceBytes(...)@147 != null
* ...
*
* Postconditions:
* init'ed(com/dmdirc/plugins/GlobalClassLoader.me)
* init'ed(return_value)
* init'ed(this.pluginInfo.myResourceManager)
* new GlobalClassLoader(getGlobalClassLoader#1) num objects <= 1
* new GlobalClassLoader(getGlobalClassLoader#1) num objects == 0
* init'ed(new GlobalClassLoader(getGlobalClassLoader#1).resourcesList)
* possibly_updated(new GlobalClassLoader(getGlobalClassLoader#1).resourcesList)
* new HashMap(GlobalClassLoader#1) num objects <= 1
* new HashMap(GlobalClassLoader#1) num objects == 0
*
* Test Vectors:
* askGlobal: {0}, {1}
* com.dmdirc.util.resourcemanager.ResourceManager:resourceExists(...)@121: {1}, {0}
*/
100 Class< ? > loadedClass = null;
101 if (getParent() instanceof PluginClassLoader) {
102 try {
103 loadedClass = ((PluginClassLoader)getParent()).loadClass(name, false);
104 if (loadedClass != null) {
105 return loadedClass;
106 }
107 } catch (ClassNotFoundException cnfe) {
108 /* Parent doesn't have the class, load ourself */
109 }
110 }
111
112 ResourceManager res;
113 try {
114 res = pluginInfo.getResourceManager();
115 } catch (IOException ioe) {
116 throw new ClassNotFoundException("Error with resourcemanager", ioe);
117 }
118
119 final String fileName = name.replace('.', '/')+".class";
120 try {
121 if (pluginInfo.isPersistent(name) || !res.resourceExists(fileName)) {
122 if (!pluginInfo.isPersistent(name) && askGlobal) {
123 return GlobalClassLoader.getGlobalClassLoader().loadClass(name);
124 } else {
125 // Try to load class from previous load.
126 try {
127 if (askGlobal) {
128 return GlobalClassLoader.getGlobalClassLoader().loadClass(name, pluginInfo);
129 }
130 } catch (ClassNotFoundException e) {
131 /* Class doesn't exist, we load it ourself below */
132 }
133 }
134 }
135 } catch (NoClassDefFoundError e) {
136 throw new ClassNotFoundException("Error loading '"+name+"' (wanted by "+pluginInfo.getName()+") -> "+e.getMessage(), e);
137 }
138
139
140 // Don't duplicate a class
141 if (isClassLoaded(name, false)) { return findLoadedClass(name); }
142
143 // We are ment to be loading this one!
144 byte[] data = null;
145
146 if (res.resourceExists(fileName)) {
147 data = res.getResourceBytes(fileName);
148 } else {
149 throw new ClassNotFoundException("Resource '"+name+"' (wanted by "+pluginInfo.getName()+") does not exist.");
150 }
151
152 try {
153 if (pluginInfo.isPersistent(name)) {
154 GlobalClassLoader.getGlobalClassLoader().defineClass(name, data);
155 } else {
156 loadedClass = defineClass(name, data, 0, data.length);
157 }
158 } catch (NoClassDefFoundError e) {
159 throw new ClassNotFoundException(e.getMessage(), e);
160 }
161
162 if (loadedClass == null) {
163 throw new ClassNotFoundException("Could not load " + name);
164 } else {
165 resolveClass(loadedClass);
166 }
167
168 return loadedClass;
169 }
170 }
SofCheck Inspector Build Version : 2.17854
| PluginClassLoader.java |
2009-Jun-25 01:54:24 |
| PluginClassLoader.class |
2009-Sep-02 17:04:13 |