Validating Attachments/Links In Transitions
Writing a validator that needs to check for newly-added linked issues or attachments in the current transition is a special case. Unfortunately due to deficiencies in the Jira API you need to jump through some additional hoops. This code only applies where you have the Attachments or Issue Links field on the screen. If you can avoid this, you should try to do so. That is, require that the attachments or links are created through the standard operations before the transition is done. It will make your code simpler.
Typically you will get attachments and linked issues from AttachmentManager or IssueLinkManager… however these will only give you newly-added attachments/links once the current transaction has been committed. In a validator it has not as yet.
This in itself makes sense, the API deficiency is that there’s no way to get these things from the issue
that is available to validators.
Validating Attachments Added this Transition
This code will only work in Jira 6.4 and above.
The following example details how to find properties of attachments added this transition, for example the file name. The Attachments field must be on the transition screen to get attachments like this.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFieldConstants
import com.atlassian.jira.issue.attachment.TemporaryWebAttachment
import com.atlassian.jira.issue.attachment.TemporaryWebAttachmentManager
import webwork.action.ActionContext
def temporaryAttachmentUtil = ComponentAccessor.getComponent(TemporaryWebAttachmentManager)
def formToken = ActionContext.getRequest()?.getParameter(IssueFieldConstants.FORM_TOKEN)
if (formToken) {
def tempWebAttachments = temporaryAttachmentUtil.getTemporaryWebAttachmentsByFormToken(formToken)
tempWebAttachments.each { TemporaryWebAttachment it ->
log.debug "Uploaded attachment name: ${it.filename}"
}
}
Via the REST API, it’s not currently possible to create an issue with attachments, or add attachments on a transition. The form token above is not available in REST contexts, but because of this limitation it doesn’t matter.
Reading Attachments Added this Transition
If you need to read the contents of newly-added attachments, for in-depth validation, you can get the data like this:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFieldConstants
import com.atlassian.jira.issue.attachment.FileSystemAttachmentDirectoryAccessor
def attachmentDirectoryAccessor = ComponentAccessor.getComponent(FileSystemAttachmentDirectoryAccessor)
def temporaryAttachmentDirectory = attachmentDirectoryAccessor.getTemporaryAttachmentDirectory()
def newAttachmentNames = issue.modifiedFields.get(IssueFieldConstants.ATTACHMENT)?.newValue
newAttachmentNames.each { String filename ->
log.debug "File text:" + new File(temporaryAttachmentDirectory, filename).text
}
Validating Links Added this Transition
The following example shows how to read links that have been added on the screen during the transition, and in this case, stops the action unless at least one blocks link has been added.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFieldConstants
import com.atlassian.jira.issue.fields.IssueLinksSystemField
import com.opensymphony.workflow.InvalidInputException
import webwork.action.ActionContext
def fieldManager = ComponentAccessor.getFieldManager()
def linksSystemField = fieldManager.getField("issuelinks") as IssueLinksSystemField
def request = ActionContext.getRequest()
if (request) {
def params = request.getParameterMap()
def issueLinkingValue = linksSystemField.getRelevantParams(params) as IssueLinksSystemField.IssueLinkingValue
if (!(issueLinkingValue.linkDescription == "blocks" && issueLinkingValue.linkedIssues.size() > 0)) {
throw new InvalidInputException(IssueFieldConstants.ISSUE_LINKS,
"You must link a blocker issue at this transition")
}
}
You should also allow for that the correct link may have been added previous to the transition, using the examples described here.