1 package com.atlassian.sal.api.license;
2
3 import com.atlassian.annotations.PublicApi;
4 import com.atlassian.sal.api.i18n.InvalidOperationException;
5 import com.atlassian.sal.api.validate.ValidationResult;
6
7 import java.util.Collection;
8 import java.util.Locale;
9 import java.util.Set;
10 import java.util.SortedSet;
11 import javax.annotation.Nonnull;
12 import javax.annotation.Nullable;
13
14 /**
15 * Interface into the license system for the underlying application.
16 *<p>
17 * Licenses and products across Atlassian vary considerably with respect to the number of licenses that any given
18 * product may accept (1-many), but also in terms of the number of products that may be granted within license (also
19 * 1-many). This interface provides both a {@link com.atlassian.sal.api.license.SingleProductLicenseDetailsView single
20 * product view} of license details (regardless of the actual number of licenses and products present), as well as a
21 * {@link com.atlassian.sal.api.license.MultiProductLicenseDetails}.
22 *</p>
23 *
24 * @see com.atlassian.sal.api.license.MultiProductLicenseDetails
25 * @since 2.0
26 */
27 @SuppressWarnings ("UnusedDeclaration")
28 @PublicApi
29 public interface LicenseHandler
30 {
31 /**
32 * Sets the license string for the currently running application.
33 *
34 * This method will fire a {@link com.atlassian.sal.api.license.LicenseChangedEvent} upon successfully setting
35 * the license.
36 *
37 * <p>
38 * This method is not suitable for platforms.
39 *
40 * @param license The raw license string
41 *
42 * @throws IllegalArgumentException if the license string is not a valid license
43 * @throws java.lang.UnsupportedOperationException if this is a platform that allows multiple licenses
44 *
45 * @deprecated Use {@link #addProductLicense(String, String)} instead. Since 3.0.
46 */
47 @Deprecated
48 void setLicense(String license);
49
50 /**
51 * Use this to figure out if this host application uses a single global license, or if it is a platform that can take
52 * multiple Product licenses.
53 * <p>
54 * Most applications would return false here but Fisheye/Crucible will return true, and JIRA 7.0 will return true.
55 *
56 * @return {@code true} if this application is a platform that accepts multiple product licenses, {@code false} if
57 * it just takes a single global license.
58 * @since 3.0
59 * @see #hostAllowsCustomProducts()
60 */
61 boolean hostAllowsMultipleLicenses();
62
63 /**
64 * Returns true if it is possible to add custom products on top of this platform.
65 * <p>
66 * Most applications would return false here.
67 * Confluence returns true because it has Spaces and Questions, JIRA 7.0 will return true, but Fisheye/Crucible will
68 * return false - although it has separate licenses for FishEye and Crucible, you cannot add new custom products.
69 *
70 * @return {@code true} if this application is a platform that accepts multiple product licenses, {@code false} if
71 * it just takes a single global license.
72 * @since 3.0
73 * @see #hostAllowsMultipleLicenses()
74 */
75 boolean hostAllowsCustomProducts();
76
77 /**
78 * Returns the list of currently available products in this host application whether these products are currently
79 * licensed or not.
80 *
81 * <p>
82 * For FishEye/Crucible this will return both "fisheye" and "crucible".
83 * <br>
84 * For JIRA, it will return the list of products that are currently installed (eg "com.atlassian.servicedesk").
85 * <br>
86 * For simple applications that only take a single license, it will return a single application name where that
87 * name is the ID used by HAMS to define the application in the license eg "bamboo", "conf".
88 * <br>
89 *
90 * @return the list of currently available products in this host application
91 */
92 Set<String> getProductKeys();
93
94 /**
95 * Adds the given product license to the host application.
96 *
97 * <p>
98 * For a platform that can take multiple license, the platform will figure out which product this is for and
99 * replace the current license for that product if one exists.
100 * </p>
101 *
102 * This method will fire a {@link com.atlassian.sal.api.license.LicenseChangedEvent} upon successfully adding
103 * the license.
104 *
105 * @param productKey The product to add this license to
106 * @param license The license string
107 *
108 * @throws InvalidOperationException if the license string is not valid for any reason.
109 * The InvalidOperationException should be localised for the currently logged in user and consumers are
110 * encouraged to call {@link InvalidOperationException#getLocalizedMessage()}
111 * @since 3.0
112 */
113 void addProductLicense(@Nonnull String productKey, @Nonnull String license) throws InvalidOperationException;
114
115 /**
116 * Removes the product license for the given productKey.
117 *
118 * <p>
119 * If the given product is in a multi-product license, it will remove that license and so all those products will
120 * become unlicensed.
121 * You can use {@code #getAllProductLicenses} to find multi-product licenses.
122 *
123 * <p>
124 * This method will fire a {@link com.atlassian.sal.api.license.LicenseChangedEvent} upon successfully removing
125 * the license.
126 * <p>
127 * If the passed productKey does not exist or is not licensed, the method will no-op and return successfully.
128 *
129 * @param productKey The product to remove the license of
130 *
131 * @throws InvalidOperationException if the host application vetoes this operation - eg JIRA will not let you remove
132 * the very last license. The InvalidOperationException should be localised for the currently logged in
133 * user and consumers are encouraged to call {@link InvalidOperationException#getLocalizedMessage()}
134 *
135 * @since 3.0
136 */
137 void removeProductLicense(@Nonnull String productKey) throws InvalidOperationException;
138
139 /**
140 * Validates that the given license is valid to add for the given product.
141 *
142 * @param productKey The product to add this license to
143 * @param license the raw license String
144 * @param locale locale of the end user - this is used to internationalise the error messages if any.
145 */
146 @Nonnull
147 ValidationResult validateProductLicense(@Nonnull String productKey, @Nonnull String license, @Nullable Locale locale);
148
149 /**
150 * Gets the server ID of the currently running application. The server ID format is four quadruples of
151 * alphanumeric characters, each separated by a dash (<tt>-</tt>).
152 *
153 * @return the server ID, or {@code null} if the server ID has not yet
154 * been set for the currently running application.
155 *
156 * @since 2.7
157 */
158 @Nullable
159 String getServerId();
160
161 /**
162 * Gets the Support Entitlement Number (SEN) for the single license in the currently running application.
163 * <p>
164 * This method is not suitable for platforms because these may have multiple licenses and hence multiple SENs.
165 *
166 * @return the Support Entitlement Number, or {@code null} if there is no current support entitlement.
167 *
168 * @throws java.lang.UnsupportedOperationException if this is a platform that allows multiple licenses
169 * @since 2.7
170 *
171 * @deprecated Get the license details and call {@link BaseLicenseDetails#getSupportEntitlementNumber()}. Since 3.0.
172 */
173 @Nullable
174 @Deprecated
175 String getSupportEntitlementNumber();
176
177
178 /**
179 * Gets the Support Entitlement Numbers (SENs) for all licenses in the currently running application.
180 * The SENs are in an ordered set, guaranteeing to return the SEN in the same order until the installed license
181 * state changes.
182 * <p>
183 * Note that licensed plugin SENs are not included in the results, unless they are being treated as application
184 * licenses.
185 *
186 * @return an ordered set of all the SENs. The set does not contain any empty or null SEN strings. If there is no
187 * SEN it will return an empty set. Non-platform products may return a set with only one SEN.
188 *
189 * @since 3.0
190 *
191 */
192 @Nonnull
193 SortedSet<String> getAllSupportEntitlementNumbers();
194
195 /**
196 * Returns the raw license String for a given product on a platform.
197 *
198 * @param productKey the product key.
199 * @return the raw license String for the given product key.
200 *
201 * @see #getProductLicenseDetails(String)
202 * @since 3.0
203 */
204 @Nullable
205 String getRawProductLicense(String productKey);
206
207 /**
208 * Returns an individual product view of the license details for the product identified by the given product key, or
209 * null if the product does not exist in any license.
210 *
211 * @param productKey the product key.
212 * @return the license details for the given product key.
213 *
214 * @see #getRawProductLicense(String)
215 * @see #decodeLicenseDetails(String)
216 * @see #getAllProductLicenses()
217 * @since 3.0
218 */
219 @Nullable
220 SingleProductLicenseDetailsView getProductLicenseDetails(@Nonnull String productKey);
221
222 /**
223 * Returns all the product licenses on a platform.
224 * <p>
225 * A platform may return multiple licenses, a simple application will return 0 or 1.
226 * </p>
227 *
228 * @return all the product licenses on a platform.
229 *
230 * @see #getProductLicenseDetails(String)
231 * @since 3.0
232 */
233 @Nonnull
234 Collection<MultiProductLicenseDetails> getAllProductLicenses();
235
236 /**
237 * Decodes a Platform Product License from the raw license String.
238 * This can be used to validate an entered license String before attempting to save it to the application.
239 *
240 * @param license the raw license String
241 * @return the license details for the given product key.
242 *
243 * @throws java.lang.IllegalArgumentException if the license string is not able to be decoded in this host application
244 * @see #getProductLicenseDetails(String)
245 * @since 3.0
246 */
247 @Nonnull
248 MultiProductLicenseDetails decodeLicenseDetails(@Nonnull String license);
249 }