Recently upgraded from Jira 6.4.11 to Jira 7.0.0 . Debugging custom plugin in amps version 6.3.21 . So far fixed errors regarding Casting ApplicationUser to com.atlassian.crowd.embedded.api.User.
Need help to understand and way to resolve this error:
C:....\jira\jql\StatusUpdateNotificationListFunction.java:[41,7] error: StatusUpdateNotificationListFunction is not abstract and does not override abstract method validate(ApplicationUser,FunctionOperand,TerminalClause) in JqlFunction
Edit : Tried changing parameters of Validate function to validate(ApplicationUser user., ..) but didnt help.
Also tried to import and implement interface com.atlassian.jira.plugin.jql.function.JqlFunction as I found details here
package ca.chi.jira.jql;
import ca.chi.jira.tools.JqlUtilities;
import com.atlassian.jira.JiraDataType;
import com.atlassian.jira.JiraDataTypes;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.changehistory.ChangeHistoryItem;
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager;
import com.atlassian.jira.issue.comments.Comment;
import com.atlassian.jira.issue.comments.CommentManager;
import com.atlassian.jira.jql.operand.QueryLiteral;
import com.atlassian.jira.jql.query.QueryCreationContext;
import com.atlassian.jira.jql.util.JqlDateSupport;
import com.atlassian.jira.plugin.jql.function.AbstractJqlFunction;
import com.atlassian.jira.util.MessageSet;
import com.atlassian.jira.util.NotNull;
import com.atlassian.query.clause.TerminalClause;
import com.atlassian.query.operand.FunctionOperand;
import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.user.ApplicationUsers;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
/**
* A handler for the "statusUpdateNotificationList" JQL function. This function
* will retrieve all issues that were transitioned to a certain state and need
* to consequently trigger a periodical notification.
*
* Parameters: [0] Project Key
* [1] Status
* [2] Periodicity (days)
*/
public class StatusUpdateNotificationListFunction extends AbstractJqlFunction {
private JqlDateSupport jqlDateSupport = null;
public StatusUpdateNotificationListFunction(JqlDateSupport jqlDateSupport) {
this.jqlDateSupport = jqlDateSupport;
}
public List<QueryLiteral> getValues(
@NotNull QueryCreationContext queryCreationContext,
@NotNull FunctionOperand operand,
@NotNull TerminalClause terminalClause) {
final List<QueryLiteral> literals = new LinkedList<QueryLiteral>();
CommentManager commentMgr = ComponentAccessor.getCommentManager();
String prjKey = operand.getArgs().get(0);
String status = operand.getArgs().get(1);
String periodicityStr = operand.getArgs().get(2);
int periodicity = -1;
try {
periodicity = Integer.parseInt(periodicityStr);
}
catch (NumberFormatException nfe) {
//
}
if (StringUtils.isNotEmpty(prjKey) && StringUtils.isNotEmpty(status)
&& (periodicity > 0)) {
String jql = "status = \"" + status + "\" and project = \""
+ prjKey + "\"";
List<Issue> issues = JqlUtilities.executeJqlQuery(jql);
if (issues != null) {
for (Issue issue: issues) {
if (needsNotification(issue, status, periodicity)) {
literals.add(new QueryLiteral(operand,
issue.getId()));
}
}
}
}
return literals;
}
private boolean needsNotification(Issue issue, String status, int periodicity) {
boolean needsNotification = false;
Date now = new Date();
if ((issue != null) && StringUtils.isNotEmpty(status) && (periodicity > 0)) {
ChangeHistoryManager mgr = ComponentAccessor.getChangeHistoryManager();
List<ChangeHistoryItem> items = mgr.getAllChangeItems(issue);
if (items != null) {
boolean statusMatch = false;
Date changeDate = null;
for (ChangeHistoryItem item: items) {
String field = item.getField();
if ((field != null) && field.toLowerCase().equals("status")) {
Map<String, String> valMap = item.getTos();
if (valMap != null) {
for (String key: valMap.keySet()) {
String s = valMap.get(key);
if ((s != null) && s.toLowerCase().equals(status.toLowerCase())) {
statusMatch = true;
break;
}
}
if (statusMatch) {
Date itemChangeDate = new Date(item.getCreated().getTime());
if ((changeDate == null) || itemChangeDate.after(changeDate)) {
changeDate = itemChangeDate;
}
}
}
}
}
if (!statusMatch) {
if (issue.getStatusObject().getName().toLowerCase().equals(status.toLowerCase())) {
changeDate = new Date(issue.getCreated().getTime());
}
}
if (changeDate != null) {
int diffInDays = (int)Math.round(((now.getTime() - changeDate.getTime())
/ (1000 * 60 * 60 * 24) ));
if ((diffInDays % periodicity) == 0) {
needsNotification = true;
}
}
}
}
return needsNotification;
}
/**
* This method validates the passed in args. In this case the function
* accepts three args.
*/
public MessageSet validate(User searcher, @NotNull FunctionOperand operand,
@NotNull TerminalClause terminalClause) {
return validateNumberOfArgs(operand, 3);
}
/**
* This method returns the min number of args the function takes.
* In this case, 3 - please see the comment at the top of this file
*/
public int getMinimumNumberOfExpectedArguments() {
return 3;
}
/**
* This method needs to return the type of objects the function deals with.
* In this case - Issue
*/
public JiraDataType getDataType() {
return JiraDataTypes.ISSUE;
}
}