Good day to everyone.
I have searched the forum and did not found something similar but if there is I do appologise in advance.
I am new to Jira development, I am trying to create a custom PostFunction that takes input from the velocity input template (the number of subtasks to be created) and creates the subtasks for the issue in question accordingly. The problem is with the values from the velocity input template, I can not get that to work right.
Here is my java code so far code so far:
public class CreateSubTaskForIssuePostFunctionFactory extends AbstractWorkflowPluginFactory implements WorkflowPluginFunctionFactory{
private static final Logger log = LoggerFactory.getLogger(CreateSubTaskForIssuePostFunctionFactory.class);
private final static String COUNT="count";
private final static String DEFAULT_COUNT="1";
@Override
protected void getVelocityParamsForEdit(Map<String, Object> velocityParams, AbstractDescriptor abstractDescriptor) {
getVelocityParamsForInput(velocityParams);
getVelocityParamsForView(velocityParams,abstractDescriptor);
}
@Override
protected void getVelocityParamsForInput(Map<String, Object> velocityParams) {
velocityParams.put(COUNT, DEFAULT_COUNT);
}
@Override
protected void getVelocityParamsForView(Map<String, Object> velocityParams, AbstractDescriptor abstractDescriptor) {
velocityParams.put(COUNT, getCount(abstractDescriptor));
}
private String getCount(AbstractDescriptor abstractDescriptor) {
if(!(abstractDescriptor instanceof FunctionDescriptor)) {
throw new IllegalArgumentException("Descriotor must be a FunctionDescriptor!");
}
FunctionDescriptor functionDescriptor = (FunctionDescriptor) abstractDescriptor;
String numberOfSubtasks = (String) functionDescriptor.getArgs().get(COUNT);
if (numberOfSubtasks == null)log.error("Something is wrong! Count is: "+numberOfSubtasks);
return (numberOfSubtasks != null && numberOfSubtasks.trim().length()>0)?numberOfSubtasks:DEFAULT_COUNT;
}
public Map<String, ?> getDescriptorParams(Map<String, Object> formParams) {
if(formParams != null && formParams.containsKey(COUNT)) {
return MapBuilder.build(COUNT, extractSingleParam(formParams, COUNT));
}
return MapBuilder.emptyMap();
}
}
The .vm input template:
<tr>
<td class="fieldLabelArea">
Number of subtasks:
</td>
<td nowrap>
<input name="count" id="count" value="$count"/>
</td>
</tr>
The post function class itself looks like this:
@Scanned
public class CreateSubTaskForIssuePostFunction extends AbstractJiraFunctionProvider
{
private static final Logger log = LoggerFactory.getLogger(CreateSubTaskForIssuePostFunction.class);
private static final String COUNT ="count";
@ComponentImport
private final JiraAuthenticationContext jiraContext;
@ComponentImport
private final SubTaskManager subtaskManager;
@ComponentImport
private final IssueService issueService;
public CreateSubTaskForIssuePostFunction(JiraAuthenticationContext jiraContext, SubTaskManager subtaskManager,
IssueService issueService) {
this.jiraContext = jiraContext;
this.subtaskManager = subtaskManager;
this.issueService = issueService;
}
public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException
{
log.info("Inside PF CreateSubTaskForIssuePostFunction");
MutableIssue parentIssue = getIssue(transientVars);
Integer count = null;
try {
count = Integer.parseInt((String)args.get(COUNT));
}catch(NumberFormatException e) {
log.error(e.getMessage());
throw new WorkflowException("This should be a numeric value! We have: "+(String)args.get(COUNT));
}
if(count != null) {
for(int i=0;i<count;i++) {
createSubtask(parentIssue);
}
}
}
private void createSubtask(MutableIssue parentIssue) {
ConstantsManager constantsManager = ComponentAccessor.getConstantsManager();
String issueTypeId = getIssueTypeId(constantsManager, "Sub-task");
//PF stops for a closed issue or if it is a subtask or subtask issue type is non-existent
if(IssueFieldConstants.CLOSED_STATUS_ID == Integer.parseInt(parentIssue.getStatus().getId()) || parentIssue.isSubTask()
|| issueTypeId == null) {
log.error("Can not create subtask issue!");
return;
}
ComponentAccessor.getComponent(IssueIndexingService.class);
ApplicationUser user = jiraContext.getLoggedInUser();
IssueInputParameters subtaskInputParameters = issueService.newIssueInputParameters();
subtaskInputParameters.setReporterId(parentIssue.getReporterId());
subtaskInputParameters.setSummary("SubTask issue created for parent issue "+parentIssue.getSummary());
subtaskInputParameters.setIssueTypeId(issueTypeId);
subtaskInputParameters.setProjectId(parentIssue.getProjectId());
CreateValidationResult validationResult = issueService.validateSubTaskCreate(user, parentIssue.getId(),subtaskInputParameters);
if(!validationResult.isValid()) {
addErrorsToLog(validationResult.getErrorCollection().getErrorMessages());
return;
}
IssueResult issueResult = issueService.create(user,validationResult);
if(!issueResult.isValid()) {
addErrorsToLog(issueResult.getErrorCollection().getErrorMessages());
return;
}
MutableIssue subTask = issueResult.getIssue();
try {
//indexing.reIndex(subTask);
subtaskManager.createSubTaskIssueLink(parentIssue, subTask, user);
} catch (CreateException e) {
log.error(e.getMessage());
e.printStackTrace();
}
log.info("SubTask "+subTask+" finalized for current issue: "+parentIssue);
}
private void addErrorsToLog(Collection<String> errors) {
errors.forEach(m -> log.error("Error creating parameters for subtask: "+m));
}
private String getIssueTypeId(ConstantsManager constantsManager, String issueName) {
Collection<IssueType> issueTypes = constantsManager.getAllIssueTypeObjects();
for(IssueType it: issueTypes) {
if(it.getName().equals(issueName)) {
return it.getId();
}
}
return null;
}
}
Any sugestion is a life saver!