source: josm/trunk/src/org/openstreetmap/josm/plugins/PluginClassLoader.java@ 14145

Last change on this file since 14145 was 13849, checked in by Don-vip, 6 years ago

SonarQube - fix minor code issues

  • Property svn:eol-style set to native
File size: 3.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.plugins;
3
4import java.net.URL;
5import java.net.URLClassLoader;
6import java.util.ArrayList;
7import java.util.Arrays;
8import java.util.Collection;
9import java.util.Objects;
10
11import org.openstreetmap.josm.tools.Logging;
12
13/**
14 * Class loader for JOSM plugins.
15 * <p>
16 * In addition to the classes in the plugin jar file, it loads classes of required
17 * plugins. The JOSM core classes should be provided by the parent class loader.
18 * @since 12322
19 */
20public class PluginClassLoader extends URLClassLoader {
21
22 private final Collection<PluginClassLoader> dependencies;
23
24 static {
25 ClassLoader.registerAsParallelCapable();
26 }
27
28 /**
29 * Create a new PluginClassLoader.
30 * @param urls URLs of the plugin jar file (and extra libraries)
31 * @param parent the parent class loader (for JOSM core classes)
32 * @param dependencies class loaders of required plugin; can be null
33 */
34 public PluginClassLoader(URL[] urls, ClassLoader parent, Collection<PluginClassLoader> dependencies) {
35 super(urls, parent);
36 this.dependencies = dependencies == null ? new ArrayList<>() : new ArrayList<>(dependencies);
37 }
38
39 /**
40 * Add class loader of a required plugin.
41 * This plugin will have access to the classes of the dependent plugin
42 * @param dependency the class loader of the required plugin
43 * @return {@code true} if the collection of dependencies changed as a result of the call
44 * @since 12867
45 */
46 public boolean addDependency(PluginClassLoader dependency) {
47 // Add dependency only if not already present (directly or transitively through another one)
48 boolean result = !dependencies.contains(Objects.requireNonNull(dependency, "dependency"))
49 && dependencies.stream().noneMatch(pcl -> pcl.dependencies.contains(dependency))
50 && dependencies.add(dependency);
51 if (result) {
52 // Now, remove top-level single dependencies, which would be children of the added one
53 dependencies.removeIf(pcl -> pcl.dependencies.isEmpty() && dependency.dependencies.contains(pcl));
54 }
55 return result;
56 }
57
58 @Override
59 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
60 Class<?> result = findLoadedClass(name);
61 if (result == null) {
62 for (PluginClassLoader dep : dependencies) {
63 try {
64 result = dep.loadClass(name, resolve);
65 if (result != null) {
66 return result;
67 }
68 } catch (ClassNotFoundException e) {
69 // do nothing
70 Logging.trace("Plugin class not found in {0}: {1}", dep, e.getMessage());
71 Logging.trace(e);
72 }
73 }
74 result = super.loadClass(name, resolve);
75 }
76 if (result != null) {
77 return result;
78 }
79 throw new ClassNotFoundException(name);
80 }
81
82 @Override
83 public String toString() {
84 return "PluginClassLoader [urls=" + Arrays.toString(getURLs()) +
85 (dependencies.isEmpty() ? "" : ", dependencies=" + dependencies) + ']';
86 }
87}
Note: See TracBrowser for help on using the repository browser.