Cannot retrieve a set of custom field options

Georgiy Senenkov May 2, 2012

Hello,

I am using JIRA4.3.4 and I need to set ”Team” custom field to some particular value which is taken from component description.

For this purpose I created small groovy script and call it in workflow post functions. The script looks as following

import com.atlassian.jira.issue.Issue

import com.atlassian.jira.issue.fields.CustomField

import com.atlassian.jira.issue.CustomFieldManager

import com.atlassian.jira.ComponentManager

import org.apache.log4j.Category

import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

import com.atlassian.jira.issue.util.IssueChangeHolder

import com.atlassian.jira.issue.ModifiedValue

import com.atlassian.jira.issue.context.IssueContext

import com.atlassian.jira.issue.context.IssueContextImpl

log = Category.getInstance("com.onresolve.jira.groovy.PRID")

log.setLevel(org.apache.log4j.Level.DEBUG)

componentManager = ComponentManager.getInstance()

customFieldManager = componentManager.getCustomFieldManager()

Issue issue = issue

IssueChangeHolder changeHolder = new DefaultIssueChangeHolder()

// get "Team" custom field object

cfTeam = customFieldManager.getCustomFieldObjectByName("Team")

// get Components description. Assumption is that Team information is provided in components description

// and followed after ":" in description field

componentsDescription = issue.getComponents().get(0).getString("description")

if ( !issue.getCustomFieldValue(cfTeam) ) {

log.debug "Team not set for "+issue.getKey()+" setting it to: "+issue.getId()

//cfTeam.updateValue(null, issue, new ModifiedValue("", teamField), changeHolder)

// update team field from component description by 1st word after ":" in component description

cfTeam.updateValue(null, issue, new ModifiedValue("", componentsDescription.split(":")[1]), changeHolder)

log.debug "Team now set to: " +issue.getCustomFieldValue(cfTeam)

} else {

log.debug "Team is already set for "+issue.getKey()+": "+issue.getCustomFieldValue(cfTeam)

}

and it works pretty well, but I need to check whether Team name taken from description matches to predefined “Team” custom field option.

I try to retrieve a set of custom field options by following code

IssueContext issueContext = new IssueContextImpl(issue.getProject(), issue.getIssueType())

FieldConfig fieldConfig = cfTeam.getRelevantConfig(issueContext)

Options cfTeamOptions = cfTeam.getOptions(null, fieldConfig, null)

but I’ve got following errors

Script61.groovy: 45: unable to resolve class FieldConfig

@ line 45, column 13.

FieldConfig fieldConfig = cfTeam.getRelevantConfig(issueContext)

^

Script61.groovy: 47: unable to resolve class Options

@ line 47, column 9.

Options cfTeamOptions = cfTeam.getOptions(null, fieldConfig, null)

I thought errors probably mean that that some packages are missing, and I added following imports

import com.atlassian.jira.issue.fields.config

import com.atlassian.jira.issue.customfields.option

but it leads to additional 2 errors

Script62.groovy: 22: unable to resolve class com.atlassian.jira.issue.fields.config

@ line 22, column 1.

import com.atlassian.jira.issue.fields.config

^

Script62.groovy: 23: unable to resolve class com.atlassian.jira.issue.customfields.option

@ line 23, column 1.

import com.atlassian.jira.issue.customfields.option

Could you please point what might be wrong in my script?

Thank you in advance.

Best regards, Georgiy

3 answers

1 accepted

2 votes
Answer accepted
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 2, 2012

Here's a full example for setting a select list value on an issue. In this case the field is SelectListA, and the value is BBB (which must exist as a valid option). No error-checking for enhanced readability ;-)

If you put this script on a post-function, and have it at or near the top of the list, you don't need to bother with that fieldvaluesholder stuff.

So you just need to take my logic and merge it with yours.

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.customfields.manager.OptionsManager

def componentManager = ComponentManager.instance
def optionsManager = ComponentManager.getComponentInstanceOfType(OptionsManager.class)
def customFieldManager = componentManager.getCustomFieldManager()

def cf = customFieldManager.getCustomFieldObjectByName("SelectListA")
def fieldConfig = cf.getRelevantConfig(issue)
def option = optionsManager.getOptions(fieldConfig).find {it.value == "BBB"}
issue.setCustomFieldValue(cf, option)

Georgiy Senenkov May 2, 2012

Thank you for advise. Now code looks much simpler, and easier to read.

The Team custom field remained as “none” in the created issue, even I selected existing value from the list (in my case was “Model”).

I printed value for the team field and correct one was printed, i.e.

System.out.println("Team now set to: " +issue.getCustomFieldValue(cf));

and in log I found

“Team now set to: Model”

Could you please tell what might be wrong here?

I am quite new to JIRA/Groovy scripts. Could you please advise what errors or warnings should be thrown if value does not exist as valid option?

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 2, 2012

> Could you please tell what might be wrong here?

I'm not sure what the error is. Are you saying it doesn't work?

> Could you please advise what errors or warnings should be thrown if value does not exist as valid option?

It depends how you want to deal with it... you could just ignore it, or you could create the option using the OptionsManager. You will need to read the javadoc...

option = optionsManager.createOption(fieldConfig, null, null, "thing")

JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 2, 2012

OK I didn't understand. Is this a post-function script? If so the location is important. For testing make sure the value Model exists as a valid value for the select list.

Georgiy Senenkov May 2, 2012

> Could you please tell what might be wrong here?

>>I'm not sure what the error is. Are you saying it doesn't work?

Yes, I'm saying that it does not work. if I look at created issue then Team is None, but "System.out.println" mentioned in previous comment prints correct value.

I found in documetation that setCustomFieldValue does not write object to the database.Could it be the reason that issue does not contain correct custom field value?

Yes, it is post-function script, and now it's called almost in the end before following steps

— THEN
Re-index an issue to keep indexes in sync with the database.
— THEN
Fire a Issue Created event that can be processed by the listeners.
I tried to move it up, but I've got errors in the log. So, I hope I call it in correct place.
>>OK I didn't understand. Is this a post-function script? If so the location is important. For testing >>make sure the value Model exists as a valid value for the select list.
The "Model" permanently exists in database as list of Team values is not considered to be changed.
>>It depends how you want to deal with it... you could just ignore it, or you could create the option >>using the OptionsManager. You will need to read the javadoc...
I would like that user see the "warning" if custom field value is not existing "Team field" value.
Thank you very much for your help.
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 2, 2012

You can either move the function to the top (post your errors if you like), OR, leave it where it is but use the original method of updating the issue, like:

IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
tgtField.updateValue(null, issue, new ModifiedValue("", "some new value"),changeHolder);

> I would like that user see the "warning" if custom field value is not existing "Team field" value.
Then you need a validator function...
Georgiy Senenkov May 3, 2012

I moved groovy script to the top of post-functions

Script C:\Atlassian\JIRA4.3\groovyrunner\autoSelectTeamByComponent.groovy will be run.
Edit | Move Down | Delete
— THEN

Creates the issue originally.

and have got the following error on the screen

Error creating issue: Error occurred while creating issue. This could be due to a plugin being incompatible with this version of JIRA. For more details please consult the logs, and see: http://confluence.atlassian.com/x/3McB

and here additioanl info from the log

2012-05-04 08:47:45,446 http-80-2 WARN admin 527x1921x1 1xg5q8o 10.161.201.37 /secure/CreateIssueDetails.jspa [groovy.canned.utils.ConditionUtils] Could not get value for field: Epic/Theme
Team now set to: Model
2012-05-04 08:47:45,586 http-80-2 ERROR admin 527x1921x1 1xg5q8o 10.161.201.37 /secure/CreateIssueDetails.jspa [atlassian.jira.workflow.SimpleWorkflowManager] Error occurred while creating issue. This could be due to a plugin being incompatible with this version of JIRA. For more details please consult the logs, and see: http://confluence.atlassian.com/x/3McB
java.lang.ClassCastException:
class com.atlassian.jira.issue.customfields.impl.SelectCFType passed an invalid value of type: class com.atlassian.jira.issue.customfields.option.LazyLoadedOption
at com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType.assertObjectImplementsType(AbstractCustomFieldType.java:111)
at com.atlassian.jira.issue.customfields.impl.SelectCFType.getStringFromSingularObject(SelectCFType.java:83)
at com.atlassian.jira.issue.customfields.impl.StringCFType.getDbValueFromObject(StringCFType.java:16)

Georgiy Senenkov May 3, 2012
> I would like that user see the "warning" if custom field value is not existing "Team field" value.
>>Then you need a validator function...
I guess you meant that script in validator will read value from description and compare it with valid ones, and raise some warning if they do not match.
Could yopu please paste example how to raise warning in groove if you have any of those?
Thank you!
Georgiy Senenkov May 3, 2012

As the solution I made 2 scripts. One which checks whether component description contains valid Team I placed into validator. The script throws exception if "option" in the code above is None. The exception is

import com.opensymphony.workflow.InvalidInputException

if (!option){
	invalidInputException = new InvalidInputException("Issue cannot be created! Contact administrator!")
}

and second script (the original one which is published in the top of this discussion) I placed into post functions.
Now it works as it should!
Thank you very much!!!

0 votes
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
May 2, 2012

You need to import foo.bar.*, if foo.bar is a package.

What type of custom field is Team?

0 votes
Georgiy Senenkov May 2, 2012

Team custom field is the "Select List" type.

Sorry, I didn't understand what I need to import. Coudlyou please clarify?

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events