/jira-automation-plugin/src/main/java/com/atlassian/plugin/automation/jira/action/SetAssigneeToLastCommentedAction.java
Java | 285 lines | 246 code | 30 blank | 9 comment | 38 complexity | 9b5ea8b74af12123ac504321a09da160 MD5 | raw file
- package com.atlassian.plugin.automation.jira.action;
- import com.atlassian.crowd.embedded.api.Group;
- import com.atlassian.crowd.embedded.api.UserComparator;
- import com.atlassian.jira.bc.issue.IssueService;
- import com.atlassian.jira.issue.Issue;
- import com.atlassian.jira.issue.comments.Comment;
- import com.atlassian.jira.issue.comments.CommentManager;
- import com.atlassian.jira.plugin.userformat.UserFormats;
- import com.atlassian.jira.plugin.userformat.UserFormatter;
- import com.atlassian.jira.security.groups.GroupManager;
- import com.atlassian.jira.user.ApplicationUser;
- import com.atlassian.jira.user.util.UserUtil;
- import com.atlassian.plugin.automation.core.Action;
- import com.atlassian.plugin.automation.core.action.ActionConfiguration;
- import com.atlassian.plugin.automation.core.auditlog.AuditString;
- import com.atlassian.plugin.automation.core.auditlog.DefaultAuditString;
- import com.atlassian.plugin.automation.jira.util.ErrorCollectionUtil;
- import com.atlassian.plugin.automation.util.ErrorCollection;
- import com.atlassian.plugin.automation.util.ParameterUtil;
- import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
- import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
- import com.atlassian.sal.api.message.I18nResolver;
- import com.atlassian.soy.renderer.SoyException;
- import com.atlassian.soy.renderer.SoyTemplateRenderer;
- import com.google.common.base.Function;
- import com.google.common.collect.Lists;
- import com.google.common.collect.Maps;
- import com.google.common.collect.Sets;
- import org.apache.commons.lang.StringUtils;
- import org.apache.log4j.Logger;
- import javax.annotation.Nullable;
- import javax.inject.Inject;
- import java.util.Collections;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import static com.atlassian.plugin.automation.jira.util.Constants.CONFIG_COMPLETE_KEY;
- import static com.atlassian.plugin.automation.util.ParameterUtil.singleValue;
- /**
- * Given a list of issues, this action will set the assignee for these issues to the person who last commented
- * (optionally from a particular group of users).
- * <p/>
- * This may be useful in a support style use case where we want to set the assignee to the supporter who last handled a
- * case when a customer adds a comment.
- *
- */
- @Scanned
- public class SetAssigneeToLastCommentedAction implements Action<Issue>
- {
- private static final Logger log = Logger.getLogger(SetAssigneeToLastCommentedAction.class);
- private static final String PROFILE_LINK_USER_FORMAT_TYPE = "profileLinkWithAvatar";
- private static final String GROUP_MEMBERSHIP_KEY = "groupMembership";
- private static final String EXCLUDED_USERS_KEY = "excludedUsers";
- private static final String UNRESTRICTED = "-1";
- private final CommentManager commentManager;
- private final GroupManager groupManager;
- private final IssueService issueService;
- private final UserUtil userUtil;
- private final SoyTemplateRenderer soyTemplateRenderer;
- private final UserFormats userFormats;
- private String groupMembership;
- private Set<ApplicationUser> excludedUsers;
- @Inject
- public SetAssigneeToLastCommentedAction(
- @ComponentImport final CommentManager commentManager,
- @ComponentImport final GroupManager groupManager,
- @ComponentImport final IssueService issueService,
- @ComponentImport final UserUtil userUtil,
- @ComponentImport final SoyTemplateRenderer soyTemplateRenderer,
- @ComponentImport final UserFormats userFormats)
- {
- this.commentManager = commentManager;
- this.groupManager = groupManager;
- this.issueService = issueService;
- this.userUtil = userUtil;
- this.soyTemplateRenderer = soyTemplateRenderer;
- this.userFormats = userFormats;
- }
- @Override
- public void init(final ActionConfiguration config)
- {
- groupMembership = singleValue(config, GROUP_MEMBERSHIP_KEY);
- excludedUsers = transformExcludedUsers(config);
- }
- @Override
- public void execute(final String actor, final Iterable<Issue> items, final ErrorCollection errorCollection)
- {
- log.debug("Processing issues");
- final Group restrictingGroup = StringUtils.isBlank(groupMembership) || StringUtils.equals(UNRESTRICTED, groupMembership) ? null : groupManager.getGroup(groupMembership);
- for (Issue issue : items)
- {
- log.debug("Processing issue: " + issue.getKey());
- final List<Comment> comments = commentManager.getComments(issue);
- Collections.reverse(comments);
- ApplicationUser lastCommented = null;
- for (Comment comment : comments)
- {
- final ApplicationUser commentAuthor = comment.getAuthorApplicationUser();
- if (excludedUsers != null && excludedUsers.contains(commentAuthor))
- {
- continue;
- }
- if (restrictingGroup != null)
- {
- if (groupManager.isUserInGroup(commentAuthor, restrictingGroup))
- {
- lastCommented = commentAuthor;
- break;
- }
- }
- else
- {
- lastCommented = commentAuthor;
- break;
- }
- }
- //if we found a user that last commented lets assign the issue to this person (if the issue isn't assigned to them already)!
- if (lastCommented != null && (issue.getAssignee() == null || !UserComparator.equal(lastCommented.getDirectoryUser(), issue.getAssignee().getDirectoryUser())))
- {
- log.debug(String.format("Last commented user found for issue '%s'. Setting assignee to user '%s'.", issue.getKey(), lastCommented.getName()));
- final ApplicationUser actorUser = userUtil.getUserByName(actor);
- final IssueService.AssignValidationResult result = issueService.validateAssign(actorUser, issue.getId(), lastCommented.getName());
- if (result.isValid())
- {
- issueService.assign(actorUser, result);
- }
- else
- {
- errorCollection.addErrorCollection(ErrorCollectionUtil.transform(result.getErrorCollection()));
- }
- }
- }
- }
- @Override
- public AuditString getAuditLog()
- {
- String logMessage = "Set Assignee to Last Commented for Issue.";
- if (!StringUtils.equals(groupMembership, UNRESTRICTED))
- {
- logMessage += " Last commented user had to be member of group '" + groupMembership + "'.";
- }
- return new DefaultAuditString(logMessage);
- }
- @Override
- public String getConfigurationTemplate(final ActionConfiguration actionConfiguration, final String actor)
- {
- try
- {
- final Map<String, Object> context = Maps.newHashMap();
- ParameterUtil.transformParams(context, actionConfiguration);
- context.put("groups", groupManager.getAllGroups());
- if (actionConfiguration != null && actionConfiguration.getParameters().containsKey(EXCLUDED_USERS_KEY))
- {
- List<ApplicationUser> excludedUsers = Lists.transform(actionConfiguration.getParameters().get(EXCLUDED_USERS_KEY), new Function<String, ApplicationUser>()
- {
- @Override
- public ApplicationUser apply(@Nullable final String userName)
- {
- return userUtil.getUserByName(userName);
- }
- });
- context.put("excludedUsers", excludedUsers);
- }
- return soyTemplateRenderer.render(CONFIG_COMPLETE_KEY, "Atlassian.Templates.Automation.JIRA.setLastCommented", context);
- }
- catch (SoyException e)
- {
- log.error("Error rendering template", e);
- return "Unable to render configuration form. Consult your server logs or administrator.";
- }
- }
- @Override
- public String getViewTemplate(final ActionConfiguration config, final String actor)
- {
- try
- {
- final Map<String, Object> context = Maps.newHashMap();
- ParameterUtil.transformParams(context, config);
- context.put("excludedUsersProfileLinks", transformExcludedUsersToProfileLinks(config));
- return soyTemplateRenderer.render(CONFIG_COMPLETE_KEY, "Atlassian.Templates.Automation.JIRA.setLastCommentedView", context);
- }
- catch (SoyException e)
- {
- log.error("Error rendering template", e);
- return "Unable to render configuration form. Consult your server logs or administrator.";
- }
- }
- @Override
- public ErrorCollection validateAddConfiguration(final I18nResolver i18n, final Map<String, List<String>> params,
- final String actor)
- {
- final ErrorCollection errors = new ErrorCollection();
- if (params.containsKey(GROUP_MEMBERSHIP_KEY))
- {
- final String groupMembership = singleValue(params, GROUP_MEMBERSHIP_KEY);
- if (!StringUtils.equals(UNRESTRICTED, groupMembership))
- {
- final Group group = groupManager.getGroup(groupMembership);
- if (group == null)
- {
- errors.addError(GROUP_MEMBERSHIP_KEY, i18n.getText("automation.jira.group.membership.invalid"));
- }
- }
- }
- if (params.containsKey(EXCLUDED_USERS_KEY))
- {
- final List<String> users = params.get(EXCLUDED_USERS_KEY);
- String usersNotFound = "";
- for (String userName : users)
- {
- ApplicationUser user = userUtil.getUserByName(userName);
- if (user == null)
- {
- usersNotFound += userName + " ";
- }
- }
- if (!usersNotFound.isEmpty())
- {
- errors.addError(EXCLUDED_USERS_KEY, i18n.getText("automation.jira.users.excluded.invalid") + " " + usersNotFound);
- }
- }
- return errors;
- }
- private Set<String> transformExcludedUsersToProfileLinks(final ActionConfiguration config)
- {
- final Set<String> ret = Sets.newLinkedHashSet();
- if (config != null && config.getParameters().containsKey(EXCLUDED_USERS_KEY))
- {
- final UserFormatter formatter = userFormats.formatter(PROFILE_LINK_USER_FORMAT_TYPE);
- for (String user : config.getParameters().get(EXCLUDED_USERS_KEY))
- {
- if (StringUtils.isNotBlank(user))
- {
- ret.add(formatter.formatUserkey(user, "excluded-user-" + config.getId()));
- }
- }
- }
- return ret;
- }
- private Set<ApplicationUser> transformExcludedUsers(final ActionConfiguration config)
- {
- final Set<ApplicationUser> ret = Sets.newHashSet();
- if (config != null && config.getParameters().containsKey(EXCLUDED_USERS_KEY))
- {
- for (String user : config.getParameters().get(EXCLUDED_USERS_KEY))
- {
- if (StringUtils.isNotBlank(user))
- {
- ret.add(userUtil.getUserByName(user));
- }
- }
- }
- return ret;
- }
- }