PageRenderTime 53ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/jira-project/jira-components/jira-core/src/main/java/com/atlassian/jira/upgrade/tasks/DowngradeTask_Build70024.java

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
Java | 306 lines | 255 code | 45 blank | 6 comment | 8 complexity | d6a85588c732cb1fcdf6d7d665d74890 MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.jira.upgrade.tasks;
  2. import com.atlassian.jira.database.DbConnection;
  3. import com.atlassian.jira.database.SqlCallback;
  4. import com.atlassian.jira.model.querydsl.QAvatar;
  5. import com.atlassian.jira.model.querydsl.QOSPropertyEntry;
  6. import com.atlassian.jira.model.querydsl.QOSPropertyNumber;
  7. import com.atlassian.jira.model.querydsl.QOSPropertyString;
  8. import com.atlassian.jira.model.querydsl.QProject;
  9. import com.atlassian.jira.upgrade.AbstractDowngradeTask;
  10. import com.atlassian.jira.upgrade.DowngradeException;
  11. import com.atlassian.jira.upgrade.ReindexRequirement;
  12. import com.google.common.collect.ImmutableList;
  13. import com.google.common.collect.ImmutableMap;
  14. import com.querydsl.sql.SQLExpressions;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import javax.annotation.Nonnull;
  18. import javax.annotation.Nullable;
  19. import java.util.List;
  20. import java.util.Map;
  21. /**
  22. * Downgrades avatar icons from SVG to PNG. This includes only system avatar icons for users, projects and issue types.
  23. *
  24. * @since 6.4.8
  25. */
  26. public final class DowngradeTask_Build70024 extends AbstractDowngradeTask {
  27. private static final Logger log = LoggerFactory.getLogger(DowngradeTask_Build70024.class);
  28. private static final int TRUE = 1;
  29. private static final int NUMBER_TYPE = 3;
  30. private static final String ISSUE_TYPE_AVATAR = "issuetype";
  31. private static final String PROJECT_AVATAR = "project";
  32. private static final String USER_AVATAR = "user";
  33. private static final String DEFAULT_PROJECT_AVATAR_KEY = "jira.avatar.default.id";
  34. private static final String DEFAULT_PROJECT_AVATAR_NAME = "rocket.png";
  35. private static final String USER_ENTITY_NAME = "ApplicationUser";
  36. private static final String USER_AVATAR_PROPERTY_KEY = "user.avatar.id";
  37. private static final String PNG_CONTENT_TYPE = "image/png";
  38. private static final String SVG_CONTENT_TYPE = "image/svg+xml";
  39. private static final Map<String, String> ISSUE_TYPE_ICONS_TO_RENAME = ImmutableMap.<String, String>builder()
  40. .put("task.svg", "task.png")
  41. .put("subtask.svg", "subtask.png")
  42. .put("story.svg", "story.png")
  43. .put("improvement.svg", "improvement.png")
  44. .put("sales.svg", "sales.png")
  45. .put("design_task.svg", "health.png")
  46. .put("remove_feature.svg", "remove_feature.png")
  47. .put("requirement.svg", "requirement.png")
  48. .put("newfeature.svg", "newfeature.png")
  49. .put("exclamation.svg", "exclamation.png")
  50. .put("documentation.svg", "documentation.png")
  51. .put("defect.svg", "defect.png")
  52. .put("epic.svg", "epic.png")
  53. .put("genericissue.svg", "genericissue.png")
  54. .put("bug.svg", "bug.png")
  55. .put("question.svg", "undefined.png")
  56. .put("development_task.svg", "development_task.png")
  57. .put("feedback.svg", "feedback.png")
  58. .put("request_access.svg", "request_access.png")
  59. .build();
  60. private static final Map<String, String> PROJECT_ICONS_TO_RENAME = ImmutableMap.<String, String>builder()
  61. .put("cloud.svg", "cloud.png")
  62. .put("spanner.svg", "config.png")
  63. .put("cd.svg", "disc.png")
  64. .put("bird.svg", "eamesbird.png")
  65. .put("money.svg", "finance.png")
  66. .put("mouse-hand.svg", "hand.png")
  67. .put("koala.svg", "kangaroo.png")
  68. .put("yeti.svg", "new_monster.png")
  69. .put("power.svg", "power.png")
  70. .put("nature.svg", "rainbow.png")
  71. .put("refresh.svg", "refresh.png")
  72. .put("rocket.svg", "rocket.png")
  73. .put("phone.svg", "servicedesk.png")
  74. .put("settings.svg", "settings.png")
  75. .put("storm.svg", "storm.png")
  76. .put("plane.svg", "travel.png")
  77. .build();
  78. private static final List<String> PROJECT_ICONS_TO_REMOVE = ImmutableList.of("default.svg", "code.svg", "coffee.svg",
  79. "design.svg", "drill.svg", "food.svg", "notes.svg", "red-flag.svg", "science.svg", "spanner.svg", "support.svg");
  80. private static final Map<String, String> USER_ICONS_TO_RENAME = ImmutableMap.<String, String>builder()
  81. .put("Avatar-default.svg", "Avatar-default.png")
  82. .build();
  83. private static final List<String> USER_ICONS_TO_REMOVE = ImmutableList.of("bull.svg", "cat.svg", "dog.svg", "female_1.svg", "female_2.svg",
  84. "female_3.svg", "female_4.svg", "ghost.svg", "male_1.svg", "male_2.svg", "male_3.svg", "male_4.svg", "male_5.svg",
  85. "male_6.svg", "male_8.svg", "owl.svg", "pirate.svg", "robot.svg", "vampire.svg");
  86. @Override
  87. public void downgrade() throws DowngradeException {
  88. downgradeIssueTypeIcons();
  89. downgradeProjectIcons();
  90. downgradeUserIcons();
  91. }
  92. private void downgradeIssueTypeIcons() {
  93. getDbConnectionManager().execute(new SqlCallback() {
  94. @Override
  95. public void run(final DbConnection connection) {
  96. connection.setAutoCommit(false);
  97. final QAvatar a = QAvatar.AVATAR;
  98. for (Map.Entry<String, String> iconToRenameEntry : ISSUE_TYPE_ICONS_TO_RENAME.entrySet()) {
  99. final String oldIconName = iconToRenameEntry.getKey();
  100. final String newIconName = iconToRenameEntry.getValue();
  101. connection
  102. .update(a)
  103. .where(a.avatarType.eq(ISSUE_TYPE_AVATAR)
  104. .and(a.systemAvatar.eq(TRUE))
  105. .and(a.fileName.eq(oldIconName)))
  106. .set(a.fileName, newIconName)
  107. .set(a.contentType, PNG_CONTENT_TYPE)
  108. .execute();
  109. }
  110. connection.commit();
  111. }
  112. });
  113. }
  114. private void downgradeProjectIcons() {
  115. getDbConnectionManager().execute(new SqlCallback() {
  116. @Override
  117. public void run(final DbConnection connection) {
  118. connection.setAutoCommit(false);
  119. final QAvatar a = QAvatar.AVATAR;
  120. for (Map.Entry<String, String> projectIconToRenameEntry : PROJECT_ICONS_TO_RENAME.entrySet()) {
  121. final String oldIconName = projectIconToRenameEntry.getKey();
  122. final String newIconName = projectIconToRenameEntry.getValue();
  123. connection
  124. .update(a)
  125. .where(a.avatarType.eq(PROJECT_AVATAR)
  126. .and(a.systemAvatar.eq(TRUE))
  127. .and(a.fileName.eq(oldIconName)))
  128. .set(a.fileName, newIconName)
  129. .set(a.contentType, PNG_CONTENT_TYPE)
  130. .execute();
  131. }
  132. final QOSPropertyEntry entry = QOSPropertyEntry.O_S_PROPERTY_ENTRY;
  133. final QOSPropertyString property = QOSPropertyString.O_S_PROPERTY_STRING;
  134. final Long defaultProjectAvatarId = obtainDefaultProjectIcon(connection);
  135. connection
  136. .update(property)
  137. .where(property.id.eq(SQLExpressions
  138. .select(entry.id)
  139. .from(entry)
  140. .where(entry.propertyKey.eq(DEFAULT_PROJECT_AVATAR_KEY))))
  141. .set(property.value, defaultProjectAvatarId.toString())
  142. .execute();
  143. //List of system avatar ids to be renamed. On a sane instance this should be no more than 20.
  144. final List<Long> oldAvatarIds = connection
  145. .newSqlQuery()
  146. .select(a.id)
  147. .from(a)
  148. .where(a.avatarType.eq(PROJECT_AVATAR)
  149. .and(a.systemAvatar.eq(TRUE)
  150. .and(a.fileName.in(PROJECT_ICONS_TO_REMOVE))))
  151. .fetch();
  152. final QProject p = QProject.PROJECT;
  153. if (!oldAvatarIds.isEmpty()) {
  154. connection
  155. .update(p)
  156. .where(p.avatar.in(oldAvatarIds))
  157. .set(p.avatar, defaultProjectAvatarId)
  158. .execute();
  159. } else {
  160. log.warn("No project icons to downgrade found.");
  161. }
  162. connection
  163. .delete(a)
  164. .where(a.fileName.in(PROJECT_ICONS_TO_REMOVE)
  165. .and(a.systemAvatar.eq(TRUE))
  166. .and(a.avatarType.eq(PROJECT_AVATAR)
  167. .and(a.contentType.eq(SVG_CONTENT_TYPE))))
  168. .execute();
  169. connection.commit();
  170. }
  171. });
  172. }
  173. private void downgradeUserIcons() {
  174. getDbConnectionManager().execute(new SqlCallback() {
  175. @Override
  176. public void run(final DbConnection connection) {
  177. connection.setAutoCommit(false);
  178. final QAvatar a = QAvatar.AVATAR;
  179. for (Map.Entry<String, String> userIconToUpdate : USER_ICONS_TO_RENAME.entrySet()) {
  180. final String oldIconName = userIconToUpdate.getKey();
  181. final String newIconName = userIconToUpdate.getValue();
  182. connection.update(a)
  183. .where(a.avatarType.eq(USER_AVATAR)
  184. .and(a.systemAvatar.eq(TRUE))
  185. .and(a.fileName.eq(oldIconName)))
  186. .set(a.fileName, newIconName)
  187. .set(a.contentType, PNG_CONTENT_TYPE)
  188. .execute();
  189. }
  190. QOSPropertyEntry e = QOSPropertyEntry.O_S_PROPERTY_ENTRY;
  191. QOSPropertyNumber n = QOSPropertyNumber.O_S_PROPERTY_NUMBER;
  192. connection
  193. .delete(n)
  194. .where(n.id.in(SQLExpressions
  195. .select(e.id)
  196. .from(e)
  197. .where(e.entityName.eq(USER_ENTITY_NAME)
  198. .and(e.propertyKey.eq(USER_AVATAR_PROPERTY_KEY))
  199. .and(e.type.eq(NUMBER_TYPE))))
  200. .and(n.value.in(SQLExpressions
  201. .select(a.id)
  202. .from(a)
  203. .where(a.avatarType.eq(USER_AVATAR)
  204. .and(a.systemAvatar.eq(TRUE))
  205. .and(a.fileName.in(USER_ICONS_TO_REMOVE))))))
  206. .execute();
  207. connection
  208. .delete(a)
  209. .where(a.fileName.in(USER_ICONS_TO_REMOVE)
  210. .and(a.systemAvatar.eq(TRUE))
  211. .and(a.avatarType.eq(USER_AVATAR)
  212. .and(a.contentType.eq(SVG_CONTENT_TYPE))))
  213. .execute();
  214. connection.commit();
  215. }
  216. });
  217. }
  218. private Long obtainDefaultProjectIcon(final DbConnection connection) {
  219. final QAvatar a = QAvatar.AVATAR;
  220. @Nullable final Long defaultProjectAvatarId = selectDefaultProjectIcon(connection);
  221. if (defaultProjectAvatarId == null) {
  222. connection
  223. .insert(a)
  224. .set(a.fileName, DEFAULT_PROJECT_AVATAR_NAME)
  225. .set(a.contentType, PNG_CONTENT_TYPE)
  226. .set(a.avatarType, PROJECT_AVATAR)
  227. .set(a.systemAvatar, TRUE)
  228. .withId()
  229. .execute();
  230. return selectDefaultProjectIcon(connection);
  231. } else {
  232. return defaultProjectAvatarId;
  233. }
  234. }
  235. @Nullable
  236. private Long selectDefaultProjectIcon(final DbConnection connection) {
  237. final QAvatar a = QAvatar.AVATAR;
  238. return connection.newSqlQuery()
  239. .select(a.id)
  240. .from(a)
  241. .where(a.avatarType.eq(PROJECT_AVATAR)
  242. .and(a.systemAvatar.eq(TRUE))
  243. .and(a.fileName.eq(DEFAULT_PROJECT_AVATAR_NAME)))
  244. .limit(1)
  245. .fetchOne();
  246. }
  247. @Override
  248. public int getBuildNumber() {
  249. return 70024;
  250. }
  251. @Nonnull
  252. @Override
  253. public String getShortDescription() {
  254. return "Downgrade issue type, project and user icons to raster versions.";
  255. }
  256. @Nonnull
  257. @Override
  258. public ReindexRequirement reindexRequired() {
  259. return ReindexRequirement.NONE;
  260. }
  261. }