1 package com.atlassian.plugin;
2
3 import org.dom4j.Element;
4
5 import javax.annotation.Nonnull;
6 import java.util.Map;
7
8 public interface ModuleDescriptor<T> extends ScopeAware, Resourced {
9 /**
10 * The complete key for this module, including the plugin key.
11 * <p>
12 * Format is plugin.key:module.key
13 * </p>
14 *
15 * @return The complete key for this module.
16 * @see #getKey()
17 * @see #getPluginKey()
18 */
19 String getCompleteKey();
20
21 /**
22 * The plugin key for this module, derived from the complete key.
23 *
24 * @return The plugin key for this module.
25 * @see #getKey()
26 * @see #getCompleteKey()
27 */
28 String getPluginKey();
29
30 /**
31 * The key for this module, unique within the plugin.
32 *
33 * @return The key for this module.
34 * @see #getCompleteKey()
35 * @see #getPluginKey()
36 */
37 String getKey();
38
39 /**
40 * A simple string name for this descriptor.
41 *
42 * @return The name for this ModuleDescriptor.
43 */
44 String getName();
45
46 /**
47 * A simple description of this descriptor.
48 *
49 * @return The description for this ModuleDescriptor.
50 */
51 String getDescription();
52
53 /**
54 * The class of the module this descriptor creates.
55 *
56 * @return The class of the module this descriptor creates.
57 * @see #getModule()
58 */
59 Class<T> getModuleClass();
60
61 /**
62 * The particular module object created by this plugin.
63 *
64 * @return The module object created by this plugin.
65 * @see #getModuleClass()
66 */
67 T getModule();
68
69 /**
70 * Initialise a module given it's parent plugin and the XML element
71 * representing the module.
72 * <p>
73 * Since atlassian-plugins v2.2, you can no longer load classes from the
74 * plugin in this method, because the OSGi bundle that they will live in is
75 * not built yet. Load classes in the {@link StateAware#enabled()}
76 * method instead.
77 *
78 * @param plugin The plugin that the module belongs to. Must not be null.
79 * @param element XML element representing the module. Must not be null.
80 * @throws PluginParseException Can be thrown if an error occurs while
81 * parsing the XML element.
82 */
83 void init(@Nonnull Plugin plugin, @Nonnull Element element) throws PluginParseException;
84
85 /**
86 * Whether or not this plugin module is enabled by default.
87 *
88 * @return {@code true} if this plugin module is enabled by default.
89 */
90 boolean isEnabledByDefault();
91
92 /**
93 * Whether or not this plugin module is a "system" module that shouldn't be
94 * made visible/disable-able to the user. System plugin modules also don't
95 * have their permissions checked, as they may be created dynamically in
96 * response to another, more safe module
97 *
98 * @return {@code true} if this plugin module is a "system" plugin that
99 * shouldn't be made visible/disable-able to the user.
100 */
101 boolean isSystemModule();
102
103 /**
104 * @deprecated The plugin parameter is redundant. Override {@link #destroy()}.
105 */
106 void destroy(Plugin plugin);
107
108 /**
109 * Override this if your plugin needs to clean up when it's been removed.
110 */
111 void destroy();
112
113 Float getMinJavaVersion();
114
115 /**
116 * If a min java version has been specified this will return true if the
117 * running jvm is >= to the specified version. If this is not set then it is
118 * treated as not having a preference.
119 *
120 * @return true if satisfied, false otherwise.
121 */
122 boolean satisfiesMinJavaVersion();
123
124 Map<String, String> getParams();
125
126 /**
127 * Key used to override {@link #getName()} when using internationalisation.
128 *
129 * @return the i18n key. May be null.
130 */
131 String getI18nNameKey();
132
133 /**
134 * Key used to override {@link #getDescription()} when using
135 * internationalisation.
136 *
137 * @return the i18n key. May be null.
138 */
139 String getDescriptionKey();
140
141 /**
142 * @return The plugin this module descriptor is associated with
143 */
144 Plugin getPlugin();
145
146 /**
147 * <p>Compares the specified object with this module descriptor for equality.</p>
148 * <p>
149 * <p>Returns <tt>true</tt> if the given object is also a module descriptor and the two descriptors have the same
150 * "complete key" as determined by {@link #getCompleteKey()}.</p>
151 * <p>
152 * This ensures that the <tt>equals</tt> method works properly across
153 * different implementations of the <tt>ModuleDescriptor</tt> interface.
154 *
155 * @param obj object to be compared for equality with this module descriptor.
156 * @return <tt>true</tt> if the specified object is equal to this module descriptor.
157 * @since 2.8.0
158 */
159 boolean equals(Object obj);
160
161 /**
162 * Returns the hash code value for this module descriptor. The hash code
163 * of a module descriptor <tt>d</tt> is defined to be: <pre>
164 * getCompleteKey() == null ? 0 : getCompleteKey().hashCode()
165 * </pre>
166 * This ensures that <tt>d1.equals(d2)</tt> implies that
167 * <tt>d1.hashCode()==d2.hashCode()</tt> for any two Module Descriptors
168 * <tt>d1</tt> and <tt>d2</tt>, as required by the general
169 * contract of <tt>Object.hashCode</tt>.
170 *
171 * @return the hash code value for this module descriptor.
172 * @see Object#hashCode()
173 * @see Object#equals(Object)
174 * @see #equals(Object)
175 * @since 2.8.0
176 */
177 int hashCode();
178
179 /**
180 * Get whether this plugin module is enabled.
181 *
182 * @return If this module is enabled
183 * @since 3.1
184 */
185 boolean isEnabled();
186
187 /**
188 * Changes state to "broken"
189 * <p>
190 * Being breakable is something subclasses can opt in to, therefore by default {@link ModuleDescriptor}s
191 * are unbreakable, this is a no-op, and {@link #isBroken()} returns {@code false}
192 */
193 default void setBroken() {
194 }
195
196 /**
197 * Returns true if this Module is "broken".
198 * <p>
199 * A "broken" module means that even though this ModuleDescriptor is enabled, calling {@code getModule()} results
200 * in an error. This typically occurs when the plugin version is not compatible with the version of the host product.
201 * <p>
202 * Note that some modules are lazy-loaded, and so this method is optimistic:
203 * it will return false until we discover that the Module is not loadable.
204 *
205 * @return {@code true} if broken, {@code false} otherwise
206 */
207 default boolean isBroken() {
208 return false;
209 }
210 }