// Copyright (C) 2012 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gerrit.server.change; import static com.google.gerrit.common.data.LabelValue.formatValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.gerrit.common.data.LabelType; import com.google.gerrit.common.data.LabelTypes; import com.google.gerrit.common.data.Permission; import com.google.gerrit.common.data.PermissionRange; import com.google.gerrit.common.data.SubmitRecord; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.ApprovalsUtil; import com.google.gerrit.server.account.AccountInfo; import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.query.change.ChangeData; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.TreeMap; @Singleton public class ReviewerJson { private final Provider<ReviewDb> db; private final ChangeData.Factory changeDataFactory; private final ApprovalsUtil approvalsUtil; private final AccountInfo.Loader.Factory accountLoaderFactory; @Inject ReviewerJson(Provider<ReviewDb> db, ChangeData.Factory changeDataFactory, ApprovalsUtil approvalsUtil, AccountInfo.Loader.Factory accountLoaderFactory) { this.db = db; this.changeDataFactory = changeDataFactory; this.approvalsUtil = approvalsUtil; this.accountLoaderFactory = accountLoaderFactory; } public List<ReviewerInfo> format(Collection<ReviewerResource> rsrcs) throws OrmException { List<ReviewerInfo> infos = Lists.newArrayListWithCapacity(rsrcs.size()); AccountInfo.Loader loader = accountLoaderFactory.create(true); for (ReviewerResource rsrc : rsrcs) { ReviewerInfo info = format(new ReviewerInfo( rsrc.getUser().getAccountId()), rsrc.getUserControl(), rsrc.getNotes()); loader.put(info); infos.add(info); } loader.fill(); return infos; } public List<ReviewerInfo> format(ReviewerResource rsrc) throws OrmException { return format(ImmutableList.<ReviewerResource> of(rsrc)); } public ReviewerInfo format(ReviewerInfo out, ChangeControl ctl, ChangeNotes changeNotes) throws OrmException { PatchSet.Id psId = ctl.getChange().currentPatchSetId(); return format(out, ctl, approvalsUtil.byPatchSetUser(db.get(), ctl, psId, out._id)); } public ReviewerInfo format(ReviewerInfo out, ChangeControl ctl, Iterable<PatchSetApproval> approvals) throws OrmException { LabelTypes labelTypes = ctl.getLabelTypes(); // Don't use Maps.newTreeMap(Comparator) due to OpenJDK bug 100167. out.approvals = new TreeMap<>(labelTypes.nameComparator()); for (PatchSetApproval ca : approvals) { for (PermissionRange pr : ctl.getLabelRanges()) { if (!pr.isEmpty()) { LabelType at = labelTypes.byLabel(ca.getLabelId()); if (at != null) { out.approvals.put(at.getName(), formatValue(ca.getValue())); } } } } // Add dummy approvals for all permitted labels for the user even if they // do not exist in the DB. ChangeData cd = changeDataFactory.create(db.get(), ctl); PatchSet ps = cd.currentPatchSet(); if (ps != null) { for (SubmitRecord rec : ctl.canSubmit(db.get(), ps, cd, true, false, true)) { if (rec.labels == null) { continue; } for (SubmitRecord.Label label : rec.labels) { String name = label.label; if (!out.approvals.containsKey(name) && !ctl.getRange(Permission.forLabel(name)).isEmpty()) { out.approvals.put(name, formatValue((short) 0)); } } } } if (out.approvals.isEmpty()) { out.approvals = null; } return out; } public static class ReviewerInfo extends AccountInfo { Map<String, String> approvals; protected ReviewerInfo(Account.Id id) { super(id); } } public static class PostResult { public List<ReviewerInfo> reviewers; public String error; Boolean confirm; } }