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