1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.plugins;
|
---|
3 |
|
---|
4 | import java.net.URL;
|
---|
5 | import java.net.URLClassLoader;
|
---|
6 | import java.util.ArrayList;
|
---|
7 | import java.util.Collection;
|
---|
8 |
|
---|
9 | import org.openstreetmap.josm.tools.Logging;
|
---|
10 |
|
---|
11 | /**
|
---|
12 | * Class loader for JOSM plugins.
|
---|
13 | * <p>
|
---|
14 | * In addition to the classes in the plugin jar file, it loads classes of required
|
---|
15 | * plugins. The JOSM core classes should be provided by the the parent class loader.
|
---|
16 | * @since 12322
|
---|
17 | */
|
---|
18 | public class PluginClassLoader extends URLClassLoader {
|
---|
19 |
|
---|
20 | Collection<PluginClassLoader> dependencies;
|
---|
21 |
|
---|
22 | static {
|
---|
23 | ClassLoader.registerAsParallelCapable();
|
---|
24 | }
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * Create a new PluginClassLoader.
|
---|
28 | * @param urls URLs of the plugin jar file (and extra libraries)
|
---|
29 | * @param parent the parent class loader (for JOSM core classes)
|
---|
30 | * @param dependencies class loaders of required plugin; can be null
|
---|
31 | */
|
---|
32 | public PluginClassLoader(URL[] urls, ClassLoader parent, Collection<PluginClassLoader> dependencies) {
|
---|
33 | super(urls, parent);
|
---|
34 | this.dependencies = dependencies == null ? new ArrayList<>() : new ArrayList<>(dependencies);
|
---|
35 | }
|
---|
36 |
|
---|
37 | /**
|
---|
38 | * Add class loader of a required plugin.
|
---|
39 | * This plugin will have access to the classes of the dependent plugin
|
---|
40 | * @param dependency the class loader of the required plugin
|
---|
41 | */
|
---|
42 | public void addDependency(PluginClassLoader dependency) {
|
---|
43 | dependencies.add(dependency);
|
---|
44 | }
|
---|
45 |
|
---|
46 | @Override
|
---|
47 | protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
---|
48 | for (PluginClassLoader dep : dependencies) {
|
---|
49 | try {
|
---|
50 | Class<?> result = dep.loadClass(name, resolve);
|
---|
51 | if (result != null) {
|
---|
52 | return result;
|
---|
53 | }
|
---|
54 | } catch (ClassNotFoundException e) {
|
---|
55 | // do nothing
|
---|
56 | Logging.trace("Plugin class not found in {0}: {1}", dep, e.getMessage());
|
---|
57 | }
|
---|
58 | }
|
---|
59 | Class<?> result = super.loadClass(name, resolve);
|
---|
60 | if (result != null) {
|
---|
61 | return result;
|
---|
62 | }
|
---|
63 | throw new ClassNotFoundException(name);
|
---|
64 | }
|
---|
65 | }
|
---|