@Override
public ReviewerResult call() throws Exception {
final Set<Account.Id> reviewerIds = new HashSet<Account.Id>();
final ChangeControl control = changeControlFactory.validateFor(changeId);
final ReviewerResult result = new ReviewerResult();
for (final String reviewer : reviewers) {
final Account account = accountResolver.find(reviewer);
if (account == null) {
AccountGroup group = groupCache.get(new AccountGroup.NameKey(reviewer));
if (group == null) {
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.REVIEWER_NOT_FOUND, reviewer));
continue;
}
if (!isLegalReviewerGroup(group.getGroupUUID())) {
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.GROUP_NOT_ALLOWED, reviewer));
continue;
}
final Set<Account> members =
groupMembersFactory.create().listAccounts(group.getGroupUUID(),
control.getProject().getNameKey());
if (members == null || members.size() == 0) {
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.GROUP_EMPTY, reviewer));
continue;
}
// if maxAllowed is set to 0, it is allowed to add any number of
// reviewers
final int maxAllowed =
cfg.getInt("addreviewer", "maxAllowed", DEFAULT_MAX_REVIEWERS);
if (maxAllowed > 0 && members.size() > maxAllowed) {
result.setMemberCount(members.size());
result.setAskForConfirmation(false);
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.GROUP_HAS_TOO_MANY_MEMBERS, reviewer));
continue;
}
// if maxWithoutCheck is set to 0, we never ask for confirmation
final int maxWithoutConfirmation =
cfg.getInt("addreviewer", "maxWithoutConfirmation",
DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK);
if (!confirmed && maxWithoutConfirmation > 0
&& members.size() > maxWithoutConfirmation) {
result.setMemberCount(members.size());
result.setAskForConfirmation(true);
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.GROUP_HAS_TOO_MANY_MEMBERS, reviewer));
continue;
}
for (final Account member : members) {
if (member.isActive()) {
final IdentifiedUser user =
identifiedUserFactory.create(member.getId());
// Does not account for draft status as a user might want to let a
// reviewer see a draft.
if (control.forUser(user).isRefVisible()) {
reviewerIds.add(member.getId());
}
}
}
continue;
}
if (!account.isActive()) {
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.ACCOUNT_INACTIVE,
formatUser(account, reviewer)));
continue;
}
final IdentifiedUser user = identifiedUserFactory.create(account.getId());
// Does not account for draft status as a user might want to let a
// reviewer see a draft.
if (!control.forUser(user).isRefVisible()) {
result.addError(new ReviewerResult.Error(
ReviewerResult.Error.Type.CHANGE_NOT_VISIBLE,
formatUser(account, reviewer)));
continue;
}