PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/example/plugins/tutorial/jira/workflow/CloseParentIssuePostFunction.java

https://bitbucket.org/atlassian_tutorial/tutorial-jira-add-workflow-extensions
Java | 120 lines | 97 code | 12 blank | 11 comment | 11 complexity | bc4f3b80b69c876d7df5b31b5183ed52 MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.example.plugins.tutorial.jira.workflow;
  2. import com.atlassian.jira.bc.issue.IssueService;
  3. import com.atlassian.jira.component.ComponentAccessor;
  4. import com.atlassian.jira.config.ConstantsManager;
  5. import com.atlassian.jira.config.SubTaskManager;
  6. import com.atlassian.jira.issue.Issue;
  7. import com.atlassian.jira.issue.IssueFieldConstants;
  8. import com.atlassian.jira.issue.IssueInputParameters;
  9. import com.atlassian.jira.issue.MutableIssue;
  10. import com.atlassian.jira.issue.IssueManager;
  11. import com.atlassian.jira.issue.status.Status;
  12. import com.atlassian.jira.security.JiraAuthenticationContext;
  13. import com.atlassian.jira.user.ApplicationUser;
  14. import com.atlassian.jira.workflow.JiraWorkflow;
  15. import com.atlassian.jira.workflow.WorkflowManager;
  16. import com.atlassian.jira.workflow.function.issue.AbstractJiraFunctionProvider;
  17. import com.opensymphony.module.propertyset.PropertySet;
  18. import com.opensymphony.workflow.WorkflowException;
  19. import com.opensymphony.workflow.loader.ActionDescriptor;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22. import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
  23. import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;
  24. import java.util.Collection;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.Map;
  28. /**
  29. * This is the post-function class that gets executed at the end of the transition.
  30. * Any parameters that were saved in your factory class will be available in the transientVars Map.
  31. */
  32. @Scanned
  33. public class CloseParentIssuePostFunction extends AbstractJiraFunctionProvider {
  34. private static final Logger log = LoggerFactory.getLogger(CloseParentIssuePostFunction.class);
  35. @JiraImport
  36. private final WorkflowManager workflowManager;
  37. @JiraImport
  38. private final SubTaskManager subTaskManager;
  39. @JiraImport
  40. private final JiraAuthenticationContext authenticationContext;
  41. @JiraImport
  42. private IssueManager issueManager;
  43. private final Status closedStatus;
  44. public CloseParentIssuePostFunction(ConstantsManager constantsManager,
  45. WorkflowManager workflowManager,
  46. SubTaskManager subTaskManager,
  47. JiraAuthenticationContext authenticationContext,
  48. IssueManager issueManager) {
  49. this.workflowManager = workflowManager;
  50. this.subTaskManager = subTaskManager;
  51. this.authenticationContext = authenticationContext;
  52. this.issueManager = issueManager;
  53. closedStatus = constantsManager
  54. .getStatus(Integer.toString(IssueFieldConstants.CLOSED_STATUS_ID));
  55. }
  56. public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException {
  57. // Retrieve the sub-task
  58. MutableIssue subTask = getIssue(transientVars);
  59. // Retrieve the parent issue
  60. MutableIssue parentIssue = issueManager.getIssueObject(subTask.getParentId());
  61. // Ensure that the parent issue is not already closed
  62. if (parentIssue == null || IssueFieldConstants.CLOSED_STATUS_ID == Integer
  63. .parseInt(parentIssue.getStatusId())) {
  64. return;
  65. }
  66. // Check that ALL OTHER sub-tasks are closed
  67. Collection<Issue> subTasks = subTaskManager.getSubTaskObjects(parentIssue);
  68. for (Iterator<Issue> iterator = subTasks.iterator(); iterator.hasNext(); ) {
  69. Issue associatedSubTask = iterator.next();
  70. if (!subTask.getKey().equals(associatedSubTask.getKey()) &&
  71. IssueFieldConstants.CLOSED_STATUS_ID != Integer.parseInt(associatedSubTask.getStatus().getId())) {
  72. return;
  73. }
  74. }
  75. // All sub-tasks are now closed - close the parent issue
  76. try {
  77. closeIssue(parentIssue);
  78. } catch (WorkflowException e) {
  79. log.error(
  80. "Error occurred while closing the issue: " + parentIssue.getKey() + ": " + e, e);
  81. e.printStackTrace();
  82. }
  83. }
  84. private void closeIssue(Issue issue) throws WorkflowException {
  85. Status currentStatus = issue.getStatus();
  86. JiraWorkflow workflow = workflowManager.getWorkflow(issue);
  87. List<ActionDescriptor> actions = workflow.getLinkedStep(currentStatus).getActions();
  88. // look for the closed transition
  89. ActionDescriptor closeAction = null;
  90. for (ActionDescriptor descriptor : actions) {
  91. if (descriptor.getUnconditionalResult().getStatus().equals(closedStatus.getName())) {
  92. closeAction = descriptor;
  93. break;
  94. }
  95. }
  96. if (closeAction != null) {
  97. ApplicationUser currentUser = authenticationContext.getLoggedInUser();
  98. IssueService issueService = ComponentAccessor.getIssueService();
  99. IssueInputParameters parameters = issueService.newIssueInputParameters();
  100. parameters.setRetainExistingValuesWhenParameterNotProvided(true);
  101. IssueService.TransitionValidationResult validationResult =
  102. issueService.validateTransition(currentUser, issue.getId(),
  103. closeAction.getId(), parameters);
  104. IssueService.IssueResult result = issueService.transition(currentUser, validationResult);
  105. // check result for errors
  106. }
  107. }
  108. }