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