/plugin/src/main/java/com/atlassian/plugin/remotable/plugin/rest/license/PluginLicenses.java

https://bitbucket.org/rodogu/remotable-plugins · Java · 299 lines · 210 code · 36 blank · 53 comment · 21 complexity · 2eebb44172e64bf0ec4e66dca8142f51 MD5 · raw file

  1. package com.atlassian.plugin.remotable.plugin.rest.license;
  2. import com.atlassian.upm.api.license.entity.LicenseError;
  3. import com.atlassian.upm.api.license.entity.PluginLicense;
  4. import com.atlassian.upm.api.util.Option;
  5. import com.google.common.base.Function;
  6. import com.google.common.base.Predicate;
  7. import com.google.common.collect.ImmutableSet;
  8. import org.joda.time.DateTime;
  9. import org.joda.time.Days;
  10. import org.joda.time.Interval;
  11. import static com.atlassian.upm.api.license.entity.LicenseError.EXPIRED;
  12. import static com.atlassian.upm.api.license.entity.LicenseError.VERSION_MISMATCH;
  13. import static com.atlassian.upm.api.license.entity.LicenseType.ACADEMIC;
  14. import static com.atlassian.upm.api.license.entity.LicenseType.COMMERCIAL;
  15. import static com.atlassian.upm.api.license.entity.LicenseType.STARTER;
  16. import static com.atlassian.upm.api.util.Option.none;
  17. import static com.atlassian.upm.api.util.Option.some;
  18. /**
  19. * Utility methods for {@link com.atlassian.upm.api.license.entity.PluginLicense}s. Exists in this module instead of licensing-lib due to class dependencies
  20. * and to increase accessibility/reusability.
  21. *
  22. * fixme: this is copied from UPM master at 75cee855ebd6475a3e7d9b619694e613c8906f09
  23. *
  24. * Remove this once UPM supports this rest resource
  25. */
  26. class PluginLicenses
  27. {
  28. /**
  29. * Number of days before expiration when a license is considered to be "nearly expired".
  30. */
  31. public static final Integer NEARLY_EXPIRED_DAYS = 7;
  32. /**
  33. * Number of days during which an expired license is considered "recently expired".
  34. */
  35. public static final Integer RECENTLY_EXPIRED_DAYS = 7;
  36. public static Predicate<PluginLicense> hasError(final LicenseError error)
  37. {
  38. return new Predicate<PluginLicense>()
  39. {
  40. public boolean apply(PluginLicense license)
  41. {
  42. return error == license.getError().getOrElse((LicenseError) null);
  43. }
  44. };
  45. }
  46. public static Predicate<PluginLicense> isNearlyExpired()
  47. {
  48. return new Predicate<PluginLicense>()
  49. {
  50. @Override
  51. public boolean apply(PluginLicense license)
  52. {
  53. for (DateTime expiryDate : license.getExpiryDate())
  54. {
  55. return new Interval(expiryDate.minusDays(NEARLY_EXPIRED_DAYS), expiryDate).contains(new DateTime());
  56. }
  57. return false; //no expiration date means it is never "nearly expired"
  58. }
  59. };
  60. }
  61. public static Predicate<PluginLicense> isNearlyMaintenanceExpired()
  62. {
  63. return new Predicate<PluginLicense>()
  64. {
  65. @Override
  66. public boolean apply(PluginLicense license)
  67. {
  68. for (DateTime maintenanceExpiryDate : license.getMaintenanceExpiryDate())
  69. {
  70. return new Interval(maintenanceExpiryDate.minusDays(NEARLY_EXPIRED_DAYS), maintenanceExpiryDate).contains(new DateTime());
  71. }
  72. return false; //no maintenance expiration date means it is never "nearly maintenance expired"
  73. }
  74. };
  75. }
  76. public static Predicate<PluginLicense> isRecentlyExpired()
  77. {
  78. return new IsRecentlyExpired();
  79. }
  80. private static class IsRecentlyExpired implements Predicate<PluginLicense>
  81. {
  82. private final DateTime sevenDaysAgo;
  83. public IsRecentlyExpired()
  84. {
  85. this.sevenDaysAgo = new DateTime().minusDays(RECENTLY_EXPIRED_DAYS);
  86. }
  87. public boolean apply(PluginLicense license)
  88. {
  89. for (DateTime expiryDate : license.getExpiryDate())
  90. {
  91. return expiryDate.isAfter(sevenDaysAgo) && expiryDate.isBefore(new DateTime());
  92. }
  93. return false; //this plugin does not expire - return false.
  94. }
  95. }
  96. public static Predicate<PluginLicense> isRecentlyMaintenanceExpired()
  97. {
  98. return new IsRecentlyMaintenanceExpired();
  99. }
  100. private static class IsRecentlyMaintenanceExpired implements Predicate<PluginLicense>
  101. {
  102. private final DateTime sevenDaysAgo;
  103. public IsRecentlyMaintenanceExpired()
  104. {
  105. this.sevenDaysAgo = new DateTime().minusDays(RECENTLY_EXPIRED_DAYS);
  106. }
  107. public boolean apply(PluginLicense license)
  108. {
  109. for (DateTime maintenanceExpiryDate : license.getMaintenanceExpiryDate())
  110. {
  111. return maintenanceExpiryDate.isAfter(sevenDaysAgo) && maintenanceExpiryDate.isBefore(new DateTime());
  112. }
  113. return false; //this plugin does not maintenance expire - return false.
  114. }
  115. }
  116. public static Predicate<PluginLicense> isEvaluation()
  117. {
  118. return new Predicate<PluginLicense>()
  119. {
  120. @Override
  121. public boolean apply(PluginLicense license)
  122. {
  123. return license.isEvaluation();
  124. }
  125. };
  126. }
  127. public static Predicate<PluginLicense> isEmbeddedWithinHostLicense()
  128. {
  129. return new Predicate<PluginLicense>()
  130. {
  131. @Override
  132. public boolean apply(PluginLicense license)
  133. {
  134. return license.isEmbeddedWithinHostLicense();
  135. }
  136. };
  137. }
  138. /**
  139. * Returns the number of days since maintenance expiry, or none() if no maintenance expiry has expired
  140. *
  141. * @param pluginLicense the license
  142. * @return the number of days since maintenance expiry, or none() if no maintenance expiry has expired
  143. */
  144. public static Option<Days> getDaysSinceMaintenanceExpiry(PluginLicense pluginLicense)
  145. {
  146. for (DateTime maintenanceExpiryDate : pluginLicense.getMaintenanceExpiryDate())
  147. {
  148. if (!pluginLicense.isMaintenanceExpired())
  149. {
  150. return none(Days.class);
  151. }
  152. return some(Days.daysBetween(maintenanceExpiryDate, new DateTime()));
  153. }
  154. return none(Days.class);
  155. };
  156. /**
  157. * Returns true if the given plugin license can be bought directly from My Atlassian, false otherwise
  158. * @param pluginLicense the plugin license
  159. * @return true if the given plugin license can be bought directly from My Atlassian, false otherwise
  160. */
  161. public static boolean isPluginBuyable(Option<PluginLicense> pluginLicense)
  162. {
  163. for (PluginLicense registeredLicense : pluginLicense)
  164. {
  165. //can only buy if the current license is an eval license or of the wrong type (e.g. commercial, academic)
  166. return registeredLicense.isEvaluation() || isErrorEqual(registeredLicense.getError(), LicenseError.TYPE_MISMATCH);
  167. }
  168. //plugin is unlicensed - it can be bought.
  169. return true;
  170. }
  171. /**
  172. * Returns true if the given plugin license can be evaluated directly from My Atlassian, false otherwise
  173. * @param pluginLicense the plugin license
  174. * @return true if the given plugin license can be evaluated directly from My Atlassian, false otherwise
  175. */
  176. public static boolean isPluginTryable(Option<PluginLicense> pluginLicense)
  177. {
  178. //only unlicensed plugins are tryable
  179. return !pluginLicense.isDefined();
  180. }
  181. /**
  182. * Returns true if the given plugin license can be renewed directly from My Atlassian, false otherwise
  183. * @param pluginLicense the plugin license
  184. * @return true if the given plugin license can be renewed directly from My Atlassian, false otherwise
  185. */
  186. public static boolean isPluginRenewable(Option<PluginLicense> pluginLicense)
  187. {
  188. //plugins that are eligible to be upgraded cannot be renewed
  189. if (isPluginUpgradable(pluginLicense))
  190. {
  191. return false;
  192. }
  193. for (PluginLicense registeredLicense : pluginLicense)
  194. {
  195. boolean nearlyExpired = PluginLicenses.isNearlyExpired().apply(registeredLicense);
  196. boolean nearlyMaintenanceExpired = PluginLicenses.isNearlyMaintenanceExpired().apply(registeredLicense);
  197. boolean maintenanceExpired = registeredLicense.isMaintenanceExpired();
  198. boolean hasAppropriateError = registeredLicense.getError().isDefined() &&
  199. ImmutableSet.of(EXPIRED, VERSION_MISMATCH).contains(registeredLicense.getError().get());
  200. boolean hasAppropriateType = ImmutableSet.of(ACADEMIC, COMMERCIAL, STARTER).contains(registeredLicense.getLicenseType());
  201. boolean evaluation = registeredLicense.isEvaluation();
  202. //can only renew plugins which are expired, nearly expired, maintenance expired, or nearly maintenance expired,
  203. //and only if the current license is of type Academic, Commercial, or Starter
  204. return (nearlyExpired || nearlyMaintenanceExpired || maintenanceExpired || hasAppropriateError) && hasAppropriateType && !evaluation;
  205. }
  206. //plugin is unlicensed - it cannot be renewed.
  207. return false;
  208. }
  209. /**
  210. * Returns true if the given plugin license can be upgraded directly from My Atlassian, false otherwise
  211. * @param pluginLicense the plugin license
  212. * @return true if the given plugin license can be upgraded directly from My Atlassian, false otherwise
  213. */
  214. public static boolean isPluginUpgradable(Option<PluginLicense> pluginLicense)
  215. {
  216. //don't offer to Upgrade anything that is eligible to be bought
  217. if (isPluginBuyable(pluginLicense))
  218. {
  219. return false;
  220. }
  221. for (PluginLicense registeredLicense : pluginLicense)
  222. {
  223. //can only upgrade when a user mismatch or edition mismatch exists
  224. return isErrorEqual(registeredLicense.getError(), LicenseError.USER_MISMATCH) ||
  225. isErrorEqual(registeredLicense.getError(), LicenseError.EDITION_MISMATCH);
  226. }
  227. //plugin is unlicensed - it cannot be upgraded.
  228. return false;
  229. }
  230. public static Function<PluginLicense, String> licensePluginKey()
  231. {
  232. return licensePluginKey;
  233. }
  234. private static final Function<PluginLicense, String> licensePluginKey = new Function<PluginLicense, String>()
  235. {
  236. public String apply(PluginLicense from)
  237. {
  238. return from.getPluginKey();
  239. }
  240. };
  241. public static Function<PluginLicense, DateTime> licenseCreationDate()
  242. {
  243. return licenseCreationDate;
  244. }
  245. private static final Function<PluginLicense, DateTime> licenseCreationDate = new Function<PluginLicense, DateTime>()
  246. {
  247. public DateTime apply(PluginLicense from)
  248. {
  249. return from.getCreationDate();
  250. }
  251. };
  252. /**
  253. * Executes a null-safe (and option-safe) equality check.
  254. */
  255. private static boolean isErrorEqual(Option<LicenseError> possibleError, LicenseError equalTo)
  256. {
  257. for (LicenseError error : possibleError)
  258. {
  259. return equalTo.equals(error);
  260. }
  261. return false;
  262. }
  263. }