PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/valiantys/jira/plugins/createissueandlink/CreateSubtaskIssueAndLinkDetails.java

https://bitbucket.org/valiantys-dev/jcalp
Java | 397 lines | 295 code | 47 blank | 55 comment | 53 complexity | 765aa1c4573c97473adecdd29140beb2 MD5 | raw file
  1. package com.valiantys.jira.plugins.createissueandlink;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5. import java.util.Collection;
  6. import java.util.HashMap;
  7. import java.util.Iterator;
  8. import java.util.StringTokenizer;
  9. import org.apache.log4j.Logger;
  10. import org.ofbiz.core.entity.GenericEntityException;
  11. import webwork.action.ResultException;
  12. import com.atlassian.core.util.FileUtils;
  13. import com.atlassian.jira.ComponentManager;
  14. import com.atlassian.jira.bc.issue.IssueService;
  15. import com.atlassian.jira.config.ConstantsManager;
  16. import com.atlassian.jira.config.SubTaskManager;
  17. import com.atlassian.jira.config.properties.PropertiesManager;
  18. import com.atlassian.jira.issue.Issue;
  19. import com.atlassian.jira.issue.IssueFactory;
  20. import com.atlassian.jira.issue.IssueManager;
  21. import com.atlassian.jira.issue.ModifiedValue;
  22. import com.atlassian.jira.issue.MutableIssue;
  23. import com.atlassian.jira.issue.attachment.Attachment;
  24. import com.atlassian.jira.issue.customfields.option.Option;
  25. import com.atlassian.jira.issue.customfields.option.Options;
  26. import com.atlassian.jira.issue.fields.CustomField;
  27. import com.atlassian.jira.issue.fields.FieldManager;
  28. import com.atlassian.jira.issue.fields.OrderableField;
  29. import com.atlassian.jira.issue.fields.screen.FieldScreenRendererFactory;
  30. import com.atlassian.jira.issue.index.IndexException;
  31. import com.atlassian.jira.issue.index.IssueIndexManager;
  32. import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
  33. import com.atlassian.jira.security.JiraAuthenticationContext;
  34. import com.atlassian.jira.util.AttachmentUtils;
  35. import com.atlassian.jira.web.action.issue.CreateSubTaskIssueDetails;
  36. import com.atlassian.jira.web.action.issue.IssueCreationHelperBean;
  37. import com.atlassian.jira.web.util.AttachmentException;
  38. import com.atlassian.jira.web.util.SubTaskQuickCreationConfig;
  39. import com.opensymphony.module.propertyset.PropertySet;
  40. import com.opensymphony.user.EntityNotFoundException;
  41. import com.opensymphony.user.UserManager;
  42. import com.valiantys.jira.plugins.createissueandlink.lnioCastor.Watcher;
  43. import com.valiantys.jira.plugins.createissueandlink.lnioCastor.WatcherToAddItem;
  44. public class CreateSubtaskIssueAndLinkDetails extends CreateSubTaskIssueDetails {
  45. /**
  46. * Logger.
  47. */
  48. private final static Logger LOG = Logger.getLogger(CreateSubtaskIssueAndLinkDetails.class);
  49. /**
  50. * Attachments Path.
  51. */
  52. private String attachmentHome;
  53. /**
  54. * Authentication context.
  55. */
  56. private final JiraAuthenticationContext authenticationContext;
  57. private String mappingid;
  58. public CreateSubtaskIssueAndLinkDetails(ConstantsManager constantsManager,
  59. SubTaskManager subTaskManager,
  60. IssueCreationHelperBean issueCreationHelperBean,
  61. SubTaskQuickCreationConfig subTaskQuickCreationConfig,
  62. FieldScreenRendererFactory fieldScreenRendererFactory,
  63. IssueFactory issueFactory, IssueService issueService,
  64. final JiraAuthenticationContext context) {
  65. super(constantsManager, subTaskManager, issueCreationHelperBean,
  66. subTaskQuickCreationConfig, fieldScreenRendererFactory, issueFactory,
  67. issueService);
  68. this.authenticationContext = context;
  69. PropertySet propSet = PropertiesManager.getInstance().getPropertySet();
  70. attachmentHome = propSet.getString("jira.path.attachments");
  71. LOG.debug("Attachments path : " + attachmentHome);
  72. }
  73. protected void validate() throws ResultException {
  74. super.validate();
  75. }
  76. /**
  77. * Action called to create the new issue.
  78. * @return the next page : the issue parent detail.
  79. * @throws Exception : Exception.
  80. */
  81. protected final String doExecute() throws Exception {
  82. return super.doExecute();
  83. }
  84. /**
  85. * Action called automatically by the JIRA api, after a creation of issue.
  86. * This action has in chage to : <br>
  87. * - Create a link between 2 issues.<br>
  88. * - Duplication of attachments if it is configured.<br>
  89. * - Add watcher if it is configured.<br>
  90. * - Update parent issue's field if it is configured.<br>
  91. * - and re-index the issue.<br>
  92. * @return the next page : the issue parent detail.
  93. * @throws Exception : Exception.
  94. */
  95. protected final String doPostCreationTasks() throws Exception {
  96. // retrieve the parent issue
  97. MutableIssue parentIssue = ComponentManager.getInstance().getIssueManager().getIssueObject(getParentIssueId());
  98. MutableIssue currentIssue = this.getIssueObject();
  99. LOG.debug("currentIssue : " + currentIssue.getKey());
  100. // retrieve the LinkedIssueContextManager.
  101. LinkedIssueContextManager licm = LinkedIssueContextManager
  102. .getInstance();
  103. // Duplication of attachements if it is needed.
  104. if (licm.isDuplicateAttachmentsActivated(parentIssue, mappingid)) {
  105. duplicatAttachments(parentIssue, currentIssue);
  106. }
  107. // Add watchers
  108. if (licm.isIssueMapped(parentIssue, mappingid)) {
  109. if (licm.isWatcherToAdd(parentIssue, mappingid)) {
  110. addWatcherToChildIssue(parentIssue);
  111. }
  112. }
  113. // update fields of parent issue
  114. if (licm.AreParentFieldsToUpdate(parentIssue, mappingid)) {
  115. // CustomFields
  116. HashMap cfIds = licm.getParentCustomFieldsIdsToUpdate(parentIssue,
  117. mappingid);
  118. if (cfIds != null && !cfIds.isEmpty()) {
  119. LOG.debug("cfIds to update = " + cfIds.toString());
  120. FieldManager fm = (FieldManager) ComponentManager
  121. .getComponentInstanceOfType(FieldManager.class);
  122. for (Iterator it = cfIds.keySet().iterator(); it.hasNext();) {
  123. String id = it.next().toString();
  124. CustomField cf = fm.getCustomField(id);
  125. if (cf != null) {
  126. Options options = cf.getOptions(null, cf
  127. .getRelevantConfig(parentIssue), null);
  128. String newValue = null;
  129. if (options != null) {
  130. LOG.debug("the cf : " + id
  131. + " has options, checks if the new value "
  132. + cfIds.get(id) + " is a valid option");
  133. if (options.getOptionForValue(cfIds.get(id)
  134. .toString(), null) == null) {
  135. LOG.error("the option " + cfIds.get(id)
  136. + " for the field" + id
  137. + " is not valid");
  138. Collection err = getErrorMessages();
  139. err
  140. .add("unable to update field "
  141. + cf.getName()
  142. + " of the parentIssue,\n the new value "
  143. + cfIds.get(id)
  144. + " is not a valid option for this field");
  145. setErrorMessages(err);
  146. } else {
  147. Option option = options.getOptionForValue(cfIds
  148. .get(id).toString(), null);
  149. newValue = option.getValue();
  150. }
  151. } else {
  152. newValue = cfIds.get(id).toString();
  153. }
  154. LOG.debug("parent cf to update : " + id);
  155. LOG.debug("parent cf old value : "
  156. + parentIssue.getCustomFieldValue(cf));
  157. LOG.debug("parent cf new value : " + newValue);
  158. if (newValue != null) {
  159. try {
  160. cf.updateValue(null, parentIssue,
  161. new ModifiedValue(parentIssue
  162. .getCustomFieldValue(cf),
  163. newValue),
  164. new DefaultIssueChangeHolder());
  165. } catch (Exception e) {
  166. Collection err = getErrorMessages();
  167. err
  168. .add("unable to update field : "
  169. + cf.getName()
  170. + " of the parentIssue, the new value : "
  171. + newValue
  172. + ", is not valid for this field");
  173. setErrorMessages(err);
  174. LOG
  175. .error("unable to update field of the parentIssue");
  176. LOG.error(e.getMessage());
  177. }
  178. }
  179. }
  180. }
  181. }
  182. // System fields
  183. HashMap fieldIds = licm.getParentFieldsToUpdate(parentIssue,
  184. mappingid);
  185. if (fieldIds != null && !fieldIds.isEmpty()) {
  186. LOG.debug("fieldsIds to update = " + fieldIds.toString());
  187. FieldManager fm = (FieldManager) ComponentManager
  188. .getComponentInstanceOfType(FieldManager.class);
  189. IssueManager im = (IssueManager) ComponentManager
  190. .getComponentInstanceOfType(IssueManager.class);
  191. for (Iterator it = fieldIds.keySet().iterator(); it.hasNext();) {
  192. String id = it.next().toString();
  193. OrderableField field = (OrderableField) fm.getField(id);
  194. if (field != null) {
  195. LOG.debug("parent field to update : " + id);
  196. LOG.debug("parent field new value : "
  197. + fieldIds.get(id));
  198. try {
  199. MutableIssue mut = im.getIssueObject(parentIssue
  200. .getId());
  201. field.updateIssue(null, mut, fieldIds);
  202. mut.store();
  203. } catch (Exception e) {
  204. Collection err = getErrorMessages();
  205. err.add("unable to update field : " + id
  206. + " of the parentIssue, the new value : "
  207. + fieldIds.get(id)
  208. + ", is not valid for this field");
  209. setErrorMessages(err);
  210. LOG
  211. .error("unable to update field of the parentIssue");
  212. LOG.error(e.getMessage());
  213. }
  214. }
  215. }
  216. }
  217. // reindex the issue
  218. IssueIndexManager indexManager = ComponentManager.getInstance()
  219. .getIndexManager();
  220. try {
  221. indexManager.reIndex(parentIssue);
  222. } catch (IndexException e) {
  223. LOG.error("unable to reindex the issue, " + e.getMessage());
  224. }
  225. }
  226. return super.doPostCreationTasks();
  227. }
  228. /**
  229. * Method used to duplicate the attachments form the parent issue to the
  230. * child issue.
  231. *
  232. * @param issueParent
  233. * : issue parent.
  234. * @param issueChild
  235. * : issue child.
  236. */
  237. private void duplicatAttachments(final Issue issueParent,
  238. final Issue issueChild) {
  239. ArrayList attachments = (ArrayList) issueParent.getAttachments();
  240. if (attachments.size() != 0) {
  241. for (int i = 0; i < attachments.size(); i++) {
  242. Attachment att = (Attachment) attachments.get(i);
  243. File origAttachment = AttachmentUtils.getAttachmentFile(att);
  244. File newAttachment = new File(attachmentHome + File.separator
  245. + att.getFilename());
  246. try {
  247. FileUtils.copyFile(origAttachment, newAttachment);
  248. attachmentManager.createAttachment(newAttachment,
  249. newAttachment.getName(), att.getMimetype(),
  250. authenticationContext.getUser(), issueChild
  251. .getGenericValue());
  252. LOG.debug("The attachments : " + newAttachment.getName()
  253. + " is added to the new issue.");
  254. } catch (IOException e) {
  255. log.error("An error occurs : " + e.getMessage());
  256. } catch (AttachmentException e) {
  257. log.error("An error occurs : " + e.getMessage());
  258. } catch (GenericEntityException e) {
  259. log.error("An error occurs : " + e.getMessage());
  260. }
  261. }
  262. }
  263. }
  264. /**
  265. * This method is used to add defined watchers to the child issue.
  266. * @param parentIssue : the parent Issue.
  267. * @throws LinkNewIssueOperationException : LinkNewIssueOperationException.
  268. * @throws EntityNotFoundException : EntityNotFoundException.
  269. *
  270. */
  271. private void addWatcherToChildIssue(final Issue parentIssue)
  272. throws LinkNewIssueOperationException, EntityNotFoundException {
  273. WatcherToAddItem[] watcherToAddItems = LinkedIssueContextManager
  274. .getInstance().getWatcherToAddItems(parentIssue, mappingid);
  275. UserManager userManager = new UserManager();
  276. for (int i = 0; i < watcherToAddItems.length; i++) {
  277. Watcher watcher = watcherToAddItems[i].getWatcher();
  278. String role = LinkedIssueContextManager.getInstance()
  279. .getWatcherToAddRole(watcher);
  280. if (role != null && role.length() > 0) {
  281. if (getFieldValuesHolder().get(role) != null
  282. && getFieldValuesHolder().get(role).toString()
  283. .length() > 0) {
  284. String userName = getFieldValuesHolder().get(role)
  285. .toString();
  286. getWatcherManager().startWatching(
  287. userManager.getUser(userName),
  288. getIssueObject().getGenericValue());
  289. }
  290. } else {
  291. String cfId = LinkedIssueContextManager.getInstance()
  292. .getWatcherToAddCfId(watcher);
  293. if (getCustomFieldManager().getCustomFieldObject(
  294. Long.valueOf(cfId)) != null) {
  295. String[] list = getListOfWatchersToAdd(cfId, parentIssue);
  296. if (list != null && list.length > 0) {
  297. for (int j = 0; j < list.length; j++) {
  298. try {
  299. if (userManager.getUser(list[j]) != null) {
  300. getWatcherManager().startWatching(
  301. userManager.getUser(list[j]),
  302. getIssueObject().getGenericValue());
  303. } else {
  304. LOG.warn("Could not add watcher, "
  305. + list[j] + " not a user");
  306. }
  307. } catch (Exception e) {
  308. LOG.warn("Could not add watcher, " + list[j]
  309. + " not a user");
  310. }
  311. }
  312. }
  313. } else {
  314. LOG.warn("No custom field of id = " + cfId
  315. + "No Watchers Added by custom field Id");
  316. }
  317. }
  318. }
  319. }
  320. /**
  321. *
  322. * @param cfId : custom field ID.
  323. * @param parentIssue : Parent Issue ID.
  324. * @return an array of users names to add as watcher
  325. */
  326. private String[] getListOfWatchersToAdd(final String cfId, final Issue parentIssue) {
  327. String[] list = null;
  328. if (cfId != null && cfId.length() > 0) {
  329. String stringList = getCustomFieldManager().getCustomFieldObject(
  330. "customfield_".concat(cfId)).getValue(parentIssue)
  331. .toString();
  332. if (stringList != null && stringList != "[]") {
  333. StringTokenizer st = new StringTokenizer(stringList, ",[]");
  334. int i = 0;
  335. list = new String[st.countTokens()];
  336. while (st.hasMoreTokens()) {
  337. list[i] = st.nextToken().trim();
  338. i++;
  339. }
  340. }
  341. }
  342. return list;
  343. }
  344. public String getMappingid() {
  345. return mappingid;
  346. }
  347. public void setMappingid(String mappingid) {
  348. this.mappingid = mappingid;
  349. }
  350. }