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