use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.
the class LabelsJson method labelsForSubmittedChange.
private Map<String, LabelWithStatus> labelsForSubmittedChange(AccountLoader accountLoader, ChangeData cd, LabelTypes labelTypes, boolean standard, boolean detailed) throws PermissionBackendException {
Set<Account.Id> allUsers = new HashSet<>();
if (detailed) {
// the latest patch set (in the next loop).
for (PatchSetApproval psa : cd.approvals().values()) {
allUsers.add(psa.accountId());
}
}
Set<String> labelNames = new HashSet<>();
SetMultimap<Account.Id, PatchSetApproval> current = MultimapBuilder.hashKeys().hashSetValues().build();
for (PatchSetApproval a : cd.currentApprovals()) {
allUsers.add(a.accountId());
Optional<LabelType> type = labelTypes.byLabel(a.labelId());
if (type.isPresent()) {
labelNames.add(type.get().getName());
// Not worth the effort to distinguish between votable/non-votable for 0
// values on closed changes, since they can't vote anyway.
current.put(a.accountId(), a);
}
}
// Since voting on merged changes is allowed all labels which apply to
// the change must be returned. All applying labels can be retrieved from
// the submit records, which is what initLabels does.
// It's not possible to only compute the labels based on the approvals
// since merged changes may not have approvals for all labels (e.g. if not
// all labels are required for submit or if the change was auto-closed due
// to direct push or if new labels were defined after the change was
// merged).
Map<String, LabelWithStatus> labels;
labels = initLabels(accountLoader, cd, labelTypes, standard);
// it wouldn't be included in the submit records.
for (String name : labelNames) {
if (!labels.containsKey(name)) {
labels.put(name, LabelWithStatus.create(new LabelInfo(), null));
}
}
labels.entrySet().stream().filter(e -> labelTypes.byLabel(e.getKey()).isPresent()).forEach(e -> setLabelValues(labelTypes.byLabel(e.getKey()).get(), e.getValue()));
for (Account.Id accountId : allUsers) {
Map<String, ApprovalInfo> byLabel = Maps.newHashMapWithExpectedSize(labels.size());
Map<String, VotingRangeInfo> pvr = Collections.emptyMap();
if (detailed) {
pvr = getPermittedVotingRanges(permittedLabels(accountId, cd));
}
for (Map.Entry<String, LabelWithStatus> entry : labels.entrySet()) {
ApprovalInfo ai = approvalInfo(accountLoader, accountId, 0, null, null, null);
byLabel.put(entry.getKey(), ai);
addApproval(entry.getValue().label(), ai);
}
for (PatchSetApproval psa : current.get(accountId)) {
Optional<LabelType> type = labelTypes.byLabel(psa.labelId());
if (!type.isPresent()) {
continue;
}
short val = psa.value();
ApprovalInfo info = byLabel.get(type.get().getName());
if (info != null) {
info.value = Integer.valueOf(val);
info.permittedVotingRange = pvr.getOrDefault(type.get().getName(), null);
info.setDate(psa.granted());
info.tag = psa.tag().orElse(null);
if (psa.postSubmit()) {
info.postSubmit = true;
}
}
if (!standard) {
continue;
}
setLabelScores(accountLoader, type.get(), labels.get(type.get().getName()), val, accountId);
}
}
return labels;
}
use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.
the class ChangeInserter method updateChange.
@Override
public boolean updateChange(ChangeContext ctx) throws RestApiException, IOException, PermissionBackendException, ConfigInvalidException {
// Use defensive copy created by ChangeControl.
change = ctx.getChange();
patchSetInfo = patchSetInfoFactory.get(ctx.getRevWalk(), ctx.getRevWalk().parseCommit(commitId), psId);
ctx.getChange().setCurrentPatchSet(patchSetInfo);
ChangeUpdate update = ctx.getUpdate(psId);
update.setChangeId(change.getKey().get());
update.setSubjectForCommit("Create change");
update.setBranch(change.getDest().branch());
try {
update.setTopic(change.getTopic());
} catch (ValidationException ex) {
throw new BadRequestException(ex.getMessage());
}
update.setPsDescription(patchSetDescription);
update.setPrivate(isPrivate);
update.setWorkInProgress(workInProgress);
if (revertOf != null) {
update.setRevertOf(revertOf.get());
}
if (cherryPickOf != null) {
update.setCherryPickOf(cherryPickOf.getCommaSeparatedChangeAndPatchSetId());
}
List<String> newGroups = groups;
if (newGroups.isEmpty()) {
newGroups = GroupCollector.getDefaultGroups(commitId);
}
patchSet = psUtil.insert(ctx.getRevWalk(), update, psId, commitId, newGroups, pushCert, patchSetDescription);
/* TODO: fixStatusToMerged is used here because the tests
* (byStatusClosed() in AbstractQueryChangesTest)
* insert changes that are already merged,
* and setStatus may not be used to set the Status to merged
*
* is it possible to make the tests use the merge code path,
* instead of setting the status directly?
*/
if (change.getStatus() == Change.Status.MERGED) {
update.fixStatusToMerged(new SubmissionId(change));
} else {
update.setStatus(change.getStatus());
}
reviewerAdditions = reviewerModifier.prepare(ctx.getNotes(), ctx.getUser(), getReviewerInputs(), true);
Optional<ReviewerModification> reviewerError = reviewerAdditions.getFailures().stream().findFirst();
if (reviewerError.isPresent()) {
throw new UnprocessableEntityException(reviewerError.get().result.error);
}
reviewerAdditions.updateChange(ctx, patchSet);
LabelTypes labelTypes = projectState.getLabelTypes();
approvalsUtil.addApprovalsForNewPatchSet(update, labelTypes, patchSet, ctx.getUser(), approvals);
// TODO(dborowitz): Still necessary?
if (!approvals.isEmpty()) {
update.putReviewer(ctx.getAccountId(), REVIEWER);
}
if (message != null) {
changeMessage = cmUtil.setChangeMessage(update, message, ChangeMessagesUtil.uploadedPatchSetTag(workInProgress));
}
return true;
}
use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.
the class DeleteReviewerOp method updateChange.
@Override
public boolean updateChange(ChangeContext ctx) throws AuthException, ResourceNotFoundException, PermissionBackendException, IOException {
Account.Id reviewerId = reviewer.id();
// Check of removing this reviewer (even if there is no vote processed by the loop below) is OK
removeReviewerControl.checkRemoveReviewer(ctx.getNotes(), ctx.getUser(), reviewerId);
if (!approvalsUtil.getReviewers(ctx.getNotes()).all().contains(reviewerId)) {
throw new ResourceNotFoundException(String.format("Reviewer %s doesn't exist in the change, hence can't delete it", reviewer.getName()));
}
currChange = ctx.getChange();
setPatchSet(psUtil.current(ctx.getNotes()));
LabelTypes labelTypes = projectCache.get(ctx.getProject()).orElseThrow(illegalState(ctx.getProject())).getLabelTypes(ctx.getNotes());
// removing a reviewer will remove all her votes
for (LabelType lt : labelTypes.getLabelTypes()) {
newApprovals.put(lt.getName(), (short) 0);
}
String ccOrReviewer = approvalsUtil.getReviewers(ctx.getNotes()).byState(ReviewerStateInternal.CC).contains(reviewerId) ? "cc" : "reviewer";
StringBuilder msg = new StringBuilder();
msg.append(String.format("Removed %s %s", ccOrReviewer, AccountTemplateUtil.getAccountTemplate(reviewer.id())));
StringBuilder removedVotesMsg = new StringBuilder();
removedVotesMsg.append(" with the following votes:\n\n");
boolean votesRemoved = false;
for (PatchSetApproval a : approvals(ctx, reviewerId)) {
// Check if removing this vote is OK
removeReviewerControl.checkRemoveReviewer(ctx.getNotes(), ctx.getUser(), a);
if (a.patchSetId().equals(patchSet.id()) && a.value() != 0) {
oldApprovals.put(a.label(), a.value());
removedVotesMsg.append("* ").append(a.label()).append(formatLabelValue(a.value())).append(" by ").append(AccountTemplateUtil.getAccountTemplate(a.accountId())).append("\n");
votesRemoved = true;
}
}
if (votesRemoved) {
msg.append(removedVotesMsg);
} else {
msg.append(".");
}
ChangeUpdate update = ctx.getUpdate(patchSet.id());
update.removeReviewer(reviewerId);
mailMessage = cmUtil.setChangeMessage(ctx, msg.toString(), ChangeMessagesUtil.TAG_DELETE_REVIEWER);
return true;
}
use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.
the class ReviewerJson method format.
public ReviewerInfo format(ReviewerInfo out, Account.Id reviewerAccountId, ChangeData cd, Iterable<PatchSetApproval> approvals) throws PermissionBackendException {
LabelTypes labelTypes = cd.getLabelTypes();
out.approvals = new TreeMap<>(labelTypes.nameComparator());
for (PatchSetApproval ca : approvals) {
Optional<LabelType> at = labelTypes.byLabel(ca.labelId());
at.ifPresent(lt -> out.approvals.put(lt.getName(), formatValue(ca.value())));
}
// Add dummy approvals for all permitted labels for the user even if they
// do not exist in the DB.
PatchSet ps = cd.currentPatchSet();
if (ps != null) {
PermissionBackend.ForChange perm = permissionBackend.absentUser(reviewerAccountId).change(cd);
for (SubmitRecord rec : cd.submitRecords(SubmitRuleOptions.defaults())) {
if (rec.labels == null) {
continue;
}
for (SubmitRecord.Label label : rec.labels) {
String name = label.label;
Optional<LabelType> type = labelTypes.byLabel(name);
if (out.approvals.containsKey(name) || !type.isPresent()) {
continue;
}
if (perm.test(new LabelPermission(type.get()))) {
out.approvals.put(name, formatValue((short) 0));
}
}
}
}
if (out.approvals.isEmpty()) {
out.approvals = null;
}
return out;
}
use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.
the class LabelNormalizer method normalize.
/**
* Returns copies of approvals normalized to the defined ranges for the label type. Approvals for
* unknown labels are not included in the output
*
* @param notes change notes containing the given approvals.
* @param approvals list of approvals.
*/
public Result normalize(ChangeNotes notes, Collection<PatchSetApproval> approvals) {
List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size());
LabelTypes labelTypes = projectCache.get(notes.getProjectName()).orElseThrow(illegalState(notes.getProjectName())).getLabelTypes(notes);
for (PatchSetApproval psa : approvals) {
Change.Id changeId = psa.key().patchSetId().changeId();
checkArgument(changeId.equals(notes.getChangeId()), "Approval %s does not match change %s", psa.key(), notes.getChange().getKey());
if (psa.isLegacySubmit()) {
unchanged.add(psa);
continue;
}
Optional<LabelType> label = labelTypes.byLabel(psa.labelId());
if (!label.isPresent()) {
deleted.add(psa);
continue;
}
PatchSetApproval copy = applyTypeFloor(label.get(), psa);
if (copy.value() != psa.value()) {
updated.add(copy);
} else {
unchanged.add(psa);
}
}
return Result.create(unchanged, updated, deleted);
}
Aggregations