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