How to get at the contents of a custom label-type field written as a custom validation script

Tyrrell_Stephen February 16, 2015

Hi,

I have been trying to write a custom validation script to be executed on workflow transition. The purpose is to validate the contents of a custom field, of the label variety.

The first approach I took was in using the CustomFieldManager/LabelManager but realised that using that  method I could only access the label contents prior to the transition being triggered. Therefore, any changes to the custom labels field made during the transition were missed.

My next approach has been to try and use the groovy script cfValues object to glean the contents changed during the transition. It was a bit of an assumption that cfValues could provide the access needed but it seemed the right direction. I proceeded to use an assertion to test it out but the assertion was not triggered having instead resulted in an error in the atlassian-jira.log (code and output snippets are below).

import java.util.Map

// intended to trigger in order to learn from assert results
assert cfValues['CustomLabelsField'].getValue() == "hello"

// output

[scriptrunner.jira.workflow.ScriptWorkflowFunction] Script function failed on issue: DMI-1, actionId: 4, file: C:\Program Files\Atlassian\Application Data\JIRA\scripts\custom_label.groovy
groovy.lang.MissingPropertyException: No such property: cfValues for class: custom_label
    at custom_label.run(custom_label.groovy:18)

I guess my questions are:

1) what approach should I be taking to access label-type custom fields mid-transition with a custom validator script (i.e. filesystem-based)?

2) in what contexts is cfValues available and not available?

Your advice would be most welcome!

 

JIRA: 6.3.8 Groovy Runner: 3.0.9 Debugging: IntelliJ IDEA 14.0.1 Java: 1.7.0_75 Groovy: 2.3.7

1 answer

1 accepted

1 vote
Answer accepted
Alejo Villarrubia [Adaptavist]
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.
February 18, 2015

Hi Stephen,

You should be able to use the built-in validator of type Simple Scripted Validator with the following code for your condition:

cfValues['my_custom_field'].any() { it.label == "some_value" }

I think cfValues is not available in the bindings of a custom script validator, but it is definitely available in the conditions of the Simple Scripted Validators.

Tyrrell_Stephen February 18, 2015

Hi Alejo, Thanks for your answer. The real problem I am trying to solve involves a number of compound conditions that make the simple scripted validator approach unsuitable. I have previously looked at using multiple simple scripted validators for the task and again today. Unfortunately I am unable to share my detailed requirements as it is not permitted by my company. I am really after finding the solution for use with custom script validators. As you say, the cfValues object is very likely to be unavailable for use with the custom script validator. Thanks

Alejo Villarrubia [Adaptavist]
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.
February 18, 2015

If your requirements are as complex to have the need to create a custom script validator, there are other ways of retrieving the custom field value for an specific issue. You could for instance do something like this to retrieve the current value of a custom field: import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.Issue def Issue issue = issue def customFieldManager = ComponentAccessor.getCustomFieldManager() def myCf = customFieldManager.getCustomFieldObjectByName("my_custom_field") def cfValue = issue.getCustomFieldValue(myCf)

Tyrrell_Stephen February 19, 2015

Hi Alejo, Thanks to your help I have a result! I started back with your code snippet and built a generic scenario that works. I proceeded to build another that demonstrates what I previously implemented (as in question) that fails. The difference comes down to how the collection of actual Labels is obtained. I had erroneously concluded that the two approaches shown would yeild identical results. /**********************************************************/ // working code import com.opensymphony.workflow.InvalidInputException import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.fields.CustomField import com.atlassian.jira.issue.label.Label Issue myIssue = issue customFieldManager = ComponentAccessor.getCustomFieldManager() CustomField myCfField = customFieldManager.getCustomFieldObjectByName("my_custom_label_field") Set<Label> myCfValue = (Set<Label>)myIssue.getCustomFieldValue(myCfField) if (myCfValue != null && myCfValue.size() > 0) { invalidInputException = new InvalidInputException("Error: There are " + myCfValue.size() + " labels present in my_custom_label_field.") } /**********************************************************/ // failing code import com.atlassian.jira.issue.label.LabelManager import com.opensymphony.workflow.InvalidInputException import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.fields.CustomField import com.atlassian.jira.issue.label.Label Issue myIssue = issue customFieldManager = ComponentAccessor.getCustomFieldManager() CustomField myCfField = customFieldManager.getCustomFieldObjectByName("my_custom_label_field") LabelManager labelManager = ComponentAccessor.getComponent(LabelManager.class) Set<Label> myCfValue = (Set<Label>)labelManager.getLabels(myIssue.getId(), myCfField.getIdAsLong()) if (myCfValue != null && myCfValue.size() > 0) { invalidInputException = new InvalidInputException("Error: There are " + myCfValue.size() + " labels present in my_custom_label_field.") } The manner in which the failing code fails is that if one or more labels are present before transition and removed during the transition, the script still detects labels present. Conversely, if the are no labels present beforehand and one or more are added during transition the script determines there are no labels present. This is consistent with the state of the issue at the time the transition is initiated. /**********************************************************/ Many thanks Alejo! Stephen

Pieterjan Vanpee January 20, 2016

Hello Alejo,

 

In one of my validators I used following code as you suggested:

cfValues['FAM'].any() { it.label != "?" }

 

This worked with Scriptrunner for JIRA until some days ago. We are now using version 4.1.3.7 of Scriptrunner for JIRA and now this script is giving me the below error:

Static type checking errors found

 

Do you now why suddenly this code is not working anymore? I have the impression that new version of Scriptrunner changed something...

Suggest an answer

Log in or Sign up to answer