PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jira-project/jira-components/jira-plugins/jira-lookandfeel-plugin/src/main/java/com/atlassian/jira/lookandfeel/AutoLookAndFeelManager.java

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
Java | 219 lines | 175 code | 35 blank | 9 comment | 26 complexity | 98c77311ba2810ab45cfab6a17753d06 MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.jira.lookandfeel;
  2. import com.atlassian.jira.bc.admin.ApplicationPropertiesService;
  3. import com.atlassian.jira.bc.admin.ApplicationProperty;
  4. import com.atlassian.jira.config.properties.APKeys;
  5. import com.atlassian.jira.config.properties.ApplicationProperties;
  6. import com.atlassian.jira.lookandfeel.upload.UploadService;
  7. import com.atlassian.jira.user.ApplicationUser;
  8. import com.atlassian.jira.user.UserPropertyManager;
  9. import com.atlassian.jira.web.ServletContextProvider;
  10. import com.atlassian.sal.api.pluginsettings.PluginSettings;
  11. import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
  12. import javax.imageio.ImageIO;
  13. import java.awt.*;
  14. import java.awt.image.BufferedImage;
  15. import java.io.File;
  16. import java.io.FileInputStream;
  17. import java.io.IOException;
  18. import java.io.InputStream;
  19. public class AutoLookAndFeelManager {
  20. private static final HSBColor LIGHT_TEXT = new HSBColor(Color.white);
  21. private static final HSBColor DARK_TEXT = new HSBColor(new Color(41, 41, 41));
  22. private static final String JUST_UPDATED_KEY = "lookandfeel.auto.just.updated";
  23. private static final String[] COLOR_KEYS = {
  24. // Background colours
  25. APKeys.JIRA_LF_TOP_BGCOLOUR,
  26. APKeys.JIRA_LF_TOP_HIGHLIGHTCOLOR,
  27. APKeys.JIRA_LF_TOP_SEPARATOR_BGCOLOR,
  28. APKeys.JIRA_LF_MENU_BGCOLOUR,
  29. APKeys.JIRA_LF_HERO_BUTTON_BASEBGCOLOUR,
  30. // Text colours
  31. APKeys.JIRA_LF_TOP_TEXTCOLOUR,
  32. APKeys.JIRA_LF_TOP_TEXTHIGHLIGHTCOLOR,
  33. APKeys.JIRA_LF_MENU_TEXTCOLOUR,
  34. APKeys.JIRA_LF_HERO_BUTTON_TEXTCOLOUR
  35. };
  36. private final ApplicationProperties applicationProperties;
  37. private final ApplicationPropertiesService applicationPropertiesService;
  38. private final UserPropertyManager userPropertyManager;
  39. private final UploadService uploadService;
  40. private final PluginSettings globalSettings;
  41. public AutoLookAndFeelManager(final ApplicationProperties applicationProperties,
  42. final ApplicationPropertiesService applicationPropertiesService,
  43. final UserPropertyManager userPropertyManager, final UploadService uploadService,
  44. final PluginSettingsFactory pluginSettingsFactory) {
  45. this.applicationProperties = applicationProperties;
  46. this.applicationPropertiesService = applicationPropertiesService;
  47. this.userPropertyManager = userPropertyManager;
  48. this.uploadService = uploadService;
  49. this.globalSettings = pluginSettingsFactory.createGlobalSettings();
  50. }
  51. public void generateFromLogo(final ApplicationUser user) {
  52. final ImageInfo logoInfo = getLogoInfo();
  53. if (logoInfo.isTransparentBackground()) {
  54. // If the logo is mostly white, use the default colour scheme
  55. if (logoInfo.isMostlyWhite()) {
  56. applyDefaultColors();
  57. } else if (logoInfo.isTooBrightForWhiteBackground() && logoInfo.getPredominantColor() != null) {
  58. // If the logo is light and it has a predominant colour, use a darker version of that colour as the background
  59. setBaseColor(logoInfo.getPredominantColor().saturateByAmount(30).darkenByAmount(30));
  60. } else {
  61. // Otherwise, use a white background
  62. setBaseColors(new HSBColor(Color.white), logoInfo.getPredominantColor());
  63. }
  64. } else {
  65. // If the background is monochrome or not very saturated, find a more interesting colour for the hero button
  66. final HSBColor base = logoInfo.getBackgroundColor();
  67. if (ImageInfo.isMonochrome(base) || base.getSaturation() < 30) {
  68. setBaseColors(base, logoInfo.getPredominantColor());
  69. } else {
  70. setBaseColor(base);
  71. }
  72. }
  73. setJustUpdated(user, true);
  74. }
  75. public boolean isJustUpdated(final ApplicationUser user) {
  76. final boolean justUpdated = userPropertyManager.getPropertySet(user).getBoolean(JUST_UPDATED_KEY);
  77. if (justUpdated) {
  78. // Reset the flag now that we have read it
  79. setJustUpdated(user, false);
  80. }
  81. return justUpdated;
  82. }
  83. public void setJustUpdated(final ApplicationUser user, final boolean justUpdated) {
  84. userPropertyManager.getPropertySet(user).setBoolean(JUST_UPDATED_KEY, justUpdated);
  85. }
  86. public boolean isDefaultColorScheme() {
  87. for (final String key : COLOR_KEYS) {
  88. if (!isDefaultColor(key)) {
  89. return false;
  90. }
  91. }
  92. return true;
  93. }
  94. public boolean isDefaultColor(final String key) {
  95. final ApplicationProperty property = applicationPropertiesService.getApplicationProperty(key);
  96. return property.getMetadata().getDefaultValue().equals(property.getCurrentValue());
  97. }
  98. public void applyDefaultColors() {
  99. for (final String key : COLOR_KEYS) {
  100. applyDefaultColor(key);
  101. }
  102. }
  103. public void applyDefaultColor(final String key) {
  104. final ApplicationProperty property = applicationPropertiesService.getApplicationProperty(key);
  105. if (!property.getMetadata().getDefaultValue().equals(property.getCurrentValue())) {
  106. applicationProperties.setString(key, property.getMetadata().getDefaultValue());
  107. }
  108. }
  109. public void backupColorScheme() {
  110. for (final String key : COLOR_KEYS) {
  111. backupColor(key);
  112. }
  113. }
  114. public void backupColor(final String key) {
  115. applicationProperties.setString(key + ".backup", applicationProperties.getString(key));
  116. }
  117. public void restoreBackupColorScheme() {
  118. for (final String key : COLOR_KEYS) {
  119. restoreBackupColor(key);
  120. }
  121. }
  122. public void restoreBackupColor(final String key) {
  123. final String backupValue = applicationProperties.getString(key + ".backup");
  124. if (backupValue != null) {
  125. applicationProperties.setString(key, backupValue);
  126. } else {
  127. applyDefaultColor(key);
  128. }
  129. }
  130. public void setBaseColor(final HSBColor base) {
  131. setBaseColors(base, getHeroButtonBackground(base));
  132. }
  133. public void setBaseColors(final HSBColor base, HSBColor heroButtonBackground) {
  134. if (heroButtonBackground == null) {
  135. heroButtonBackground = getHeroButtonBackground(base);
  136. }
  137. final HSBColor baseHighlight = getBaseHighlight(heroButtonBackground);
  138. final HSBColor separator = getSeparator(base, heroButtonBackground);
  139. applicationProperties.setString(APKeys.JIRA_LF_TOP_BGCOLOUR, base.getHexString());
  140. applicationProperties.setString(APKeys.JIRA_LF_TOP_HIGHLIGHTCOLOR, baseHighlight.getHexString());
  141. applicationProperties.setString(APKeys.JIRA_LF_TOP_SEPARATOR_BGCOLOR, separator.getHexString());
  142. applicationProperties.setString(APKeys.JIRA_LF_MENU_BGCOLOUR, baseHighlight.getHexString());
  143. applicationProperties.setString(APKeys.JIRA_LF_HERO_BUTTON_BASEBGCOLOUR, heroButtonBackground.getHexString());
  144. // Figure out appropriate text colours
  145. applicationProperties.setString(APKeys.JIRA_LF_TOP_TEXTCOLOUR, getTextColor(base).getHexString());
  146. applicationProperties.setString(APKeys.JIRA_LF_TOP_TEXTHIGHLIGHTCOLOR, getTextColor(baseHighlight).getHexString());
  147. applicationProperties.setString(APKeys.JIRA_LF_MENU_TEXTCOLOUR, getTextColor(baseHighlight).getHexString());
  148. applicationProperties.setString(APKeys.JIRA_LF_HERO_BUTTON_TEXTCOLOUR, getTextColor(heroButtonBackground).getHexString());
  149. }
  150. private HSBColor getBaseHighlight(final HSBColor heroButtonBackground) {
  151. return heroButtonBackground.darkenByAmount(13);
  152. }
  153. private HSBColor getSeparator(final HSBColor base, final HSBColor heroButtonBackground) {
  154. if (ImageInfo.isMonochrome(base) && !ImageInfo.isMonochrome(heroButtonBackground)) {
  155. return heroButtonBackground.darkenByAmount(45).desaturateByAmount(25);
  156. }
  157. return base.darkenByAmount(18).desaturateByAmount(30);
  158. }
  159. private HSBColor getHeroButtonBackground(final HSBColor base) {
  160. HSBColor result = (base.getBrightness() <= 73) ? base.lightenByAmount(27) : base.darkenByAmount(27);
  161. return result.desaturateByAmount(5);
  162. }
  163. private HSBColor getTextColor(final HSBColor background) {
  164. // Check the difference in perceived brightness to determine which text colour to use
  165. final float lightTextDiff = Math.abs(background.getPerceivedBrightness() - LIGHT_TEXT.getPerceivedBrightness());
  166. final float darkTextDiff = Math.abs(background.getPerceivedBrightness() - DARK_TEXT.getPerceivedBrightness());
  167. return (lightTextDiff > darkTextDiff) ? LIGHT_TEXT : DARK_TEXT;
  168. }
  169. private ImageInfo getLogoInfo() {
  170. try {
  171. final BufferedImage image = ImageIO.read(getLogoInputStream());
  172. return new ImageInfo(image);
  173. } catch (IOException e) {
  174. throw new RuntimeException(e);
  175. }
  176. }
  177. private InputStream getLogoInputStream() throws IOException {
  178. if ("true".equals(globalSettings.get(LookAndFeelConstants.USING_CUSTOM_LOGO))) {
  179. final File logoDirectory = uploadService.getLogoDirectory();
  180. return new FileInputStream(new File(logoDirectory, LookAndFeelConstants.JIRA_SCALED_LOGO_FILENAME));
  181. }
  182. return ServletContextProvider.getServletContext().getResourceAsStream(LookAndFeelConstants.BUILTIN_DEFAULT_LOGO_URL);
  183. }
  184. }