Merge "Remove ChangeControl from ChangeData"

This commit is contained in:
Patrick Hiesel
2017-09-25 12:28:47 +00:00
committed by Gerrit Code Review
20 changed files with 180 additions and 123 deletions

View File

@@ -119,6 +119,7 @@ import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.LabelPermission; import com.google.gerrit.server.permissions.LabelPermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.RemoveReviewerControl; import com.google.gerrit.server.project.RemoveReviewerControl;
@@ -219,6 +220,7 @@ public class ChangeJson {
private final ApprovalsUtil approvalsUtil; private final ApprovalsUtil approvalsUtil;
private final RemoveReviewerControl removeReviewerControl; private final RemoveReviewerControl removeReviewerControl;
private final TrackingFooters trackingFooters; private final TrackingFooters trackingFooters;
private final ChangeControl.GenericFactory changeControlFactory;
private boolean lazyLoad = true; private boolean lazyLoad = true;
private AccountLoader accountLoader; private AccountLoader accountLoader;
private FixInput fix; private FixInput fix;
@@ -251,6 +253,7 @@ public class ChangeJson {
ApprovalsUtil approvalsUtil, ApprovalsUtil approvalsUtil,
RemoveReviewerControl removeReviewerControl, RemoveReviewerControl removeReviewerControl,
TrackingFooters trackingFooters, TrackingFooters trackingFooters,
ChangeControl.GenericFactory changeControlFactory,
@Assisted Iterable<ListChangesOption> options) { @Assisted Iterable<ListChangesOption> options) {
this.db = db; this.db = db;
this.userProvider = user; this.userProvider = user;
@@ -276,6 +279,7 @@ public class ChangeJson {
this.indexes = indexes; this.indexes = indexes;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
this.removeReviewerControl = removeReviewerControl; this.removeReviewerControl = removeReviewerControl;
this.changeControlFactory = changeControlFactory;
this.options = Sets.immutableEnumSet(options); this.options = Sets.immutableEnumSet(options);
this.trackingFooters = trackingFooters; this.trackingFooters = trackingFooters;
} }
@@ -345,7 +349,7 @@ public class ChangeJson {
} }
public ChangeInfo format(RevisionResource rsrc) throws OrmException { public ChangeInfo format(RevisionResource rsrc) throws OrmException {
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getChangeResource()); ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
return format(cd, Optional.of(rsrc.getPatchSet().getId()), true); return format(cd, Optional.of(rsrc.getPatchSet().getId()), true);
} }
@@ -494,7 +498,11 @@ public class ChangeJson {
} }
} }
PermissionBackend.ForChange perm = permissionBackend.user(user).database(db).change(cd); PermissionBackend.WithUser withUser = permissionBackend.user(user).database(db);
PermissionBackend.ForChange perm =
lazyLoad
? withUser.change(cd)
: withUser.indexedChange(cd, notesFactory.createFromIndexedChange(cd.change()));
Change in = cd.change(); Change in = cd.change();
out.project = in.getProject().get(); out.project = in.getProject().get();
out.branch = in.getDest().getShortName(); out.branch = in.getDest().getShortName();
@@ -588,15 +596,20 @@ public class ChangeJson {
} else { } else {
src = null; src = null;
} }
ChangeControl ctl = null;
if (needMessages || needRevisions) {
ctl = changeControlFactory.controlFor(db.get(), cd.change(), userProvider.get());
}
if (needMessages) { if (needMessages) {
out.messages = messages(cd, src); out.messages = messages(ctl, cd, src);
} }
finish(out); finish(out);
// This block must come after the ChangeInfo is mostly populated, since // This block must come after the ChangeInfo is mostly populated, since
// it will be passed to ActionVisitors as-is. // it will be passed to ActionVisitors as-is.
if (needRevisions) { if (needRevisions) {
out.revisions = revisions(cd, src, limitToPsId, out); out.revisions = revisions(ctl, cd, src, limitToPsId, out);
if (out.revisions != null) { if (out.revisions != null) {
for (Map.Entry<String, RevisionInfo> entry : out.revisions.entrySet()) { for (Map.Entry<String, RevisionInfo> entry : out.revisions.entrySet()) {
if (entry.getValue().isCurrent) { if (entry.getValue().isCurrent) {
@@ -653,11 +666,11 @@ public class ChangeJson {
return result; return result;
} }
private boolean submittable(ChangeData cd) { private boolean submittable(ChangeData cd) throws OrmException {
return SubmitRecord.findOkRecord(cd.submitRecords(SUBMIT_RULE_OPTIONS_STRICT)).isPresent(); return SubmitRecord.findOkRecord(cd.submitRecords(SUBMIT_RULE_OPTIONS_STRICT)).isPresent();
} }
private List<SubmitRecord> submitRecords(ChangeData cd) { private List<SubmitRecord> submitRecords(ChangeData cd) throws OrmException {
return cd.submitRecords(SUBMIT_RULE_OPTIONS_LENIENT); return cd.submitRecords(SUBMIT_RULE_OPTIONS_LENIENT);
} }
@@ -709,7 +722,7 @@ public class ChangeJson {
} }
private Map<String, LabelWithStatus> initLabels( private Map<String, LabelWithStatus> initLabels(
ChangeData cd, LabelTypes labelTypes, boolean standard) { ChangeData cd, LabelTypes labelTypes, boolean standard) throws OrmException {
Map<String, LabelWithStatus> labels = new TreeMap<>(labelTypes.nameComparator()); Map<String, LabelWithStatus> labels = new TreeMap<>(labelTypes.nameComparator());
for (SubmitRecord rec : submitRecords(cd)) { for (SubmitRecord rec : submitRecords(cd)) {
if (rec.labels == null) { if (rec.labels == null) {
@@ -1091,8 +1104,8 @@ public class ChangeJson {
return result; return result;
} }
private Collection<ChangeMessageInfo> messages(ChangeData cd, Map<PatchSet.Id, PatchSet> map) private Collection<ChangeMessageInfo> messages(
throws OrmException { ChangeControl ctl, ChangeData cd, Map<PatchSet.Id, PatchSet> map) throws OrmException {
List<ChangeMessage> messages = cmUtil.byChange(db.get(), cd.notes()); List<ChangeMessage> messages = cmUtil.byChange(db.get(), cd.notes());
if (messages.isEmpty()) { if (messages.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
@@ -1102,7 +1115,7 @@ public class ChangeJson {
for (ChangeMessage message : messages) { for (ChangeMessage message : messages) {
PatchSet.Id patchNum = message.getPatchSetId(); PatchSet.Id patchNum = message.getPatchSetId();
PatchSet ps = patchNum != null ? map.get(patchNum) : null; PatchSet ps = patchNum != null ? map.get(patchNum) : null;
if (patchNum == null || cd.changeControl().isPatchVisible(ps, db.get())) { if (patchNum == null || ctl.isPatchVisible(ps, db.get())) {
ChangeMessageInfo cmi = new ChangeMessageInfo(); ChangeMessageInfo cmi = new ChangeMessageInfo();
cmi.id = message.getKey().get(); cmi.id = message.getKey().get();
cmi.author = accountLoader.get(message.getAuthor()); cmi.author = accountLoader.get(message.getAuthor());
@@ -1217,6 +1230,7 @@ public class ChangeJson {
} }
private Map<String, RevisionInfo> revisions( private Map<String, RevisionInfo> revisions(
ChangeControl ctl,
ChangeData cd, ChangeData cd,
Map<PatchSet.Id, PatchSet> map, Map<PatchSet.Id, PatchSet> map,
Optional<PatchSet.Id> limitToPsId, Optional<PatchSet.Id> limitToPsId,
@@ -1235,7 +1249,7 @@ public class ChangeJson {
} else { } else {
want = id.equals(cd.change().currentPatchSetId()); want = id.equals(cd.change().currentPatchSetId());
} }
if (want && cd.changeControl().isPatchVisible(in, db.get())) { if (want && ctl.isPatchVisible(in, db.get())) {
res.put(in.getRevision().get(), toRevisionInfo(cd, in, repo, rw, false, changeInfo)); res.put(in.getRevision().get(), toRevisionInfo(cd, in, repo, rw, false, changeInfo));
} }
} }
@@ -1392,6 +1406,7 @@ public class ChangeJson {
private Map<String, FetchInfo> makeFetchMap(ChangeData cd, PatchSet in) throws OrmException { private Map<String, FetchInfo> makeFetchMap(ChangeData cd, PatchSet in) throws OrmException {
Map<String, FetchInfo> r = new LinkedHashMap<>(); Map<String, FetchInfo> r = new LinkedHashMap<>();
ChangeControl ctl = changeControlFactory.controlFor(db.get(), cd.change(), anonymous);
for (DynamicMap.Entry<DownloadScheme> e : downloadSchemes) { for (DynamicMap.Entry<DownloadScheme> e : downloadSchemes) {
String schemeName = e.getExportName(); String schemeName = e.getExportName();
DownloadScheme scheme = e.getProvider().get(); DownloadScheme scheme = e.getProvider().get();
@@ -1400,8 +1415,7 @@ public class ChangeJson {
continue; continue;
} }
if (!scheme.isAuthSupported() if (!scheme.isAuthSupported() && !ctl.isPatchVisible(in, db.get())) {
&& !cd.changeControl().forUser(anonymous).isPatchVisible(in, db.get())) {
continue; continue;
} }

View File

@@ -27,6 +27,7 @@ import com.google.gerrit.server.CommonConverters;
import com.google.gerrit.server.PatchSetUtil; import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.change.RelatedChangesSorter.PatchSetData; import com.google.gerrit.server.change.RelatedChangesSorter.PatchSetData;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -63,13 +64,14 @@ public class GetRelated implements RestReadView<RevisionResource> {
@Override @Override
public RelatedInfo apply(RevisionResource rsrc) public RelatedInfo apply(RevisionResource rsrc)
throws RepositoryNotFoundException, IOException, OrmException { throws RepositoryNotFoundException, IOException, OrmException, NoSuchProjectException {
RelatedInfo relatedInfo = new RelatedInfo(); RelatedInfo relatedInfo = new RelatedInfo();
relatedInfo.changes = getRelated(rsrc); relatedInfo.changes = getRelated(rsrc);
return relatedInfo; return relatedInfo;
} }
private List<ChangeAndCommit> getRelated(RevisionResource rsrc) throws OrmException, IOException { private List<ChangeAndCommit> getRelated(RevisionResource rsrc)
throws OrmException, IOException, NoSuchProjectException {
Set<String> groups = getAllGroups(rsrc.getNotes()); Set<String> groups = getAllGroups(rsrc.getNotes());
if (groups.isEmpty()) { if (groups.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
@@ -93,7 +95,7 @@ public class GetRelated implements RestReadView<RevisionResource> {
reloadChangeIfStale(cds, basePs); reloadChangeIfStale(cds, basePs);
for (PatchSetData d : sorter.sort(cds, basePs)) { for (PatchSetData d : sorter.sort(cds, basePs, rsrc.getUser())) {
PatchSet ps = d.patchSet(); PatchSet ps = d.patchSet();
RevCommit commit; RevCommit commit;
if (isEdit && ps.getId().equals(basePs.getId())) { if (isEdit && ps.getId().equals(basePs.getId())) {

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.server.ReviewDbUtil; import com.google.gerrit.reviewdb.server.ReviewDbUtil;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.git.BranchOrderSection; import com.google.gerrit.server.git.BranchOrderSection;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeUtil; import com.google.gerrit.server.git.MergeUtil;
@@ -108,8 +109,8 @@ public class Mergeable implements RestReadView<RevisionResource> {
return result; return result;
} }
ChangeData cd = changeDataFactory.create(db.get(), resource.getChangeResource()); ChangeData cd = changeDataFactory.create(db.get(), resource.getNotes());
result.submitType = getSubmitType(cd, ps); result.submitType = getSubmitType(resource.getUser(), cd, ps);
try (Repository git = gitManager.openRepository(change.getProject())) { try (Repository git = gitManager.openRepository(change.getProject())) {
ObjectId commit = toId(ps); ObjectId commit = toId(ps);
@@ -141,9 +142,10 @@ public class Mergeable implements RestReadView<RevisionResource> {
return result; return result;
} }
private SubmitType getSubmitType(ChangeData cd, PatchSet patchSet) throws OrmException { private SubmitType getSubmitType(CurrentUser user, ChangeData cd, PatchSet patchSet)
throws OrmException {
SubmitTypeRecord rec = SubmitTypeRecord rec =
submitRuleEvaluatorFactory.create(cd).setPatchSet(patchSet).getSubmitType(); submitRuleEvaluatorFactory.create(user, cd).setPatchSet(patchSet).getSubmitType();
if (rec.status != SubmitTypeRecord.Status.OK) { if (rec.status != SubmitTypeRecord.Status.OK) {
throw new OrmException("Submit type rule failed: " + rec); throw new OrmException("Submit type rule failed: " + rec);
} }

View File

@@ -570,7 +570,7 @@ public class PostReview
} }
private Set<String> getAffectedFilePaths(RevisionResource revision) throws OrmException { private Set<String> getAffectedFilePaths(RevisionResource revision) throws OrmException {
ChangeData changeData = changeDataFactory.create(db.get(), revision.getChangeResource()); ChangeData changeData = changeDataFactory.create(db.get(), revision.getNotes());
return new HashSet<>(changeData.filePaths(revision.getPatchSet())); return new HashSet<>(changeData.filePaths(revision.getPatchSet()));
} }
@@ -1107,7 +1107,7 @@ public class PostReview
if (ctx.getAccountId().equals(ctx.getChange().getOwner())) { if (ctx.getAccountId().equals(ctx.getChange().getOwner())) {
return true; return true;
} }
ChangeData cd = changeDataFactory.create(db.get(), ctx); ChangeData cd = changeDataFactory.create(db.get(), ctx.getNotes());
ReviewerSet reviewers = cd.reviewers(); ReviewerSet reviewers = cd.reviewers();
if (reviewers.byState(REVIEWER).contains(ctx.getAccountId())) { if (reviewers.byState(REVIEWER).contains(ctx.getAccountId())) {
return true; return true;

View File

@@ -446,7 +446,7 @@ public class PostReviewers
result.ccs = Lists.newArrayListWithCapacity(opResult.addedCCs().size()); result.ccs = Lists.newArrayListWithCapacity(opResult.addedCCs().size());
for (Account.Id accountId : opResult.addedCCs()) { for (Account.Id accountId : opResult.addedCCs()) {
IdentifiedUser u = identifiedUserFactory.create(accountId); IdentifiedUser u = identifiedUserFactory.create(accountId);
result.ccs.add(json.format(new ReviewerInfo(accountId.get()), perm.user(u), cd)); result.ccs.add(json.format(caller, new ReviewerInfo(accountId.get()), perm.user(u), cd));
} }
accountLoaderFactory.create(true).fill(result.ccs); accountLoaderFactory.create(true).fill(result.ccs);
for (Address a : reviewersByEmail) { for (Address a : reviewersByEmail) {
@@ -459,6 +459,7 @@ public class PostReviewers
IdentifiedUser u = identifiedUserFactory.create(psa.getAccountId()); IdentifiedUser u = identifiedUserFactory.create(psa.getAccountId());
result.reviewers.add( result.reviewers.add(
json.format( json.format(
caller,
new ReviewerInfo(psa.getAccountId().get()), new ReviewerInfo(psa.getAccountId().get()),
perm.user(u), perm.user(u),
cd, cd,

View File

@@ -27,7 +27,9 @@ import com.google.common.collect.MultimapBuilder;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -53,20 +55,23 @@ import org.eclipse.jgit.revwalk.RevWalk;
@Singleton @Singleton
class RelatedChangesSorter { class RelatedChangesSorter {
private final GitRepositoryManager repoManager; private final GitRepositoryManager repoManager;
private final ProjectControl.GenericFactory projectControlFactory;
@Inject @Inject
RelatedChangesSorter(GitRepositoryManager repoManager) { RelatedChangesSorter(
GitRepositoryManager repoManager, ProjectControl.GenericFactory projectControlFactory) {
this.repoManager = repoManager; this.repoManager = repoManager;
this.projectControlFactory = projectControlFactory;
} }
public List<PatchSetData> sort(List<ChangeData> in, PatchSet startPs) public List<PatchSetData> sort(List<ChangeData> in, PatchSet startPs, CurrentUser user)
throws OrmException, IOException { throws OrmException, IOException, NoSuchProjectException {
checkArgument(!in.isEmpty(), "Input may not be empty"); checkArgument(!in.isEmpty(), "Input may not be empty");
// Map of all patch sets, keyed by commit SHA-1. // Map of all patch sets, keyed by commit SHA-1.
Map<String, PatchSetData> byId = collectById(in); Map<String, PatchSetData> byId = collectById(in);
PatchSetData start = byId.get(startPs.getRevision().get()); PatchSetData start = byId.get(startPs.getRevision().get());
checkArgument(start != null, "%s not found in %s", startPs, in); checkArgument(start != null, "%s not found in %s", startPs, in);
ProjectControl ctl = start.data().changeControl().getProjectControl(); ProjectControl ctl = projectControlFactory.controlFor(start.data().project(), user);
// Map of patch set -> immediate parent. // Map of patch set -> immediate parent.
ListMultimap<PatchSetData, PatchSetData> parents = ListMultimap<PatchSetData, PatchSetData> parents =

View File

@@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil; import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountLoader; import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.permissions.LabelPermission; import com.google.gerrit.server.permissions.LabelPermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
@@ -77,6 +78,7 @@ public class ReviewerJson {
} }
ReviewerInfo info = ReviewerInfo info =
format( format(
rsrc.getChangeResource().getUser(),
new ReviewerInfo(rsrc.getReviewerUser().getAccountId().get()), new ReviewerInfo(rsrc.getReviewerUser().getAccountId().get()),
permissionBackend.user(rsrc.getReviewerUser()).database(db).change(cd), permissionBackend.user(rsrc.getReviewerUser()).database(db).change(cd),
cd); cd);
@@ -92,10 +94,12 @@ public class ReviewerJson {
return format(ImmutableList.<ReviewerResource>of(rsrc)); return format(ImmutableList.<ReviewerResource>of(rsrc));
} }
public ReviewerInfo format(ReviewerInfo out, PermissionBackend.ForChange perm, ChangeData cd) public ReviewerInfo format(
CurrentUser user, ReviewerInfo out, PermissionBackend.ForChange perm, ChangeData cd)
throws OrmException, PermissionBackendException { throws OrmException, PermissionBackendException {
PatchSet.Id psId = cd.change().currentPatchSetId(); PatchSet.Id psId = cd.change().currentPatchSetId();
return format( return format(
user,
out, out,
perm, perm,
cd, cd,
@@ -104,6 +108,7 @@ public class ReviewerJson {
} }
public ReviewerInfo format( public ReviewerInfo format(
CurrentUser user,
ReviewerInfo out, ReviewerInfo out,
PermissionBackend.ForChange perm, PermissionBackend.ForChange perm,
ChangeData cd, ChangeData cd,
@@ -125,7 +130,7 @@ public class ReviewerJson {
if (ps != null) { if (ps != null) {
for (SubmitRecord rec : for (SubmitRecord rec :
submitRuleEvaluatorFactory submitRuleEvaluatorFactory
.create(cd) .create(user, cd)
.setFastEvalLabels(true) .setFastEvalLabels(true)
.setAllowDraft(true) .setAllowDraft(true)
.evaluate()) { .evaluate()) {

View File

@@ -322,12 +322,7 @@ public class Submit
} }
ReviewDb db = dbProvider.get(); ReviewDb db = dbProvider.get();
ChangeData cd; ChangeData cd = changeDataFactory.create(db, resource.getNotes());
try {
cd = changeDataFactory.create(db, resource.getChangeResource());
} catch (NoSuchChangeException e) {
return null; // submit not visible
}
try { try {
MergeOp.checkSubmitRule(cd, false); MergeOp.checkSubmitRule(cd, false);
} catch (ResourceConflictException e) { } catch (ResourceConflictException e) {

View File

@@ -71,7 +71,7 @@ public class TestSubmitRule implements RestModifyView<RevisionResource, TestSubm
input.filters = MoreObjects.firstNonNull(input.filters, filters); input.filters = MoreObjects.firstNonNull(input.filters, filters);
SubmitRuleEvaluator evaluator = SubmitRuleEvaluator evaluator =
submitRuleEvaluatorFactory.create( submitRuleEvaluatorFactory.create(
changeDataFactory.create(db.get(), rsrc.getChangeResource())); rsrc.getUser(), changeDataFactory.create(db.get(), rsrc.getNotes()));
List<SubmitRecord> records = List<SubmitRecord> records =
evaluator evaluator

View File

@@ -65,7 +65,7 @@ public class TestSubmitType implements RestModifyView<RevisionResource, TestSubm
input.filters = MoreObjects.firstNonNull(input.filters, filters); input.filters = MoreObjects.firstNonNull(input.filters, filters);
SubmitRuleEvaluator evaluator = SubmitRuleEvaluator evaluator =
submitRuleEvaluatorFactory.create( submitRuleEvaluatorFactory.create(
changeDataFactory.create(db.get(), rsrc.getChangeResource())); rsrc.getUser(), changeDataFactory.create(db.get(), rsrc.getNotes()));
SubmitTypeRecord rec = SubmitTypeRecord rec =
evaluator evaluator

View File

@@ -327,7 +327,8 @@ public class MergeOp implements AutoCloseable {
return allowClosed ? SUBMIT_RULE_OPTIONS_ALLOW_CLOSED : SUBMIT_RULE_OPTIONS; return allowClosed ? SUBMIT_RULE_OPTIONS_ALLOW_CLOSED : SUBMIT_RULE_OPTIONS;
} }
private static List<SubmitRecord> getSubmitRecords(ChangeData cd, boolean allowClosed) { private static List<SubmitRecord> getSubmitRecords(ChangeData cd, boolean allowClosed)
throws OrmException {
return cd.submitRecords(submitRuleOptions(allowClosed)); return cd.submitRecords(submitRuleOptions(allowClosed));
} }
@@ -391,7 +392,7 @@ public class MergeOp implements AutoCloseable {
commitStatus.maybeFailVerbose(); commitStatus.maybeFailVerbose();
} }
private void bypassSubmitRules(ChangeSet cs, boolean allowClosed) { private void bypassSubmitRules(ChangeSet cs, boolean allowClosed) throws OrmException {
checkArgument( checkArgument(
!cs.furtherHiddenChanges(), "cannot bypass submit rules for topic with hidden change"); !cs.furtherHiddenChanges(), "cannot bypass submit rules for topic with hidden change");
for (ChangeData cd : cs.changes()) { for (ChangeData cd : cs.changes()) {
@@ -705,15 +706,16 @@ public class MergeOp implements AutoCloseable {
Change.Id changeId = cd.getId(); Change.Id changeId = cd.getId();
ChangeNotes notes; ChangeNotes notes;
Change chg; Change chg;
SubmitType st;
try { try {
notes = cd.notes(); notes = cd.notes();
chg = cd.change(); chg = cd.change();
st = getSubmitType(cd);
} catch (OrmException e) { } catch (OrmException e) {
commitStatus.logProblem(changeId, e); commitStatus.logProblem(changeId, e);
continue; continue;
} }
SubmitType st = getSubmitType(cd);
if (st == null) { if (st == null) {
commitStatus.logProblem(changeId, "No submit type for change"); commitStatus.logProblem(changeId, "No submit type for change");
continue; continue;
@@ -828,7 +830,7 @@ public class MergeOp implements AutoCloseable {
} }
} }
private SubmitType getSubmitType(ChangeData cd) { private SubmitType getSubmitType(ChangeData cd) throws OrmException {
SubmitTypeRecord str = cd.submitTypeRecord(); SubmitTypeRecord str = cd.submitTypeRecord();
return str.isOk() ? str.type : null; return str.isOk() ? str.type : null;
} }

View File

@@ -160,7 +160,7 @@ public class MergeSuperSet {
} }
} }
private SubmitType submitType(ChangeData cd, PatchSet ps, boolean visible) private SubmitType submitType(CurrentUser user, ChangeData cd, PatchSet ps, boolean visible)
throws OrmException, IOException { throws OrmException, IOException {
// Submit type prolog rules mean that the submit type can depend on the // Submit type prolog rules mean that the submit type can depend on the
// submitting user and the content of the change. // submitting user and the content of the change.
@@ -179,7 +179,7 @@ public class MergeSuperSet {
SubmitTypeRecord str = SubmitTypeRecord str =
ps == cd.currentPatchSet() ps == cd.currentPatchSet()
? cd.submitTypeRecord() ? cd.submitTypeRecord()
: submitRuleEvaluatorFactory.create(cd).setPatchSet(ps).getSubmitType(); : submitRuleEvaluatorFactory.create(user, cd).setPatchSet(ps).getSubmitType();
if (!str.isOk()) { if (!str.isOk()) {
logErrorAndThrow("Failed to get submit type for " + cd.getId() + ": " + str.errorMessage); logErrorAndThrow("Failed to get submit type for " + cd.getId() + ": " + str.errorMessage);
} }
@@ -258,7 +258,7 @@ public class MergeSuperSet {
} }
} }
if (submitType(cd, ps, visiblePatchSet) == SubmitType.CHERRY_PICK) { if (submitType(user, cd, ps, visiblePatchSet) == SubmitType.CHERRY_PICK) {
if (visible) { if (visible) {
visibleChanges.add(cd); visibleChanges.add(cd);
} else { } else {

View File

@@ -299,7 +299,7 @@ public class ReplaceOp implements BatchUpdateOp {
recipients.add( recipients.add(
getRecipientsFromFooters(ctx.getDb(), accountResolver, draft, commit.getFooterLines())); getRecipientsFromFooters(ctx.getDb(), accountResolver, draft, commit.getFooterLines()));
recipients.remove(ctx.getAccountId()); recipients.remove(ctx.getAccountId());
ChangeData cd = changeDataFactory.create(ctx.getDb(), ctx); ChangeData cd = changeDataFactory.create(ctx.getDb(), ctx.getNotes());
MailRecipients oldRecipients = getRecipientsFromReviewers(cd.reviewers()); MailRecipients oldRecipients = getRecipientsFromReviewers(cd.reviewers());
Iterable<PatchSetApproval> newApprovals = Iterable<PatchSetApproval> newApprovals =
approvalsUtil.addApprovalsForNewPatchSet( approvalsUtil.addApprovalsForNewPatchSet(

View File

@@ -658,7 +658,8 @@ public class ChangeField {
return Lists.transform(records, r -> GSON.toJson(new StoredSubmitRecord(r)).getBytes(UTF_8)); return Lists.transform(records, r -> GSON.toJson(new StoredSubmitRecord(r)).getBytes(UTF_8));
} }
private static Iterable<byte[]> storedSubmitRecords(ChangeData cd, SubmitRuleOptions opts) { private static Iterable<byte[]> storedSubmitRecords(ChangeData cd, SubmitRuleOptions opts)
throws OrmException {
return storedSubmitRecords(cd.submitRecords(opts)); return storedSubmitRecords(cd.submitRecords(opts));
} }

View File

@@ -72,7 +72,7 @@ public class MergedSender extends ReplyToChangeSender {
args.approvalsUtil.byPatchSet( args.approvalsUtil.byPatchSet(
args.db.get(), args.db.get(),
changeData.notes(), changeData.notes(),
changeData.changeControl().getUser(), args.identifiedUserFactory.create(changeData.change().getOwner()),
patchSet.getId(), patchSet.getId(),
null, null,
null)) { null)) {

View File

@@ -397,7 +397,7 @@ public class ChangeControl {
} }
private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) { private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) {
return cd != null ? cd : changeDataFactory.create(db, this); return cd != null ? cd : changeDataFactory.create(db, getNotes());
} }
public boolean isDraftVisible(ReviewDb db, ChangeData cd) throws OrmException { public boolean isDraftVisible(ReviewDb db, ChangeData cd) throws OrmException {
@@ -442,7 +442,7 @@ public class ChangeControl {
if (cd == null) { if (cd == null) {
ReviewDb reviewDb = db(); ReviewDb reviewDb = db();
checkState(reviewDb != null, "need ReviewDb"); checkState(reviewDb != null, "need ReviewDb");
cd = changeDataFactory.create(reviewDb, ChangeControl.this); cd = changeDataFactory.create(reviewDb, getNotes());
} }
return cd; return cd;
} }

View File

@@ -32,6 +32,7 @@ import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission; import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.util.Providers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -517,7 +518,10 @@ public class RefControl {
@Override @Override
public ForChange change(ChangeData cd) { public ForChange change(ChangeData cd) {
try { try {
return cd.changeControl().forUser(getUser()).asForChange(cd, db); // TODO(hiesel) Force callers to call database() and use db instead of cd.db()
return getProjectControl()
.controlFor(cd.db(), cd.change())
.asForChange(cd, Providers.of(cd.db()));
} catch (OrmException e) { } catch (OrmException e) {
return FailedPermissionBackend.change("unavailable", e); return FailedPermissionBackend.change("unavailable", e);
} }

View File

@@ -24,6 +24,7 @@ import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.rules.PrologEnvironment; import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.rules.StoredValues; import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
@@ -33,6 +34,7 @@ import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.googlecode.prolog_cafe.exceptions.CompileException; import com.googlecode.prolog_cafe.exceptions.CompileException;
import com.googlecode.prolog_cafe.exceptions.ReductionLimitException; import com.googlecode.prolog_cafe.exceptions.ReductionLimitException;
@@ -43,6 +45,7 @@ import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm; import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term; import com.googlecode.prolog_cafe.lang.Term;
import com.googlecode.prolog_cafe.lang.VariableTerm; import com.googlecode.prolog_cafe.lang.VariableTerm;
import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -87,29 +90,45 @@ public class SubmitRuleEvaluator {
} }
public interface Factory { public interface Factory {
SubmitRuleEvaluator create(ChangeData cd); SubmitRuleEvaluator create(CurrentUser user, ChangeData cd);
} }
private final AccountCache accountCache; private final AccountCache accountCache;
private final Accounts accounts; private final Accounts accounts;
private final Emails emails; private final Emails emails;
private final ProjectCache projectCache;
private final Provider<ReviewDb> dbProvider;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeData cd; private final ChangeData cd;
private SubmitRuleOptions.Builder optsBuilder = SubmitRuleOptions.defaults(); private SubmitRuleOptions.Builder optsBuilder = SubmitRuleOptions.defaults();
private SubmitRuleOptions opts; private SubmitRuleOptions opts;
private Change change;
private CurrentUser user;
private PatchSet patchSet; private PatchSet patchSet;
private boolean logErrors = true; private boolean logErrors = true;
private long reductionsConsumed; private long reductionsConsumed;
private ChangeControl control; private ProjectState projectState;
private Term submitRule; private Term submitRule;
@Inject @Inject
SubmitRuleEvaluator( SubmitRuleEvaluator(
AccountCache accountCache, Accounts accounts, Emails emails, @Assisted ChangeData cd) { AccountCache accountCache,
Accounts accounts,
Emails emails,
ProjectCache projectCache,
Provider<ReviewDb> dbProvider,
ChangeControl.GenericFactory changeControlFactory,
@Assisted CurrentUser user,
@Assisted ChangeData cd) {
this.accountCache = accountCache; this.accountCache = accountCache;
this.accounts = accounts; this.accounts = accounts;
this.emails = emails; this.emails = emails;
this.projectCache = projectCache;
this.dbProvider = dbProvider;
this.changeControlFactory = changeControlFactory;
this.user = user;
this.cd = cd; this.cd = cd;
} }
@@ -225,19 +244,18 @@ public class SubmitRuleEvaluator {
public List<SubmitRecord> evaluate() { public List<SubmitRecord> evaluate() {
initOptions(); initOptions();
try { try {
initChange(); init();
} catch (OrmException e) { } catch (OrmException e) {
return ruleError("Error looking up change " + cd.getId(), e); return ruleError("Error looking up change " + cd.getId(), e);
} }
Change c = control.getChange(); if (!opts.allowClosed() && change.getStatus().isClosed()) {
if (!opts.allowClosed() && c.getStatus().isClosed()) {
SubmitRecord rec = new SubmitRecord(); SubmitRecord rec = new SubmitRecord();
rec.status = SubmitRecord.Status.CLOSED; rec.status = SubmitRecord.Status.CLOSED;
return Collections.singletonList(rec); return Collections.singletonList(rec);
} }
if (!opts.allowDraft()) { if (!opts.allowDraft()) {
if (c.getStatus() == Change.Status.DRAFT || patchSet.isDraft()) { if (change.getStatus() == Change.Status.DRAFT || patchSet.isDraft()) {
return cannotSubmitDraft(); return cannotSubmitDraft();
} }
} }
@@ -250,7 +268,7 @@ public class SubmitRuleEvaluator {
"can_submit", "can_submit",
"locate_submit_filter", "locate_submit_filter",
"filter_submit_results", "filter_submit_results",
control.getUser()); user);
} catch (RuleEvalException e) { } catch (RuleEvalException e) {
return ruleError(e.getMessage(), e); return ruleError(e.getMessage(), e);
} }
@@ -271,7 +289,9 @@ public class SubmitRuleEvaluator {
private List<SubmitRecord> cannotSubmitDraft() { private List<SubmitRecord> cannotSubmitDraft() {
try { try {
if (!control.isDraftVisible(cd.db(), cd)) { if (!changeControlFactory
.controlFor(dbProvider.get(), change, user)
.isDraftVisible(cd.db(), cd)) {
return createRuleError("Patch set " + patchSet.getId() + " not found"); return createRuleError("Patch set " + patchSet.getId() + " not found");
} }
if (patchSet.isDraft()) { if (patchSet.isDraft()) {
@@ -279,8 +299,7 @@ public class SubmitRuleEvaluator {
} }
return createRuleError("Cannot submit draft changes"); return createRuleError("Cannot submit draft changes");
} catch (OrmException err) { } catch (OrmException err) {
PatchSet.Id psId = PatchSet.Id psId = patchSet != null ? patchSet.getId() : patchSet.getId();
patchSet != null ? patchSet.getId() : control.getChange().currentPatchSetId();
String msg = "Cannot check visibility of patch set " + psId; String msg = "Cannot check visibility of patch set " + psId;
log.error(msg, err); log.error(msg, err);
return createRuleError(msg); return createRuleError(msg);
@@ -414,17 +433,22 @@ public class SubmitRuleEvaluator {
public SubmitTypeRecord getSubmitType() { public SubmitTypeRecord getSubmitType() {
initOptions(); initOptions();
try { try {
initChange(); init();
} catch (OrmException e) { } catch (OrmException e) {
return typeError("Error looking up change " + cd.getId(), e); return typeError("Error looking up change " + cd.getId(), e);
} }
try { try {
if (control.getChange().getStatus() == Change.Status.DRAFT if (change.getStatus() == Change.Status.DRAFT
&& !control.isDraftVisible(cd.db(), cd)) { && !changeControlFactory
.controlFor(dbProvider.get(), change, user)
.isDraftVisible(cd.db(), cd)) {
return SubmitTypeRecord.error("Patch set " + patchSet.getId() + " not found"); return SubmitTypeRecord.error("Patch set " + patchSet.getId() + " not found");
} }
if (patchSet.isDraft() && !control.isDraftVisible(cd.db(), cd)) { if (patchSet.isDraft()
&& !changeControlFactory
.controlFor(dbProvider.get(), change, user)
.isDraftVisible(cd.db(), cd)) {
return SubmitTypeRecord.error("Patch set " + patchSet.getId() + " not found"); return SubmitTypeRecord.error("Patch set " + patchSet.getId() + " not found");
} }
} catch (OrmException err) { } catch (OrmException err) {
@@ -561,7 +585,6 @@ public class SubmitRuleEvaluator {
} }
private PrologEnvironment getPrologEnvironment(CurrentUser user) throws RuleEvalException { private PrologEnvironment getPrologEnvironment(CurrentUser user) throws RuleEvalException {
ProjectState projectState = control.getProjectControl().getProjectState();
PrologEnvironment env; PrologEnvironment env;
try { try {
if (opts.rule() == null) { if (opts.rule() == null) {
@@ -571,12 +594,10 @@ public class SubmitRuleEvaluator {
} }
} catch (CompileException err) { } catch (CompileException err) {
String msg; String msg;
if (opts.rule() == null && control.getProjectControl().isOwner()) { if (opts.rule() == null) {
msg = String.format("Cannot load rules.pl for %s: %s", getProjectName(), err.getMessage()); msg = String.format("Cannot load rules.pl for %s: %s", getProjectName(), err.getMessage());
} else if (opts.rule() != null) {
msg = err.getMessage();
} else { } else {
msg = String.format("Cannot load rules.pl for %s", getProjectName()); msg = err.getMessage();
} }
throw new RuleEvalException(msg, err); throw new RuleEvalException(msg, err);
} }
@@ -598,7 +619,6 @@ public class SubmitRuleEvaluator {
String filterRuleLocatorName, String filterRuleLocatorName,
String filterRuleWrapperName) String filterRuleWrapperName)
throws RuleEvalException { throws RuleEvalException {
ProjectState projectState = control.getProjectControl().getProjectState();
PrologEnvironment childEnv = env; PrologEnvironment childEnv = env;
for (ProjectState parentState : projectState.parents()) { for (ProjectState parentState : projectState.parents()) {
PrologEnvironment parentEnv; PrologEnvironment parentEnv;
@@ -684,9 +704,20 @@ public class SubmitRuleEvaluator {
} }
} }
private void initChange() throws OrmException { private void init() throws OrmException {
if (control == null) { if (change == null) {
control = cd.changeControl(); change = cd.change();
if (change == null) {
throw new OrmException("No change found");
}
}
if (projectState == null) {
try {
projectState = projectCache.checkedGet(change.getProject());
} catch (IOException e) {
throw new OrmException("Can't load project state", e);
}
} }
if (patchSet == null) { if (patchSet == null) {
@@ -698,6 +729,6 @@ public class SubmitRuleEvaluator {
} }
private String getProjectName() { private String getProjectName() {
return control.getProjectControl().getProjectState().getName(); return projectState.getName();
} }
} }

View File

@@ -58,7 +58,6 @@ import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.ReviewerStatusUpdate; import com.google.gerrit.server.ReviewerStatusUpdate;
import com.google.gerrit.server.StarredChangesUtil; import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.StarredChangesUtil.StarRef; import com.google.gerrit.server.StarredChangesUtil.StarRef;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.GetPureRevert; import com.google.gerrit.server.change.GetPureRevert;
import com.google.gerrit.server.change.MergeabilityCache; import com.google.gerrit.server.change.MergeabilityCache;
import com.google.gerrit.server.config.AllUsersName; import com.google.gerrit.server.config.AllUsersName;
@@ -76,7 +75,6 @@ import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.SubmitRuleEvaluator; import com.google.gerrit.server.project.SubmitRuleEvaluator;
import com.google.gerrit.server.project.SubmitRuleOptions; import com.google.gerrit.server.project.SubmitRuleOptions;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet; import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -282,44 +280,23 @@ public class ChangeData {
public static class Factory { public static class Factory {
private final AssistedFactory assistedFactory; private final AssistedFactory assistedFactory;
private final ChangeControl.GenericFactory changeControlFactory;
@Inject @Inject
Factory(AssistedFactory assistedFactory, ChangeControl.GenericFactory changeControlFactory) { Factory(AssistedFactory assistedFactory) {
this.assistedFactory = assistedFactory; this.assistedFactory = assistedFactory;
this.changeControlFactory = changeControlFactory;
} }
public ChangeData create(ReviewDb db, Project.NameKey project, Change.Id id) { public ChangeData create(ReviewDb db, Project.NameKey project, Change.Id id) {
return assistedFactory.create(db, project, id, null, null, null); return assistedFactory.create(db, project, id, null, null);
} }
public ChangeData create(ReviewDb db, Change change) { public ChangeData create(ReviewDb db, Change change) {
return assistedFactory.create(db, change.getProject(), change.getId(), change, null, null); return assistedFactory.create(db, change.getProject(), change.getId(), change, null);
} }
public ChangeData create(ReviewDb db, ChangeNotes notes) { public ChangeData create(ReviewDb db, ChangeNotes notes) {
return assistedFactory.create( return assistedFactory.create(
db, notes.getChange().getProject(), notes.getChangeId(), notes.getChange(), notes, null); db, notes.getChange().getProject(), notes.getChangeId(), notes.getChange(), notes);
}
public ChangeData create(ReviewDb db, ChangeControl control) {
return assistedFactory.create(
db,
control.getChange().getProject(),
control.getId(),
control.getChange(),
control.getNotes(),
control);
}
// TODO(hiesel): Remove these after ChangeControl is removed from ChangeData
public ChangeData create(ReviewDb db, ChangeResource rsrc) throws NoSuchChangeException {
return create(db, changeControlFactory.controlFor(rsrc.getNotes(), rsrc.getUser()));
}
public ChangeData create(ReviewDb db, ChangeContext ctx) throws NoSuchChangeException {
return create(db, changeControlFactory.controlFor(ctx.getNotes(), ctx.getUser()));
} }
} }
@@ -329,8 +306,7 @@ public class ChangeData {
Project.NameKey project, Project.NameKey project,
Change.Id id, Change.Id id,
@Nullable Change change, @Nullable Change change,
@Nullable ChangeNotes notes, @Nullable ChangeNotes notes);
@Nullable ChangeControl control);
} }
/** /**
@@ -347,7 +323,7 @@ public class ChangeData {
ChangeData cd = ChangeData cd =
new ChangeData( new ChangeData(
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, project, id, null, null, null); null, null, null, null, null, project, id, null, null);
cd.currentPatchSet = new PatchSet(new PatchSet.Id(id, currentPatchSetId)); cd.currentPatchSet = new PatchSet(new PatchSet.Id(id, currentPatchSetId));
return cd; return cd;
} }
@@ -356,7 +332,6 @@ public class ChangeData {
private @Nullable final StarredChangesUtil starredChangesUtil; private @Nullable final StarredChangesUtil starredChangesUtil;
private final AllUsersName allUsersName; private final AllUsersName allUsersName;
private final ApprovalsUtil approvalsUtil; private final ApprovalsUtil approvalsUtil;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeMessagesUtil cmUtil; private final ChangeMessagesUtil cmUtil;
private final ChangeNotes.Factory notesFactory; private final ChangeNotes.Factory notesFactory;
private final CommentsUtil commentsUtil; private final CommentsUtil commentsUtil;
@@ -371,6 +346,7 @@ public class ChangeData {
private final TrackingFooters trackingFooters; private final TrackingFooters trackingFooters;
private final GetPureRevert pureRevert; private final GetPureRevert pureRevert;
private final SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory; private final SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory;
private final ChangeControl.GenericFactory changeControlFactory;
// Required assisted injected fields. // Required assisted injected fields.
private final ReviewDb db; private final ReviewDb db;
@@ -426,7 +402,6 @@ public class ChangeData {
@Nullable StarredChangesUtil starredChangesUtil, @Nullable StarredChangesUtil starredChangesUtil,
ApprovalsUtil approvalsUtil, ApprovalsUtil approvalsUtil,
AllUsersName allUsersName, AllUsersName allUsersName,
ChangeControl.GenericFactory changeControlFactory,
ChangeMessagesUtil cmUtil, ChangeMessagesUtil cmUtil,
ChangeNotes.Factory notesFactory, ChangeNotes.Factory notesFactory,
CommentsUtil commentsUtil, CommentsUtil commentsUtil,
@@ -441,15 +416,14 @@ public class ChangeData {
TrackingFooters trackingFooters, TrackingFooters trackingFooters,
GetPureRevert pureRevert, GetPureRevert pureRevert,
SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory, SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory,
ChangeControl.GenericFactory changeControlFactory,
@Assisted ReviewDb db, @Assisted ReviewDb db,
@Assisted Project.NameKey project, @Assisted Project.NameKey project,
@Assisted Change.Id id, @Assisted Change.Id id,
@Assisted @Nullable Change change, @Assisted @Nullable Change change,
@Assisted @Nullable ChangeNotes notes, @Assisted @Nullable ChangeNotes notes) {
@Assisted @Nullable ChangeControl control) {
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
this.allUsersName = allUsersName; this.allUsersName = allUsersName;
this.changeControlFactory = changeControlFactory;
this.cmUtil = cmUtil; this.cmUtil = cmUtil;
this.notesFactory = notesFactory; this.notesFactory = notesFactory;
this.commentsUtil = commentsUtil; this.commentsUtil = commentsUtil;
@@ -465,6 +439,7 @@ public class ChangeData {
this.trackingFooters = trackingFooters; this.trackingFooters = trackingFooters;
this.pureRevert = pureRevert; this.pureRevert = pureRevert;
this.submitRuleEvaluatorFactory = submitRuleEvaluatorFactory; this.submitRuleEvaluatorFactory = submitRuleEvaluatorFactory;
this.changeControlFactory = changeControlFactory;
// May be null in tests when created via createForTest above, in which case lazy-loading will // May be null in tests when created via createForTest above, in which case lazy-loading will
// intentionally fail with NPE. Still not marked @Nullable in the constructor, to force callers // intentionally fail with NPE. Still not marked @Nullable in the constructor, to force callers
@@ -476,7 +451,6 @@ public class ChangeData {
this.change = change; this.change = change;
this.notes = notes; this.notes = notes;
this.changeControl = control;
} }
public ChangeData setLazyLoad(boolean load) { public ChangeData setLazyLoad(boolean load) {
@@ -601,7 +575,8 @@ public class ChangeData {
return visibleTo == user; return visibleTo == user;
} }
public ChangeControl changeControl() throws OrmException { private ChangeControl changeControl() throws OrmException {
// TODO(hiesel): Remove this method.
if (changeControl == null) { if (changeControl == null) {
Change c = change(); Change c = change();
try { try {
@@ -648,8 +623,7 @@ public class ChangeData {
} catch (IOException e) { } catch (IOException e) {
throw new OrmException("project state not available", e); throw new OrmException("project state not available", e);
} }
labelTypes = labelTypes = state.getLabelTypes(change().getDest(), userFactory.create(change().getOwner()));
state.getLabelTypes(changeControl().getChange().getDest(), changeControl().getUser());
} }
return labelTypes; return labelTypes;
} }
@@ -693,7 +667,12 @@ public class ChangeData {
currentApprovals = currentApprovals =
ImmutableList.copyOf( ImmutableList.copyOf(
approvalsUtil.byPatchSet( approvalsUtil.byPatchSet(
db, notes(), changeControl().getUser(), c.currentPatchSetId(), null, null)); db,
notes(),
userFactory.create(c.getOwner()),
c.currentPatchSetId(),
null,
null));
} catch (OrmException e) { } catch (OrmException e) {
if (e.getCause() instanceof NoSuchChangeException) { if (e.getCause() instanceof NoSuchChangeException) {
currentApprovals = Collections.emptyList(); currentApprovals = Collections.emptyList();
@@ -965,13 +944,17 @@ public class ChangeData {
return messages; return messages;
} }
public List<SubmitRecord> submitRecords(SubmitRuleOptions options) { public List<SubmitRecord> submitRecords(SubmitRuleOptions options) throws OrmException {
List<SubmitRecord> records = submitRecords.get(options); List<SubmitRecord> records = submitRecords.get(options);
if (records == null) { if (records == null) {
if (!lazyLoad) { if (!lazyLoad) {
return Collections.emptyList(); return Collections.emptyList();
} }
records = submitRuleEvaluatorFactory.create(this).setOptions(options).evaluate(); records =
submitRuleEvaluatorFactory
.create(userFactory.create(change().getOwner()), this)
.setOptions(options)
.evaluate();
submitRecords.put(options, records); submitRecords.put(options, records);
} }
return records; return records;
@@ -986,9 +969,12 @@ public class ChangeData {
submitRecords.put(options, records); submitRecords.put(options, records);
} }
public SubmitTypeRecord submitTypeRecord() { public SubmitTypeRecord submitTypeRecord() throws OrmException {
if (submitTypeRecord == null) { if (submitTypeRecord == null) {
submitTypeRecord = submitRuleEvaluatorFactory.create(this).getSubmitType(); submitTypeRecord =
submitRuleEvaluatorFactory
.create(userFactory.create(change().getOwner()), this)
.getSubmitType();
} }
return submitTypeRecord; return submitTypeRecord;
} }

View File

@@ -31,6 +31,7 @@ import com.google.gerrit.server.data.PatchSetAttribute;
import com.google.gerrit.server.data.QueryStatsAttribute; import com.google.gerrit.server.data.QueryStatsAttribute;
import com.google.gerrit.server.events.EventFactory; import com.google.gerrit.server.events.EventFactory;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.SubmitRuleEvaluator; import com.google.gerrit.server.project.SubmitRuleEvaluator;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -78,6 +79,7 @@ public class OutputStreamQuery {
private final EventFactory eventFactory; private final EventFactory eventFactory;
private final TrackingFooters trackingFooters; private final TrackingFooters trackingFooters;
private final CurrentUser user; private final CurrentUser user;
private final ChangeControl.GenericFactory changeControlFactory;
private final SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory; private final SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory;
private OutputFormat outputFormat = OutputFormat.TEXT; private OutputFormat outputFormat = OutputFormat.TEXT;
@@ -103,6 +105,7 @@ public class OutputStreamQuery {
EventFactory eventFactory, EventFactory eventFactory,
TrackingFooters trackingFooters, TrackingFooters trackingFooters,
CurrentUser user, CurrentUser user,
ChangeControl.GenericFactory changeControlFactory,
SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory) { SubmitRuleEvaluator.Factory submitRuleEvaluatorFactory) {
this.db = db; this.db = db;
this.repoManager = repoManager; this.repoManager = repoManager;
@@ -111,6 +114,7 @@ public class OutputStreamQuery {
this.eventFactory = eventFactory; this.eventFactory = eventFactory;
this.trackingFooters = trackingFooters; this.trackingFooters = trackingFooters;
this.user = user; this.user = user;
this.changeControlFactory = changeControlFactory;
this.submitRuleEvaluatorFactory = submitRuleEvaluatorFactory; this.submitRuleEvaluatorFactory = submitRuleEvaluatorFactory;
} }
@@ -250,7 +254,11 @@ public class OutputStreamQuery {
if (includeSubmitRecords) { if (includeSubmitRecords) {
eventFactory.addSubmitRecords( eventFactory.addSubmitRecords(
c, c,
submitRuleEvaluatorFactory.create(d).setAllowClosed(true).setAllowDraft(true).evaluate()); submitRuleEvaluatorFactory
.create(user, d)
.setAllowClosed(true)
.setAllowDraft(true)
.evaluate());
} }
if (includeCommitMessage) { if (includeCommitMessage) {
@@ -270,12 +278,13 @@ public class OutputStreamQuery {
} }
} }
ChangeControl ctl = changeControlFactory.controlFor(db, d.change(), user);
if (includePatchSets) { if (includePatchSets) {
eventFactory.addPatchSets( eventFactory.addPatchSets(
db, db,
rw, rw,
c, c,
d.changeControl().getVisiblePatchSets(d.patchSets(), db), ctl.getVisiblePatchSets(d.patchSets(), db),
includeApprovals ? d.approvals().asMap() : null, includeApprovals ? d.approvals().asMap() : null,
includeFiles, includeFiles,
d.change(), d.change(),
@@ -284,7 +293,7 @@ public class OutputStreamQuery {
if (includeCurrentPatchSet) { if (includeCurrentPatchSet) {
PatchSet current = d.currentPatchSet(); PatchSet current = d.currentPatchSet();
if (current != null && d.changeControl().forUser(user).isPatchVisible(current, d.db())) { if (current != null && ctl.isPatchVisible(current, d.db())) {
c.currentPatchSet = eventFactory.asPatchSetAttribute(db, rw, d.change(), current); c.currentPatchSet = eventFactory.asPatchSetAttribute(db, rw, d.change(), current);
eventFactory.addApprovals(c.currentPatchSet, d.currentApprovals(), labelTypes); eventFactory.addApprovals(c.currentPatchSet, d.currentApprovals(), labelTypes);
@@ -304,7 +313,7 @@ public class OutputStreamQuery {
db, db,
rw, rw,
c, c,
d.changeControl().getVisiblePatchSets(d.patchSets(), db), ctl.getVisiblePatchSets(d.patchSets(), db),
includeApprovals ? d.approvals().asMap() : null, includeApprovals ? d.approvals().asMap() : null,
includeFiles, includeFiles,
d.change(), d.change(),