[转]Three ways to update an issue in Jira Java Api

本文转自:https://community.atlassian.com/t5/Agile-articles/Three-ways-to-update-an-issue-in-Jira-Java-Api/ba-p/736585

Three ways to update an issue in Jira Java Api

In this article I would like to  examine three ways to update an issue in Jira, using Jira Java API. I tested all the code, provided in this article, in Jira 7.7.0 and Adaptivist ScriptRunner 5.3.7.

I will use Issue.setCustomFieldValue, CustomField.updateValue and IssueService.update methods. I will write example scripts on how to update all out of the box custom fields, using these methods.

The following custom fields were created:

Selection_015.png

 

1. Issue.setCustomFieldValue(CustomField customField, Object value):

A sample code looks like this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import java.sql.Date
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser


def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("BP-7")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// Initialize custom fields ----------------------------------
def singleline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("singleline_field")
def datetimepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datetimepicker_field")
def checkbox_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("checkbox_field")
def number_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("number_field")
def labels_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("labels_field")
def multi_grouppicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multi_grouppicker_field")
def multiline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multiline_field")
def datepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datepicker_field")
def userpicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("userpicker_field")
def radiobuttons_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("radiobuttons_field")
def selectlist_cascading_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_cascading_field")
def select_singlechoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("select_singlechoice_field")
def selectlist_multichoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_multichoice_field")
def url_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("url_field")

// set field values -------------------------------
issue.setCustomFieldValue(singleline_field, "test 1")
issue.setCustomFieldValue(datetimepicker_field, new Date(Calendar.getInstance().getTime().getTime()))
issue.setCustomFieldValue(checkbox_field, getOptions(issue, checkbox_field, ["option 1", "option 2"]))
issue.setCustomFieldValue(number_field, (Double) 1)
issue.setCustomFieldValue(labels_field, [new Label(null, issue.getId(), labels_field.getIdAsLong(), "Label")] as Set)
issue.setCustomFieldValue(multi_grouppicker_field, [ComponentAccessor.getGroupManager().getGroup("jira-software-users")])
issue.setCustomFieldValue(multiline_field, "test 1")
issue.setCustomFieldValue(datepicker_field, new Date(Calendar.getInstance().getTime().getTime()))
issue.setCustomFieldValue(userpicker_field, findUser("admin"))
issue.setCustomFieldValue(radiobuttons_field, getOptions(issue, checkbox_field, ["option 1"]).get(0))
issue.setCustomFieldValue(selectlist_cascading_field, getCascadingOptions(issue, selectlist_cascading_field))
issue.setCustomFieldValue(select_singlechoice_field,  getOptions(issue, select_singlechoice_field, ["option 1"]).get(0))
issue.setCustomFieldValue(selectlist_multichoice_field, getOptions(issue, selectlist_multichoice_field, ["option 1", "option 2"]))
issue.setCustomFieldValue(url_field, "http://google.com")

// apply changes to Jira -----------------------
ComponentAccessor.getIssueManager().updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)

// get option list for radio button, checkbox and select custom fields
def List<Option> getOptions(Issue issue, CustomField customField, List<String> optionList) {
    def config = customField.getRelevantConfig(issue)
    def options = ComponentAccessor.getOptionsManager().getOptions(config)
    def optionsToSelect = options.findAll { it.value in optionList }
}

// get user for the user picker custom field
def ApplicationUser findUser(String userName) {
   def userSearchService = ComponentAccessor.getComponent(UserSearchService.class);
   UserSearchParams userSearchParams = (new UserSearchParams.Builder()).allowEmptyQuery(true).includeActive(true).includeInactive(true).maxResults(100000).build();

   return userSearchService.findUsers(userName, userSearchParams).get(0)

}

// get options for cascading select
def Map<String, Object> getCascadingOptions(Issue issue, CustomField customField) {
    def parentOptionObj = getOptions(issue, customField, ["option 1"]).get(0) as Option
    def childOptionObj = ComponentAccessor.getOptionsManager().findByParentId(parentOptionObj.getOptionId()).get(0)
    Map<String,Object> newValues = new HashMap<>()
    newValues.put(null, parentOptionObj)
    newValues.put("1", childOptionObj)
    return newValues
}

If you want to empty values then you should set the null value for custom fields:

issue.setCustomFieldValue(singleline_field, null) 

2. CustomField.updateValue(FieldLayoutItem fieldLayoutItem, Issue issue, ModifiedValue modifiedValue, IssueChangeHolder issueChangeHolder):

A sample code looks like this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import java.sql.Date
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue


def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("BP-7")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// Initialize custom fields --------------------------
def singleline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("singleline_field")
def datetimepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datetimepicker_field")
def checkbox_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("checkbox_field")
def number_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("number_field")
def labels_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("labels_field")
def multi_grouppicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multi_grouppicker_field")
def multiline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multiline_field")
def datepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datepicker_field")
def userpicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("userpicker_field")
def radiobuttons_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("radiobuttons_field")
def selectlist_cascading_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_cascading_field")
def select_singlechoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("select_singlechoice_field")
def selectlist_multichoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_multichoice_field")
def url_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("url_field")

// set custom fields values (changes will be applied immediately) --------------------
singleline_field.updateValue(null, issue, new ModifiedValue("", (Object) "Test 1"), new DefaultIssueChangeHolder())
datetimepicker_field.updateValue(null, issue, new ModifiedValue("", (Object) new Date(Calendar.getInstance().getTime().getTime())), new DefaultIssueChangeHolder())
checkbox_field.updateValue(null, issue, new ModifiedValue("", (Object) getOptions(issue, checkbox_field, ["option 1", "option 2"])), new DefaultIssueChangeHolder())
number_field.updateValue(null, issue, new ModifiedValue("",  (Object) (Double)  1), new DefaultIssueChangeHolder())
labels_field.updateValue(null, issue, new ModifiedValue("",  (Object) ([new Label(null, issue.getId(), labels_field.getIdAsLong(), "Label")] as Set)), new DefaultIssueChangeHolder())
multi_grouppicker_field.updateValue(null, issue, new ModifiedValue("",  (Object) [ComponentAccessor.getGroupManager().getGroup("jira-software-users")]), new DefaultIssueChangeHolder())
multiline_field.updateValue(null, issue, new ModifiedValue("",  (Object)  "test 1"), new DefaultIssueChangeHolder())
datepicker_field.updateValue(null, issue, new ModifiedValue("",  (Object)  new Date(Calendar.getInstance().getTime().getTime())), new DefaultIssueChangeHolder())
userpicker_field.updateValue(null, issue, new ModifiedValue("",  (Object) findUser("admin")), new DefaultIssueChangeHolder())
radiobuttons_field.updateValue(null, issue, new ModifiedValue("",  (Object) getOptions(issue, checkbox_field, ["option 1"]).get(0)), new DefaultIssueChangeHolder())
selectlist_cascading_field.updateValue(null, issue, new ModifiedValue("",  (Object)  getCascadingOptions(issue, selectlist_cascading_field)), new DefaultIssueChangeHolder())
select_singlechoice_field.updateValue(null, issue, new ModifiedValue("",  (Object) getOptions(issue, select_singlechoice_field, ["option 1"]).get(0)), new DefaultIssueChangeHolder())
selectlist_multichoice_field.updateValue(null, issue, new ModifiedValue("",  (Object) getOptions(issue, selectlist_multichoice_field, ["option 1", "option 2"])), new DefaultIssueChangeHolder())
url_field.updateValue(null, issue, new ModifiedValue("",  (Object) "http://google.com"), new DefaultIssueChangeHolder())

// all functions are the same as in the script above ---------------------

 You can empty custom fields by setting the null value:

singleline_field.updateValue(null, issue, new ModifiedValue("", null), new DefaultIssueChangeHolder())

3.  IssueService.update(ApplicationUser user, IssueService.UpdateValidationResult updateValidationResult):

A sample code looks like this:

import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.UpdateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.label.Label
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.user.ApplicationUser
import java.text.SimpleDateFormat

def issue = ComponentAccessor.getIssueManager().getIssueByCurrentKey("BP-7")
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// initialize custom fields --------------------
def singleline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("singleline_field")
def datetimepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datetimepicker_field")
def checkbox_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("checkbox_field")
def number_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("number_field")
def labels_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("labels_field")
def multi_grouppicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multi_grouppicker_field")
def multiline_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("multiline_field")
def datepicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("datepicker_field")
def userpicker_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("userpicker_field")
def radiobuttons_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("radiobuttons_field")
def selectlist_cascading_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_cascading_field")
def select_singlechoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("select_singlechoice_field")
def selectlist_multichoice_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("selectlist_multichoice_field")
def url_field = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("url_field")

IssueService issueService = ComponentAccessor.getComponent(IssueService.class);
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
// set values for custom fields ------------------
issueInputParameters
      .addCustomFieldValue(singleline_field.getId(), "Test 1")
      .addCustomFieldValue(datetimepicker_field.getId(), new SimpleDateFormat("d/MMM/yy hh:mm a").format(new Date()))
      .addCustomFieldValue(checkbox_field.getId(),  getOptionsAsString(issue, checkbox_field, ["option 1"]))
      .addCustomFieldValue(number_field.getId(), "1")
      .addCustomFieldValue(labels_field.getId(), "Label")
      .addCustomFieldValue(multi_grouppicker_field.getId(), "jira-software-users")
      .addCustomFieldValue(multiline_field.getId(), "Test 2")
      .addCustomFieldValue(datepicker_field.getId(), new SimpleDateFormat("d/MMM/yy").format(new Date()))
      .addCustomFieldValue(userpicker_field.getId(), "admin")
      .addCustomFieldValue(radiobuttons_field.getId(), getOptionsAsString(issue, radiobuttons_field, ["option 1"]))
      .addCustomFieldValue(selectlist_cascading_field.getId(), getCascadingOptions(issue, selectlist_cascading_field).get("parent").toString())
      .addCustomFieldValue(selectlist_cascading_field.getId() + ":1", getCascadingOptions(issue, selectlist_cascading_field).get("1").toString())
      .addCustomFieldValue(select_singlechoice_field.getId(), getOptionsAsString(issue, select_singlechoice_field, ["option 1"]))
      .addCustomFieldValue(selectlist_multichoice_field.getId(), getOptionsAsString(issue, selectlist_multichoice_field, ["option 1"]))
      .addCustomFieldValue(url_field.getId(), "http://google.com")
// we do not provide all the values for an issue, that is why we need to state it
      issueInputParameters.setRetainExistingValuesWhenParameterNotProvided(true,true)
// validate update -------------
UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters);
if (updateValidationResult.isValid())
{
// update the issue ----------
    IssueResult updateResult = issueService.update(user, updateValidationResult);
    if (!updateResult.isValid())
    {
        log.error("error updateResult: " + updateResult.getErrorCollection().toString())
    }
} else {
    log.error("error: updateValidationResult" + updateValidationResult.getErrorCollection().toString())
}

// get options for radio button, checkbox and select custom fields ------
def List<Option> getOptions(Issue issue, CustomField customField, List<String> optionList) {
    def config = customField.getRelevantConfig(issue)
    def options = ComponentAccessor.getOptionsManager().getOptions(config)
    return options.findAll{ it.value in optionList }
}
// represent options as String
def String getOptionsAsString(Issue issue, CustomField customField, List<String> optionList) {
    List<Long> optionIdList = new ArrayList<>()
    getOptions(issue, customField, optionList).each {
       optionIdList.add(((Option) it).getOptionId())
    }
    return optionIdList.join(",")

}

// get user for user picker custom field
def ApplicationUser findUser(String userName) {
   def userSearchService = ComponentAccessor.getComponent(UserSearchService.class);
   UserSearchParams userSearchParams = (new UserSearchParams.Builder()).allowEmptyQuery(true).includeActive(true).includeInactive(true).maxResults(100000).build();

   return userSearchService.findUsers(userName, userSearchParams).get(0)

}
// get cascading options
def Map<String, Object> getCascadingOptions(Issue issue, CustomField customField) {
    def parentOptionObj = getOptions(issue, customField, ["option 1"]).get(0) as Option
    def childOptionObj = ComponentAccessor.getOptionsManager().findByParentId(parentOptionObj.getOptionId()).get(0)
    Map<String,Object> newValues = new HashMap<>()
    newValues.put("parent", parentOptionObj.getOptionId())
    newValues.put("1", childOptionObj.getOptionId())
    return newValues
}

 You can empty field by:

 .addCustomFieldValue(singleline_field.getId(), null)

 What type of values to pass to the three methods?

Selection_016.png  

 Functionality difference:

 Selection_017.png

 You can find all the code here:

Issue.setCustomFieldValue

CustomField.updateValue

IssueService.update

 

posted on 2022-02-10 21:34  freeliver54  阅读(92)  评论(0编辑  收藏  举报

导航