source: josm/trunk/src/org/openstreetmap/josm/plugins/Plugin.java

Last change on this file was 19050, checked in by taylor.smock, 16 months ago

Revert most var changes from r19048, fix most new compile warnings and checkstyle issues

Also, document why various ErrorProne checks were originally disabled and fix
generic SonarLint issues.

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.plugins;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.File;
7import java.net.URL;
8import java.net.URLClassLoader;
9import java.security.AccessController;
10import java.security.PrivilegedAction;
11import java.util.List;
12
13import org.openstreetmap.josm.data.Preferences;
14import org.openstreetmap.josm.gui.MapFrame;
15import org.openstreetmap.josm.gui.MapFrameListener;
16import org.openstreetmap.josm.gui.download.DownloadSelection;
17import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
18import org.openstreetmap.josm.spi.preferences.Config;
19import org.openstreetmap.josm.spi.preferences.IBaseDirectories;
20import org.openstreetmap.josm.tools.Logging;
21import org.openstreetmap.josm.tools.Utils;
22
23/**
24 * For all purposes of loading dynamic resources, the Plugin's class loader should be used
25 * (or else, the plugin jar will not be within the class path).
26 * <p>
27 * A plugin may subclass this abstract base class (but it is optional).
28 * <p>
29 * The actual implementation of this class is optional, as all functions will be called
30 * via reflection. This is to be able to change this interface without the need of
31 * recompiling or even breaking the plugins. If your class does not provide a
32 * function here (or does provide a function with a mismatching signature), it will not
33 * be called. That simple.
34 * <p>
35 * Or in other words: See this base class as an documentation of what automatic callbacks
36 * are provided (you can register yourself to more callbacks in your plugin class
37 * constructor).
38 * <p>
39 * Subclassing Plugin and overriding some functions makes it easy for you to keep sync
40 * with the correct actual plugin architecture of JOSM.
41 *
42 * @author Immanuel.Scholz
43 */
44public abstract class Plugin implements MapFrameListener {
45
46 /**
47 * This is the info available for this plugin. You can access this from your
48 * constructor.
49 * <p>
50 * (The actual implementation to request the info from a static variable
51 * is a bit hacky, but it works).
52 */
53 private PluginInformation info;
54
55 private final IBaseDirectories pluginBaseDirectories = new PluginBaseDirectories();
56
57 private final class PluginBaseDirectories implements IBaseDirectories {
58 private File preferencesDir;
59 private File cacheDir;
60 private File userdataDir;
61
62 @Override
63 public File getPreferencesDirectory(boolean createIfMissing) {
64 if (preferencesDir == null) {
65 preferencesDir = Config.getDirs().getPreferencesDirectory(createIfMissing).toPath()
66 .resolve("plugins").resolve(info.name).toFile();
67 }
68 if (createIfMissing && !preferencesDir.exists() && !preferencesDir.mkdirs()) {
69 Logging.error(tr("Failed to create missing plugin preferences directory: {0}", preferencesDir.getAbsoluteFile()));
70 }
71 return preferencesDir;
72 }
73
74 @Override
75 public File getUserDataDirectory(boolean createIfMissing) {
76 if (userdataDir == null) {
77 userdataDir = Config.getDirs().getUserDataDirectory(createIfMissing).toPath()
78 .resolve("plugins").resolve(info.name).toFile();
79 }
80 if (createIfMissing && !userdataDir.exists() && !userdataDir.mkdirs()) {
81 Logging.error(tr("Failed to create missing plugin user data directory: {0}", userdataDir.getAbsoluteFile()));
82 }
83 return userdataDir;
84 }
85
86 @Override
87 public File getCacheDirectory(boolean createIfMissing) {
88 if (cacheDir == null) {
89 cacheDir = Config.getDirs().getCacheDirectory(createIfMissing).toPath()
90 .resolve("plugins").resolve(info.name).toFile();
91 }
92 if (createIfMissing && !cacheDir.exists() && !cacheDir.mkdirs()) {
93 Logging.error(tr("Failed to create missing plugin cache directory: {0}", cacheDir.getAbsoluteFile()));
94 }
95 return cacheDir;
96 }
97 }
98
99 /**
100 * Creates the plugin
101 *
102 * @param info the plugin information describing the plugin.
103 */
104 protected Plugin(PluginInformation info) {
105 this.info = info;
106 }
107
108 /**
109 * Replies the plugin information object for this plugin
110 *
111 * @return the plugin information object
112 */
113 public PluginInformation getPluginInformation() {
114 return info;
115 }
116
117 /**
118 * Sets the plugin information object for this plugin
119 *
120 * @param info the plugin information object
121 */
122 public void setPluginInformation(PluginInformation info) {
123 this.info = info;
124 }
125
126 /**
127 * Get the directories where this plugin can store various files.
128 * @return the directories where this plugin can store files
129 * @since 13007
130 */
131 public IBaseDirectories getPluginDirs() {
132 return pluginBaseDirectories;
133 }
134
135 @Override
136 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {}
137
138 /**
139 * Called in the preferences dialog to create a preferences page for the plugin,
140 * if any available.
141 * @return the preferences dialog, or {@code null}
142 */
143 public PreferenceSetting getPreferenceSetting() {
144 return null;
145 }
146
147 /**
148 * Called in the download dialog to give the plugin a chance to modify the list
149 * of bounding box selectors.
150 * @param list list of bounding box selectors
151 */
152 public void addDownloadSelection(List<DownloadSelection> list) {}
153
154 /**
155 * Get a class loader for loading resources from the plugin jar.
156 *
157 * This can be used to avoid getting a file from another plugin that
158 * happens to have a file with the same file name and path.
159 *
160 * Usage: Instead of
161 * getClass().getResource("/resources/pluginProperties.properties");
162 * write
163 * getPluginResourceClassLoader().getResource("resources/pluginProperties.properties");
164 *
165 * (Note the missing leading "/".)
166 * @return a class loader for loading resources from the plugin jar
167 */
168 public ClassLoader getPluginResourceClassLoader() {
169 File pluginDir = Preferences.main().getPluginsDirectory();
170 File pluginJar = new File(pluginDir, info.name + ".jar");
171 final URL pluginJarUrl = Utils.fileToURL(pluginJar);
172 return AccessController.doPrivileged((PrivilegedAction<ClassLoader>)
173 () -> new URLClassLoader(new URL[] {pluginJarUrl}, Plugin.class.getClassLoader()));
174 }
175}
Note: See TracBrowser for help on using the repository browser.