I am trying to create a custom JQL using Scriptrunner. I need to find all issues that have at least one attachment in an attachment category in the Smart Attachments add-on. I have the code working as just a groovy script. However, I want to turn it into a custom JQL function so the users don't need an admin to execute it. I place the working code into the custom JQL template that the ScriptRunner documentation states. The Issue Navigator is throwing the following error.
Scripted function "customJQL" compilation failure. Contact administrator and check logs. Message: Cannot cast object '[]' with class 'java.util.ArrayList' to class 'com.atlassian.query.Query' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.atlassian.query.Query()
Here is the code:
/*********************
Description: This script is a template to create custom JQL functions using scriptRunner
Author: Kevin Bouman
Created: 3/4/2020
Updated:
**********************/
package com.onresolve.jira.groovy.jql
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.jql.query.LuceneQueryBuilder
import com.atlassian.jira.jql.query.QueryCreationContext
import com.atlassian.jira.jql.validator.NumberOfArgumentsValidator
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.util.MessageSet
import com.atlassian.query.clause.TerminalClause
import com.atlassian.query.operand.FunctionOperand
import org.apache.lucene.search.Query
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.user.util.UserManager
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.stiltsoft.jira.attachcategory.facade.SmartAttachmentsFacade
import com.stiltsoft.jira.attachcategory.facade.entity.issue.AttachmentCategories
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.MutableIssue
import org.apache.lucene.search.BooleanClause
import org.apache.lucene.search.BooleanQuery
import org.apache.lucene.index.Term
import org.apache.lucene.search.Query
import org.apache.lucene.search.TermQuery
import java.text.MessageFormat
class customJQLFunction extends AbstractScriptedJqlFunction implements JqlQueryFunction {
/**
* Modify this query as appropriate.
*
* See {@link java.text.MessageFormat} for details
*/
public static final String TEMPLATE_QUERY = {0}
def queryParser = ComponentAccessor.getComponent(JqlQueryParser)
def luceneQueryBuilder = ComponentAccessor.getComponent(LuceneQueryBuilder)
def searchService = ComponentAccessor.getComponent(SearchService)
@Override
String getDescription() {
"Search for issues with no attachments in specific Smart Attachment category."
}
@Override
MessageSet validate(ApplicationUser user, FunctionOperand operand, TerminalClause terminalClause) {
def messageSet = new NumberOfArgumentsValidator(2, 2, getI18n()).validate(operand)
if (messageSet.hasAnyErrors()) {
return messageSet
}
def query = mergeQuery(operand)
messageSet = searchService.validateQuery(user, query)
messageSet
}
@Override
List<Map> getArguments() {
[
[
description: "Subquery to limit results, Example: (project = abc)",
optional : false,
],
[
description: "Smart Attachment category name.",
optional : false,
]
]
}
@Override
String getFunctionName() {
"customJQL"
}
@Override
Query getQuery(QueryCreationContext queryCreationContext, FunctionOperand operand, TerminalClause terminalClause) {
def query = mergeQuery(operand)
luceneQueryBuilder.createLuceneQuery(queryCreationContext, query)
}
private com.atlassian.query.Query mergeQuery(FunctionOperand operand) {
// Initializing the app components
@WithPlugin("com.stiltsoft.jira.smart-attachments")
SmartAttachmentsFacade facade = ScriptRunnerImpl.getPluginComponent(SmartAttachmentsFacade)
UserManager userManager = ComponentAccessor.getUserManager()
IssueManager issueManager = ComponentAccessor.getIssueManager()
def searchService = ComponentAccessor.getComponent(SearchService.class);
//def firstQuery = MessageFormat.format(TEMPLATE_QUERY, operand.args.first());
//def query = queryParser.parseQuery(firstQuery);
def returnArray = []
def myCategory = {1}
//Get the current user
JiraAuthenticationContext authContext = ComponentAccessor.getJiraAuthenticationContext();
def user = authContext.getLoggedInUser();
//Run the JQL
SearchService.ParseResult parseResult = searchService.parseQuery(user, TEMPLATE_QUERY);
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter());
//create the list that contains all the issue keys
def issues = searchResult.results.collect {issueManager.getIssueObject(it.id)};
//Loop through all issues and see if there are attachments in the requested category
for (MutableIssue i in issues){
AttachmentCategories attachmentCategories = facade.getAttachmentCategories(i)
//Specify the category in question to search for attachments
def selectedCategory = attachmentCategories.categories.find { category -> category.name.equalsIgnoreCase(myCategory) }
def attachments = selectedCategory.getAttachments(false)
if(attachments.size() > 0){
returnArray = returnArray + i
}
}
return returnArray
/***********************/
}
// private com.atlassian.query.Query mergeQuery(FunctionOperand operand) {
// def queryStr = MessageFormat.format(TEMPLATE_QUERY, operand.args.first())
// queryParser.parseQuery(queryStr)
// }
}
What am I missing?
I am new to creating custom JQL functions so please forgive my ignorance.