1 package com.atlassian.plugin;
2
3 import java.io.InputStream;
4 import java.net.URL;
5 import java.util.*;
6
7 public interface Plugin extends Resourced, Comparable<Plugin>
8 {
9 /**
10 * This is the historical version of plugins. Which is mostly static plugins loaded from the same classpath to the
11 * application.
12 */
13 static final int VERSION_1 = 1;
14
15 /**
16 * This is the version of plugins which introduced dynamic plugins for all. Based on OSGi and Spring DM. Those plugins
17 * undergo some transformations to make the plugin artifact compatible with the OSGi + Spring DM container.
18 */
19 static final int VERSION_2 = 2;
20
21 /**
22 * This is the versions of plugins that adds remotes plugins (developed outside of the plugin framework itself).
23 * Plugins version 3 don't undergo any transformation so it is up to the plugin developer to write their own Spring
24 * configuration files if this is their chosen framework, but other frameworks can be introduced.
25 */
26 static final int VERSION_3 = 3;
27
28 /**
29 * @deprecated since 2.2.0. This comparator only takes into account the plugin name and assumes it is not null,
30 * yet a) that constraint is not validated anywhere in plugin loading and b) the plugin could have used the i18n
31 * name, and only the application can resolve that to a name useful for comparisons.
32 */
33 public static final Comparator<Plugin> NAME_COMPARATOR = new PluginNameComparator();
34
35 /**
36 * Gets the version of the plugins system to handle this plugin
37 * @return The plugins version. If undefined, assumed to be 1.
38 */
39 int getPluginsVersion();
40
41 /**
42 * Sets the version of the plugins system
43 * @param version The version
44 */
45 void setPluginsVersion(int version);
46
47 /**
48 * Returns the non-localised name of this plugin if defined.
49 *
50 * <p> This corresponds to the value of the {@code name} field in the plugin's XML configuration file.
51 *
52 * <p> You would expect a plugin developer to fill in one of either {@code name}, or {@code i18n-name-key},
53 * but the framework does no validation and makes no guarantees that this is the case.
54 *
55 * @return the non-localised name of this plugin if defined, or null.
56 * @see #getI18nNameKey()
57 */
58 String getName();
59
60 /**
61 * Sets the non-localised name of this plugin.
62 *
63 * @param name the name.
64 * @see #getName()
65 */
66 void setName(String name);
67
68 /**
69 * Returns the i18nKey used to get an internationalised name for this plugin.
70 *
71 * <p> This corresponds to the value of the {@code i18n-name-key} field in the plugin's XML configuration file.
72 *
73 * <p> You would expect a plugin developer to fill in one of either {@code name}, or {@code i18n-name-key},
74 * but the framework does no validation and makes no guarantees that this is the case.
75 *
76 * @return the i18n Name Key for this plugin if defined, or null.
77 * @see #getName()
78 */
79 String getI18nNameKey();
80
81 /**
82 * Sets the i18nKey used to get an internationalised name for this plugin.
83 *
84 * @param i18nNameKey the i18n Name Key.
85 * @see #getI18nNameKey()
86 */
87 void setI18nNameKey(String i18nNameKey);
88
89 String getKey();
90
91 void setKey(String aPackage);
92
93 void addModuleDescriptor(ModuleDescriptor<?> moduleDescriptor);
94
95 /**
96 * Get the {@link Collection} of {@link ModuleDescriptor descriptors}.
97 *
98 * <p> The iteration order of the collection is
99 * the order that the modules will be enabled, and should be the same order that the modules appear in the
100 * plugin descriptor.
101 *
102 * @return the modules contained by this plugin in the order they are to be enabled
103 */
104 Collection<ModuleDescriptor<?>> getModuleDescriptors();
105
106 /**
107 * Get the {@link ModuleDescriptor} for a particular key. Returns <tt>null</tt> if the plugin does not exist.
108 * <p>
109 * Note: The {@link ModuleDescriptor#getModule()} may throw {@link ClassCastException} if the expected type is incorrect.
110 *
111 * @param key the {@link String} complete key of the module, in the form "org.example.plugin:module-key".
112 * @return the {@link ModuleDescriptor} of the expected type.
113 */
114 ModuleDescriptor<?> getModuleDescriptor(String key);
115
116 /**
117 * Get the {@link ModuleDescriptor descriptors} whose module class implements or is assignable from the supplied {@link Class}.
118 * <p>
119 * Note: The {@link ModuleDescriptor#getModule()} may throw {@link ClassCastException} if the expected type is incorrect.
120 * Normally this method would not be supplied with anything other than {@link Object} or <?>, unless you are
121 * confident in the super type of the module classes this {@link Plugin} provides.
122 *
123 * @param <M> The expected module type of the returned {@link ModuleDescriptor descriptors}.
124 * @param moduleClass the {@link Class super class} the {@link ModuleDescriptor descriptors} return.
125 * @return the {@link List} of {@link ModuleDescriptor descriptors} of the expected type.
126 */
127 <M> List<ModuleDescriptor<M>> getModuleDescriptorsByModuleClass(Class<M> moduleClass);
128
129 /**
130 * Gets the installation mode
131 * @return the plugin's installation mode, local or remote.
132 *
133 * @since 3.0
134 */
135 InstallationMode getInstallationMode();
136
137 boolean isEnabledByDefault();
138
139 void setEnabledByDefault(boolean enabledByDefault);
140
141 PluginInformation getPluginInformation();
142
143 void setPluginInformation(PluginInformation pluginInformation);
144
145 void setResources(Resourced resources);
146
147 /**
148 * Returns this plugin's current state.
149 *
150 * @return the current state of the plugin.
151 * @since 2.2.0
152 */
153 PluginState getPluginState();
154
155 /**
156 * @deprecated since 2.2.0, use {@link #getPluginState()} instead
157 * @return {@code true} if this plugin is enabled.
158 */
159 boolean isEnabled();
160
161
162 /**
163 * Whether the plugin is a "system" plugin that shouldn't be made visible to the user.
164 *
165 * @return {@code true} if this plugin is a "system" plugin.
166 * @deprecated since 2.6.0 use {@link com.atlassian.plugin.metadata.PluginMetadataManager#isSystemProvided(Plugin)}}
167 * instead.
168 */
169 boolean isSystemPlugin();
170
171 /**
172 * @param system whether the plugin is a "system" plugin that shouldn't be made visible to the user.
173 * @deprecated since 2.6.0 provide {@link com.atlassian.plugin.metadata.PluginMetadataManager} with information about the
174 * plugin instead. There is no way to programatically set this value now.
175 */
176 void setSystemPlugin(boolean system);
177
178 boolean containsSystemModule();
179
180 /**
181 * Whether the plugin is a "bundled" plugin that can't be removed.
182 *
183 * @return {@code true} if this plugin is a "bundled" plugin.
184 */
185 boolean isBundledPlugin();
186
187 /**
188 * The date this plugin was loaded into the system.
189 *
190 * @return The date this plugin was loaded into the system.
191 */
192 Date getDateLoaded();
193
194
195 /**
196 * The date this plugin was installed into the system, is the same as the loaded date for non artifact backed plugins
197 *
198 * @return The date this plugin was installed into the system
199 * @since 3.0.0
200 */
201 Date getDateInstalled();
202
203 /**
204 * Whether or not this plugin can be 'uninstalled'.
205 *
206 * @return {@code true} if this plugin can be 'uninstalled'.
207 */
208 boolean isUninstallable();
209
210 /**
211 * Should the plugin file be deleted on unistall?
212 *
213 * @return {@code true} if this plugin file should be deleted on unistall.
214 */
215 boolean isDeleteable();
216
217 /**
218 * Whether or not this plugin is loaded dynamically at runtime.
219 *
220 * @return {@code true} if this plugin is loaded dynamically at runtime.
221 */
222 boolean isDynamicallyLoaded();
223
224 /**
225 * Get the plugin to load a specific class.
226 *
227 * @param clazz The name of the class to be loaded
228 * @param callingClass The class calling the loading (used to help find a classloader)
229 * @return The loaded class.
230 * @throws ClassNotFoundException if the class cannot be located.
231 */
232 <T> Class<T> loadClass(String clazz, Class<?> callingClass) throws ClassNotFoundException;
233
234 /**
235 * Get the classloader for the plugin.
236 *
237 * @return The classloader used to load classes for this plugin
238 */
239 ClassLoader getClassLoader();
240
241 /**
242 * Retrieve the URL of the resource from the plugin.
243 *
244 * @param path the name of the resource to be loaded
245 * @return The URL to the resource, or null if the resource is not found
246 */
247 URL getResource(String path);
248
249 /**
250 * Load a given resource from the plugin. Plugins that are loaded dynamically will need
251 * to implement this in a way that loads the resource from the same context as the plugin.
252 * Static plugins can just pull them from their own classloader.
253 *
254 * @param name The name of the resource to be loaded.
255 * @return An InputStream for the resource, or null if the resource is not found.
256 */
257 InputStream getResourceAsStream(String name);
258
259 /**
260 * @param enabled new enabled state
261 * @deprecated Since 2.2.0, use {@link #enable()} or {@link #disable()} instead
262 */
263 void setEnabled(boolean enabled);
264
265 /**
266 * Free any resources held by this plugin. To be called during uninstallation of the {@link Plugin}.
267 * @deprecated Since 2.2.0, use {@link #uninstall()} instead
268 */
269 void close();
270
271 /**
272 * Installs the plugin into any internal, managing container. This method will be called on every startup. Unless
273 * an exception is thrown, the plugin should be in the {@link PluginState#INSTALLED} state. If the plugin is already
274 * in the {@link PluginState#INSTALLED} state, nothing will happen.
275 *
276 * @since 2.2.0
277 * @throws PluginException If the plugin could not be installed
278 */
279 void install() throws PluginException;
280
281 /**
282 * Uninstalls the plugin from any internal container. This method will be called on every shutdown. Unless an
283 * exception is thrown, the plugin should be in the {@link PluginState#UNINSTALLED} state. If the plugin is already
284 * in the {@link PluginState#UNINSTALLED} state, nothing will happen.
285 *
286 * @since 2.2.0
287 * @throws PluginException If the plugin could not be uninstalled
288 */
289 void uninstall() throws PluginException;
290
291 /**
292 * Enables the plugin. Unless an exception is thrown, the plugin should then be in either the
293 * {@link PluginState#ENABLING} or {@link PluginState#ENABLED} state. If the plugin is already in the
294 * {@link PluginState#ENABLING} or {@link PluginState#ENABLED} state, nothing will happen.
295 *
296 *
297 * @since 2.2.0
298 * @throws PluginException If the plugin could not be enabled
299 */
300 void enable() throws PluginException;
301
302 /**
303 * Disables the plugin. Unless an exception is thrown, the plugin should be in the {@link PluginState#DISABLED}
304 * state. If the plugin is already in the {@link PluginState#DISABLED} state, nothing will happen.
305 *
306 * @since 2.2.0 If the plugin could not be disabled
307 * @throws PluginException If the plugin could not be disabled
308 */
309 void disable() throws PluginException;
310
311 /**
312 * @return A list of plugin keys that this plugin is dependent upon, or an empty list if none
313 * @since 2.2.0
314 */
315 Set<String> getRequiredPlugins();
316
317 /**
318 * @return the list of permissions currently valid for the plugin
319 * @since 3.0
320 */
321 Set<String> getActivePermissions();
322
323 /**
324 * @return {@code true} if the plugin has all the permissions
325 * @since 3.0
326 */
327 boolean hasAllPermissions();
328 }