/src/main/resources/com/onresolve/jira/groovy/canned/workflow/postfunctions/AbstractCloneIssue.groovy
Groovy | 206 lines | 163 code | 30 blank | 13 comment | 27 complexity | c7a9617a6951703ef232ee193328c5be MD5 | raw file
- package com.onresolve.jira.groovy.canned.workflow.postfunctions
-
- import com.atlassian.crowd.embedded.api.User
- import com.atlassian.jira.ComponentManager
- import com.atlassian.jira.bc.project.component.ProjectComponent
- import com.atlassian.jira.bc.project.component.ProjectComponentManager
- import com.atlassian.jira.issue.fields.CustomField
- import com.atlassian.jira.project.version.Version
- import com.atlassian.jira.user.util.UserUtil
- import com.atlassian.jira.util.ImportUtils
- import com.onresolve.jira.groovy.canned.utils.ConditionUtils
- import com.opensymphony.workflow.WorkflowContext
- import org.apache.log4j.Category
- import org.ofbiz.core.entity.GenericValue
- import com.atlassian.jira.issue.*
- import com.atlassian.jira.ManagerFactory
- import com.atlassian.jira.issue.label.LabelManager
-
- abstract class AbstractCloneIssue {
-
- public static final String FIELD_TARGET_PROJECT = "FIELD_TARGET_PROJECT"
- public static final String FIELD_TARGET_ISSUE_TYPE = "FIELD_TARGET_ISSUE_TYPE"
- public static final String FIELD_LINK_TYPE = 'FIELD_LINK_TYPE'
- public static final String FIELD_ADDITIONAL_SCRIPT = 'FIELD_ADDITIONAL_SCRIPT'
-
- ComponentManager componentManager = ComponentManager.getInstance()
- UserUtil userUtil = ComponentManager.getInstance().getUserUtil()
- ProjectComponentManager projectComponentManager = componentManager.getProjectComponentManager()
- Category log = Category.getInstance(CloneIssue.class)
- def projectManager = componentManager.getProjectManager()
- def versionManager = componentManager.getVersionManager()
- def indexManager = ComponentManager.getInstance().getIndexManager()
- def issueSecuritySchemeManager = ManagerFactory.getIssueSecuritySchemeManager()
- def labelManager = ComponentManager.getComponentInstanceOfType(LabelManager.class)
-
- Map doScript(Map params) {
- log.debug ("CloneIssue.doScript with params: ${params}");
-
- Issue issue = params['issue'] as Issue
- String targetProjKey = params[FIELD_TARGET_PROJECT] as String
- GenericValue targetProject = projectManager.getProjectByKey(targetProjKey)
- String targetIssueType = params[FIELD_TARGET_ISSUE_TYPE] as String
- Map transientVars = params['transientVars'] as Map
-
- IssueManager issueMgr = componentManager.getIssueManager()
-
- User currentUserObj = getUser(params)
-
- IssueFactory issueFactory = ComponentManager.getInstance().getIssueFactory()
- MutableIssue newIssue = issueFactory.getIssue()
-
- // needs to go before copying custom field values, otherwise we can't get the right target custom fields to copy them
- if (targetProject) {
- newIssue.setProject (targetProject)
- }
- if (targetIssueType) {
- newIssue.setIssueTypeId(targetIssueType)
- }
-
-
- copySystemFieldValues(issue, newIssue)
- copyCustomFieldValues(newIssue, issue)
-
- if (params[CreateSubTask.FIELD_SUBTASK_SUMMARY]) {
- newIssue.setSummary(params[CreateSubTask.FIELD_SUBTASK_SUMMARY] as String)
- }
-
- Map<String,Object> newIssueParams = ["issue":newIssue] as Map<String,Object>
-
- ConditionUtils.doAdditional(params[FIELD_ADDITIONAL_SCRIPT] as String, newIssue, [transientVars: transientVars])
-
- // todo: check the user has the Create Issue perm in the target project, or allow the setup to choose a user
- GenericValue newIssueGv = issueMgr.createIssue(currentUserObj, newIssueParams)
- reindexIssue(newIssueGv)
-
- params['newIssue'] = newIssue
-
- copyLabels(issue, newIssue, currentUserObj)
-
- return params
- }
-
- protected void reindexIssue(GenericValue gv) {
- def wasIndexing = ImportUtils.indexIssues
- ImportUtils.indexIssues = true
- indexManager.reIndex(gv);
- ImportUtils.indexIssues = wasIndexing
- }
-
- protected User getUser(Map params) {
- String currentUser
- Map transientVars = params['transientVars'] as Map
- if (transientVars) {
- currentUser = ((WorkflowContext) transientVars.get("context")).getCaller();
- }
- else {
- currentUser = componentManager.getJiraAuthenticationContext().getUser().getName()
- }
- User currentUserObj = userUtil.getUser(currentUser);
- return currentUserObj
- }
-
- protected def copyCustomFieldValues(MutableIssue newissue, Issue issue) {
-
- CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
- List newIssueCfs = customFieldManager.getCustomFieldObjects(newissue)
- newIssueCfs.intersect(customFieldManager.getCustomFieldObjects(issue)).each {CustomField cf ->
- // this format of setting a CF can be used before an issue is created
- // Something here may be causing GRV-40 - order is important
-
- newissue.setCustomFieldValue(cf, cf.getValue(issue))
-
- // If it's done like the following unit tests fail
- // newissue.setCustomFieldValue(cf, issue.getCustomFieldValue(cf))
-
- // this format must be used after it's created
- // if (cf.getValue(issue)) {
- // IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
- // cf.updateValue(null, newissue, new ModifiedValue(cf.getValue(newissue), cf.getValue(issue)), changeHolder)
- // }
- }
- }
-
- protected def copyLabels(Issue issue, MutableIssue newissue, User user) {
- issue.labels.each {label ->
- labelManager.addLabel(user, newissue.id, label.label, false)
- }
- }
-
- protected def copySystemFieldValues(Issue issue, MutableIssue newissue) {
- List systemFields = ["issueTypeId", "projectId", "summary", "assigneeId", "fixVersions", "affectedVersions",
- "reporterId", "environment", "description", "priorityId", "dueDate", "originalEstimate", "components",
- "securityLevel"
- ];
-
- Map allProps = issue.properties
- systemFields.each {String prop ->
- if (allProps.containsKey(prop)) {
- if (prop == "components") {
- def newComps = []
- issue.components.each {GenericValue gv ->
- ProjectComponent newComp = projectComponentManager.findByComponentName(newissue.project.id, gv.name)
- if (newComp)
- newComps.add(newComp.genericValue)
- }
- newissue.components = newComps
- }
- else if (prop == "affectedVersions") {
- def l = []
- issue.affectedVersions.each {Version v ->
- Version version = versionManager.getVersion(newissue.projectId, v.name)
- if (version) {
- l.add(version)
- }
- }
- newissue.affectedVersions = l
- }
- else if (prop == "fixVersions") {
- def l = []
- issue.fixVersions.each {Version v ->
- Version version = versionManager.getVersion(newissue.projectId, v.name)
- if (version) {
- l.add(version)
- }
- }
- newissue.fixVersions = l
- }
- // see https://studio.plugins.atlassian.com/browse/GRV-94
- else if (prop == "securityLevel") {
- def securityLevel = issue.getSecurityLevel()
- if (securityLevel) {
- if (issueSecuritySchemeManager.getSchemes(issue.project) == issueSecuritySchemeManager.getSchemes(newissue.project)) {
- newissue.setSecurityLevel(issue.securityLevel)
- }
- else {
- log.warn("Could not set security level, as the schemes between the two projects are different.")
- }
- }
- }
- // only copy issueTypeId and projectId if not already set through input parameters
- if (["issueTypeId", "projectId"]) {
- if (! newissue.@"$prop") {
- newissue.@"$prop" = issue.@"$prop"
- }
- }
- else {
- newissue.@"$prop" = issue.@"$prop"
- }
- }
- }
- }
-
- LinkedHashMap getOverridesParam() {
- [
- Name:FIELD_ADDITIONAL_SCRIPT,
- Label:'Additional issue actions',
- Description:"Enter any customisations to the target issue, e.g. hard-coding specific field values.",
- Type: "mediumtext",
- Examples: [
- "Set target issue summary": "issue.summary = \\'Cloned issue\\'",
- "Set custom field": "def cf = customFieldManager.getCustomFieldObjects(issue).find {it.name == \\'MyCustomFieldType\\'}\\n" +
- "issue.setCustomFieldValue(cf, \\'my value\\')"
- ]
- ]
- }
- }