Reduce usage of ProjectControl

Reduce the usage of ProjectControl by replacing it with ProjectState and
CurrentUser where it was just used as a container for these.

Eventually, {Ref,Change,Project}Control should be package-private. This
commit is an incremental step towards that goal.

Change-Id: I204d7cae3816e81a7859672a6ac3b5d5273997fa
This commit is contained in:
Patrick Hiesel
2017-08-29 14:14:04 +02:00
parent 5a87d534ce
commit d5d39cb8bb
37 changed files with 135 additions and 148 deletions

View File

@@ -147,7 +147,8 @@ public abstract class ProjectAccessHandler<T> extends Handler<T> {
setParent setParent
.get() .get()
.validateParentUpdate( .validateParentUpdate(
projectControl, projectControl.getProject().getNameKey(),
projectControl.getUser().asIdentifiedUser(),
MoreObjects.firstNonNull(parentProjectName, allProjects).get(), MoreObjects.firstNonNull(parentProjectName, allProjects).get(),
checkIfOwner); checkIfOwner);
} catch (AuthException e) { } catch (AuthException e) {

View File

@@ -37,7 +37,7 @@ import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.WorkQueue; import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.change.ChangeField; import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder; import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.query.change.InternalChangeQuery;
@@ -108,7 +108,7 @@ public class ReviewerRecommender {
public List<Account.Id> suggestReviewers( public List<Account.Id> suggestReviewers(
ChangeNotes changeNotes, ChangeNotes changeNotes,
SuggestReviewers suggestReviewers, SuggestReviewers suggestReviewers,
ProjectControl projectControl, ProjectState projectState,
List<Account.Id> candidateList) List<Account.Id> candidateList)
throws OrmException, IOException, ConfigInvalidException { throws OrmException, IOException, ConfigInvalidException {
String query = suggestReviewers.getQuery(); String query = suggestReviewers.getQuery();
@@ -118,7 +118,7 @@ public class ReviewerRecommender {
if (Strings.isNullOrEmpty(query)) { if (Strings.isNullOrEmpty(query)) {
reviewerScores = baseRankingForEmptyQuery(baseWeight); reviewerScores = baseRankingForEmptyQuery(baseWeight);
} else { } else {
reviewerScores = baseRankingForCandidateList(candidateList, projectControl, baseWeight); reviewerScores = baseRankingForCandidateList(candidateList, projectState, baseWeight);
} }
// Send the query along with a candidate list to all plugins and merge the // Send the query along with a candidate list to all plugins and merge the
@@ -135,7 +135,7 @@ public class ReviewerRecommender {
.getProvider() .getProvider()
.get() .get()
.suggestReviewers( .suggestReviewers(
projectControl.getProject().getNameKey(), projectState.getProject().getNameKey(),
changeNotes.getChangeId(), changeNotes.getChangeId(),
query, query,
reviewerScores.keySet())); reviewerScores.keySet()));
@@ -227,7 +227,7 @@ public class ReviewerRecommender {
} }
private Map<Account.Id, MutableDouble> baseRankingForCandidateList( private Map<Account.Id, MutableDouble> baseRankingForCandidateList(
List<Account.Id> candidates, ProjectControl projectControl, double baseWeight) List<Account.Id> candidates, ProjectState projectState, double baseWeight)
throws OrmException, IOException, ConfigInvalidException { throws OrmException, IOException, ConfigInvalidException {
// Get each reviewer's activity based on number of applied labels // Get each reviewer's activity based on number of applied labels
// (weighted 10d), number of comments (weighted 0.5d) and number of owned // (weighted 10d), number of comments (weighted 0.5d) and number of owned
@@ -240,11 +240,11 @@ public class ReviewerRecommender {
for (Account.Id id : candidates) { for (Account.Id id : candidates) {
try { try {
Predicate<ChangeData> projectQuery = Predicate<ChangeData> projectQuery =
changeQueryBuilder.project(projectControl.getProject().getName()); changeQueryBuilder.project(projectState.getProject().getName());
// Get all labels for this project and create a compound OR query to // Get all labels for this project and create a compound OR query to
// fetch all changes where users have applied one of these labels // fetch all changes where users have applied one of these labels
List<LabelType> labelTypes = projectControl.getLabelTypes().getLabelTypes(); List<LabelType> labelTypes = projectState.getLabelTypes().getLabelTypes();
List<Predicate<ChangeData>> labelPredicates = new ArrayList<>(labelTypes.size()); List<Predicate<ChangeData>> labelPredicates = new ArrayList<>(labelTypes.size());
for (LabelType type : labelTypes) { for (LabelType type : labelTypes) {
labelPredicates.add(changeQueryBuilder.label(type.getName() + ",user=" + id)); labelPredicates.add(changeQueryBuilder.label(type.getName() + ",user=" + id));

View File

@@ -42,7 +42,7 @@ import com.google.gerrit.server.change.PostReviewers;
import com.google.gerrit.server.change.SuggestReviewers; import com.google.gerrit.server.change.SuggestReviewers;
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.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.account.AccountPredicates; import com.google.gerrit.server.query.account.AccountPredicates;
import com.google.gerrit.server.query.account.AccountQueryBuilder; import com.google.gerrit.server.query.account.AccountQueryBuilder;
import com.google.gerrit.server.query.account.AccountQueryProcessor; import com.google.gerrit.server.query.account.AccountQueryProcessor;
@@ -145,7 +145,7 @@ public class ReviewersUtil {
public List<SuggestedReviewerInfo> suggestReviewers( public List<SuggestedReviewerInfo> suggestReviewers(
ChangeNotes changeNotes, ChangeNotes changeNotes,
SuggestReviewers suggestReviewers, SuggestReviewers suggestReviewers,
ProjectControl projectControl, ProjectState projectState,
VisibilityControl visibilityControl, VisibilityControl visibilityControl,
boolean excludeGroups) boolean excludeGroups)
throws IOException, OrmException, ConfigInvalidException { throws IOException, OrmException, ConfigInvalidException {
@@ -162,7 +162,7 @@ public class ReviewersUtil {
} }
List<Account.Id> sortedRecommendations = List<Account.Id> sortedRecommendations =
recommendAccounts(changeNotes, suggestReviewers, projectControl, candidateList); recommendAccounts(changeNotes, suggestReviewers, projectState, candidateList);
// Filter accounts by visibility and enforce limit // Filter accounts by visibility and enforce limit
List<Account.Id> filteredRecommendations = new ArrayList<>(); List<Account.Id> filteredRecommendations = new ArrayList<>();
@@ -183,10 +183,7 @@ public class ReviewersUtil {
// important. // important.
suggestedReviewer.addAll( suggestedReviewer.addAll(
suggestAccountGroups( suggestAccountGroups(
suggestReviewers, suggestReviewers, projectState, visibilityControl, limit - suggestedReviewer.size()));
projectControl,
visibilityControl,
limit - suggestedReviewer.size()));
} }
if (suggestedReviewer.size() <= limit) { if (suggestedReviewer.size() <= limit) {
@@ -215,12 +212,12 @@ public class ReviewersUtil {
private List<Account.Id> recommendAccounts( private List<Account.Id> recommendAccounts(
ChangeNotes changeNotes, ChangeNotes changeNotes,
SuggestReviewers suggestReviewers, SuggestReviewers suggestReviewers,
ProjectControl projectControl, ProjectState projectState,
List<Account.Id> candidateList) List<Account.Id> candidateList)
throws OrmException, IOException, ConfigInvalidException { throws OrmException, IOException, ConfigInvalidException {
try (Timer0.Context ctx = metrics.recommendAccountsLatency.start()) { try (Timer0.Context ctx = metrics.recommendAccountsLatency.start()) {
return reviewerRecommender.suggestReviewers( return reviewerRecommender.suggestReviewers(
changeNotes, suggestReviewers, projectControl, candidateList); changeNotes, suggestReviewers, projectState, candidateList);
} }
} }
@@ -247,16 +244,16 @@ public class ReviewersUtil {
private List<SuggestedReviewerInfo> suggestAccountGroups( private List<SuggestedReviewerInfo> suggestAccountGroups(
SuggestReviewers suggestReviewers, SuggestReviewers suggestReviewers,
ProjectControl projectControl, ProjectState projectState,
VisibilityControl visibilityControl, VisibilityControl visibilityControl,
int limit) int limit)
throws OrmException, IOException { throws OrmException, IOException {
try (Timer0.Context ctx = metrics.queryGroupsLatency.start()) { try (Timer0.Context ctx = metrics.queryGroupsLatency.start()) {
List<SuggestedReviewerInfo> groups = new ArrayList<>(); List<SuggestedReviewerInfo> groups = new ArrayList<>();
for (GroupReference g : suggestAccountGroups(suggestReviewers, projectControl)) { for (GroupReference g : suggestAccountGroups(suggestReviewers, projectState)) {
GroupAsReviewer result = GroupAsReviewer result =
suggestGroupAsReviewer( suggestGroupAsReviewer(
suggestReviewers, projectControl.getProject(), g, visibilityControl); suggestReviewers, projectState.getProject(), g, visibilityControl);
if (result.allowed || result.allowedWithConfirmation) { if (result.allowed || result.allowedWithConfirmation) {
GroupBaseInfo info = new GroupBaseInfo(); GroupBaseInfo info = new GroupBaseInfo();
info.id = Url.encode(g.getUUID().get()); info.id = Url.encode(g.getUUID().get());
@@ -278,10 +275,11 @@ public class ReviewersUtil {
} }
private List<GroupReference> suggestAccountGroups( private List<GroupReference> suggestAccountGroups(
SuggestReviewers suggestReviewers, ProjectControl ctl) { SuggestReviewers suggestReviewers, ProjectState projectState) {
return Lists.newArrayList( return Lists.newArrayList(
Iterables.limit( Iterables.limit(
groupBackend.suggest(suggestReviewers.getQuery(), ctl), suggestReviewers.getLimit())); groupBackend.suggest(suggestReviewers.getQuery(), projectState),
suggestReviewers.getLimit()));
} }
private static class GroupAsReviewer { private static class GroupAsReviewer {

View File

@@ -20,7 +20,7 @@ import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.extensions.annotations.ExtensionPoint; import com.google.gerrit.extensions.annotations.ExtensionPoint;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import java.util.Collection; import java.util.Collection;
/** Implementations of GroupBackend provide lookup and membership accessors to a group system. */ /** Implementations of GroupBackend provide lookup and membership accessors to a group system. */
@@ -39,7 +39,7 @@ public interface GroupBackend {
GroupDescription.Basic get(AccountGroup.UUID uuid); GroupDescription.Basic get(AccountGroup.UUID uuid);
/** @return suggestions for the group name sorted by name. */ /** @return suggestions for the group name sorted by name. */
Collection<GroupReference> suggest(String name, @Nullable ProjectControl project); Collection<GroupReference> suggest(String name, @Nullable ProjectState project);
/** @return the group membership checker for the backend. */ /** @return the group membership checker for the backend. */
GroupMembership membershipsOf(IdentifiedUser user); GroupMembership membershipsOf(IdentifiedUser user);

View File

@@ -17,7 +17,7 @@ package com.google.gerrit.server.account;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
@@ -33,7 +33,7 @@ public class GroupBackends {
}; };
/** /**
* Runs {@link GroupBackend#suggest(String, ProjectControl)} and filters the result to return the * Runs {@link GroupBackend#suggest(String, ProjectState)} and filters the result to return the
* best suggestion, or null if one does not exist. * best suggestion, or null if one does not exist.
* *
* @param groupBackend the group backend * @param groupBackend the group backend
@@ -46,7 +46,7 @@ public class GroupBackends {
} }
/** /**
* Runs {@link GroupBackend#suggest(String, ProjectControl)} and filters the result to return the * Runs {@link GroupBackend#suggest(String, ProjectState)} and filters the result to return the
* best suggestion, or null if one does not exist. * best suggestion, or null if one does not exist.
* *
* @param groupBackend the group backend * @param groupBackend the group backend
@@ -56,7 +56,7 @@ public class GroupBackends {
*/ */
@Nullable @Nullable
public static GroupReference findBestSuggestion( public static GroupReference findBestSuggestion(
GroupBackend groupBackend, String name, @Nullable ProjectControl project) { GroupBackend groupBackend, String name, @Nullable ProjectState project) {
Collection<GroupReference> refs = groupBackend.suggest(name, project); Collection<GroupReference> refs = groupBackend.suggest(name, project);
if (refs.size() == 1) { if (refs.size() == 1) {
return Iterables.getOnlyElement(refs); return Iterables.getOnlyElement(refs);
@@ -71,7 +71,7 @@ public class GroupBackends {
} }
/** /**
* Runs {@link GroupBackend#suggest(String, ProjectControl)} and filters the result to return the * Runs {@link GroupBackend#suggest(String, ProjectState)} and filters the result to return the
* exact suggestion, or null if one does not exist. * exact suggestion, or null if one does not exist.
* *
* @param groupBackend the group backend * @param groupBackend the group backend
@@ -84,7 +84,7 @@ public class GroupBackends {
} }
/** /**
* Runs {@link GroupBackend#suggest(String, ProjectControl)} and filters the result to return the * Runs {@link GroupBackend#suggest(String, ProjectState)} and filters the result to return the
* exact suggestion, or null if one does not exist. * exact suggestion, or null if one does not exist.
* *
* @param groupBackend the group backend * @param groupBackend the group backend
@@ -94,7 +94,7 @@ public class GroupBackends {
*/ */
@Nullable @Nullable
public static GroupReference findExactSuggestion( public static GroupReference findExactSuggestion(
GroupBackend groupBackend, String name, ProjectControl project) { GroupBackend groupBackend, String name, ProjectState project) {
Collection<GroupReference> refs = groupBackend.suggest(name, project); Collection<GroupReference> refs = groupBackend.suggest(name, project);
for (GroupReference ref : refs) { for (GroupReference ref : refs) {
if (isExactSuggestion(ref, name)) { if (isExactSuggestion(ref, name)) {

View File

@@ -21,7 +21,7 @@ import com.google.gerrit.common.data.GroupDescriptions;
import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.util.Collection; import java.util.Collection;
@@ -64,7 +64,7 @@ public class InternalGroupBackend implements GroupBackend {
} }
@Override @Override
public Collection<GroupReference> suggest(String name, ProjectControl project) { public Collection<GroupReference> suggest(String name, ProjectState project) {
return groupCache return groupCache
.all() .all()
.stream() .stream()

View File

@@ -31,7 +31,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.StartupCheck; import com.google.gerrit.server.StartupCheck;
import com.google.gerrit.server.StartupException; import com.google.gerrit.server.StartupException;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.util.Collection; import java.util.Collection;
@@ -87,7 +87,7 @@ public class UniversalGroupBackend implements GroupBackend {
} }
@Override @Override
public Collection<GroupReference> suggest(String name, ProjectControl project) { public Collection<GroupReference> suggest(String name, ProjectState project) {
Set<GroupReference> groups = Sets.newTreeSet(GROUP_REF_NAME_COMPARATOR); Set<GroupReference> groups = Sets.newTreeSet(GROUP_REF_NAME_COMPARATOR);
for (GroupBackend g : backends) { for (GroupBackend g : backends) {
groups.addAll(g.suggest(name, project)); groups.addAll(g.suggest(name, project));

View File

@@ -277,7 +277,7 @@ public class ProjectApiImpl implements ProjectApi {
if (project == null) { if (project == null) {
throw new ResourceNotFoundException(name); throw new ResourceNotFoundException(name);
} }
return projectJson.format(project.getControl()); return projectJson.format(project.getProjectState());
} }
@Override @Override

View File

@@ -34,7 +34,7 @@ import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.externalids.ExternalId; import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.auth.ldap.Helper.LdapSchema; import com.google.gerrit.server.auth.ldap.Helper.LdapSchema;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.name.Named; import com.google.inject.name.Named;
@@ -158,7 +158,7 @@ public class LdapGroupBackend implements GroupBackend {
} }
@Override @Override
public Collection<GroupReference> suggest(String name, ProjectControl project) { public Collection<GroupReference> suggest(String name, ProjectState project) {
AccountGroup.UUID uuid = new AccountGroup.UUID(name); AccountGroup.UUID uuid = new AccountGroup.UUID(name);
if (isLdapUUID(uuid)) { if (isLdapUUID(uuid)) {
GroupDescription.Basic g = get(uuid); GroupDescription.Basic g = get(uuid);

View File

@@ -76,14 +76,14 @@ public class CherryPickCommit
input.message = message.isEmpty() ? commit.getFullMessage() : message; input.message = message.isEmpty() ? commit.getFullMessage() : message;
String destination = Strings.nullToEmpty(input.destination).trim(); String destination = Strings.nullToEmpty(input.destination).trim();
input.parent = input.parent == null ? 1 : input.parent; input.parent = input.parent == null ? 1 : input.parent;
Project.NameKey projectName = rsrc.getProject().getProject().getNameKey(); Project.NameKey projectName = rsrc.getProjectState().getProject().getNameKey();
if (destination.isEmpty()) { if (destination.isEmpty()) {
throw new BadRequestException("destination must be non-empty"); throw new BadRequestException("destination must be non-empty");
} }
String refName = RefNames.fullName(destination); String refName = RefNames.fullName(destination);
CreateChange.checkValidCLA(rsrc.getProject()); CreateChange.checkValidCLA(rsrc.getProjectState().controlFor(user.get()));
permissionBackend permissionBackend
.user(user) .user(user)
.project(projectName) .project(projectName)
@@ -99,7 +99,7 @@ public class CherryPickCommit
projectName, projectName,
commit, commit,
input, input,
new Branch.NameKey(rsrc.getProject().getProject().getNameKey(), refName)); new Branch.NameKey(rsrc.getProjectState().getProject().getNameKey(), refName));
return json.noOptions().format(projectName, cherryPickedChangeId); return json.noOptions().format(projectName, cherryPickedChangeId);
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage()); throw new BadRequestException(e.getMessage());

View File

@@ -194,7 +194,7 @@ public class CreateChange
ObjectId parentCommit; ObjectId parentCommit;
List<String> groups; List<String> groups;
if (input.baseChange != null) { if (input.baseChange != null) {
List<ChangeControl> ctls = changeFinder.find(input.baseChange, rsrc.getControl().getUser()); List<ChangeControl> ctls = changeFinder.find(input.baseChange, rsrc.getUser());
if (ctls.size() != 1) { if (ctls.size() != 1) {
throw new UnprocessableEntityException("Base change not found: " + input.baseChange); throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
} }
@@ -253,7 +253,7 @@ public class CreateChange
} }
c = c =
newMergeCommit( newMergeCommit(
git, oi, rw, rsrc.getControl(), mergeTip, input.merge, author, commitMessage); git, oi, rw, rsrc.getProjectState(), mergeTip, input.merge, author, commitMessage);
} else { } else {
// create an empty commit // create an empty commit
c = newCommit(oi, rw, author, mergeTip, commitMessage); c = newCommit(oi, rw, author, mergeTip, commitMessage);
@@ -310,7 +310,7 @@ public class CreateChange
Repository repo, Repository repo,
ObjectInserter oi, ObjectInserter oi,
RevWalk rw, RevWalk rw,
ProjectControl projectControl, ProjectState projectState,
RevCommit mergeTip, RevCommit mergeTip,
MergeInput merge, MergeInput merge,
PersonIdent authorIdent, PersonIdent authorIdent,
@@ -320,13 +320,12 @@ public class CreateChange
throw new BadRequestException("merge.source must be non-empty"); throw new BadRequestException("merge.source must be non-empty");
} }
ProjectState state = projectControl.getProjectState();
RevCommit sourceCommit = MergeUtil.resolveCommit(repo, rw, merge.source); RevCommit sourceCommit = MergeUtil.resolveCommit(repo, rw, merge.source);
if (!commits.canRead(state, repo, sourceCommit)) { if (!commits.canRead(projectState, repo, sourceCommit)) {
throw new BadRequestException("do not have read permission for: " + merge.source); throw new BadRequestException("do not have read permission for: " + merge.source);
} }
MergeUtil mergeUtil = mergeUtilFactory.create(state); MergeUtil mergeUtil = mergeUtilFactory.create(projectState);
// default merge strategy from project settings // default merge strategy from project settings
String mergeStrategy = String mergeStrategy =
MoreObjects.firstNonNull( MoreObjects.firstNonNull(

View File

@@ -44,7 +44,7 @@ import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.CommitsCollection; import com.google.gerrit.server.project.CommitsCollection;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.ProjectControl; 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.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper; import com.google.gerrit.server.update.RetryHelper;
@@ -79,6 +79,7 @@ public class CreateMergePatchSet
private final PatchSetUtil psUtil; private final PatchSetUtil psUtil;
private final MergeUtil.Factory mergeUtilFactory; private final MergeUtil.Factory mergeUtilFactory;
private final PatchSetInserter.Factory patchSetInserterFactory; private final PatchSetInserter.Factory patchSetInserterFactory;
private final ProjectCache projectCache;
@Inject @Inject
CreateMergePatchSet( CreateMergePatchSet(
@@ -91,7 +92,8 @@ public class CreateMergePatchSet
PatchSetUtil psUtil, PatchSetUtil psUtil,
MergeUtil.Factory mergeUtilFactory, MergeUtil.Factory mergeUtilFactory,
RetryHelper retryHelper, RetryHelper retryHelper,
PatchSetInserter.Factory patchSetInserterFactory) { PatchSetInserter.Factory patchSetInserterFactory,
ProjectCache projectCache) {
super(retryHelper); super(retryHelper);
this.db = db; this.db = db;
this.gitManager = gitManager; this.gitManager = gitManager;
@@ -102,6 +104,7 @@ public class CreateMergePatchSet
this.psUtil = psUtil; this.psUtil = psUtil;
this.mergeUtilFactory = mergeUtilFactory; this.mergeUtilFactory = mergeUtilFactory;
this.patchSetInserterFactory = patchSetInserterFactory; this.patchSetInserterFactory = patchSetInserterFactory;
this.projectCache = projectCache;
} }
@Override @Override
@@ -117,8 +120,7 @@ public class CreateMergePatchSet
} }
PatchSet ps = psUtil.current(db.get(), rsrc.getNotes()); PatchSet ps = psUtil.current(db.get(), rsrc.getNotes());
ProjectControl projectControl = rsrc.getControl().getProjectControl(); ProjectState projectState = projectCache.checkedGet(rsrc.getProject());
ProjectState state = projectControl.getProjectState();
Change change = rsrc.getChange(); Change change = rsrc.getChange();
Project.NameKey project = change.getProject(); Project.NameKey project = change.getProject();
Branch.NameKey dest = change.getDest(); Branch.NameKey dest = change.getDest();
@@ -128,7 +130,7 @@ public class CreateMergePatchSet
RevWalk rw = new RevWalk(reader)) { RevWalk rw = new RevWalk(reader)) {
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source); RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
if (!commits.canRead(state, git, sourceCommit)) { if (!commits.canRead(projectState, git, sourceCommit)) {
throw new ResourceNotFoundException( throw new ResourceNotFoundException(
"cannot find source commit: " + merge.source + " to merge."); "cannot find source commit: " + merge.source + " to merge.");
} }
@@ -140,7 +142,7 @@ public class CreateMergePatchSet
RevCommit newCommit = RevCommit newCommit =
createMergeCommit( createMergeCommit(
in, in,
projectControl, projectState,
dest, dest,
git, git,
oi, oi,
@@ -172,7 +174,7 @@ public class CreateMergePatchSet
private RevCommit createMergeCommit( private RevCommit createMergeCommit(
MergePatchSetInput in, MergePatchSetInput in,
ProjectControl projectControl, ProjectState projectState,
Branch.NameKey dest, Branch.NameKey dest,
Repository git, Repository git,
ObjectInserter oi, ObjectInserter oi,
@@ -210,7 +212,7 @@ public class CreateMergePatchSet
String mergeStrategy = String mergeStrategy =
MoreObjects.firstNonNull( MoreObjects.firstNonNull(
Strings.emptyToNull(in.merge.strategy), Strings.emptyToNull(in.merge.strategy),
mergeUtilFactory.create(projectControl.getProjectState()).mergeStrategyName()); mergeUtilFactory.create(projectState).mergeStrategyName());
return MergeUtil.createMergeCommit( return MergeUtil.createMergeCommit(
oi, git.getConfig(), mergeTip, sourceCommit, mergeStrategy, author, commitMsg, rw); oi, git.getConfig(), mergeTip, sourceCommit, mergeStrategy, author, commitMsg, rw);

View File

@@ -74,7 +74,7 @@ public class SuggestChangeReviewers extends SuggestReviewers
return reviewersUtil.suggestReviewers( return reviewersUtil.suggestReviewers(
rsrc.getNotes(), rsrc.getNotes(),
this, this,
rsrc.getControl().getProjectControl(), rsrc.getControl().getProjectControl().getProjectState(),
getVisibility(rsrc), getVisibility(rsrc),
excludeGroups); excludeGroups);
} }

View File

@@ -302,11 +302,12 @@ public class ListGroups implements RestReadView<TopLevelResource> {
throw new BadRequestException( throw new BadRequestException(
"You should only have no more than one --project and -n with --suggest"); "You should only have no more than one --project and -n with --suggest");
} }
List<GroupReference> groupRefs = List<GroupReference> groupRefs =
Lists.newArrayList( Lists.newArrayList(
Iterables.limit( Iterables.limit(
groupBackend.suggest(suggest, Iterables.getFirst(projects, null)), groupBackend.suggest(
suggest,
projects.stream().findFirst().map(pc -> pc.getProjectState()).orElse(null)),
limit <= 0 ? 10 : Math.min(limit, 10))); limit <= 0 ? 10 : Math.min(limit, 10)));
List<GroupInfo> groupInfos = Lists.newArrayListWithCapacity(groupRefs.size()); List<GroupInfo> groupInfos = Lists.newArrayListWithCapacity(groupRefs.size());

View File

@@ -32,7 +32,7 @@ import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupMembership; import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership; import com.google.gerrit.server.account.ListGroupMembership;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.util.ArrayList; import java.util.ArrayList;
@@ -156,7 +156,7 @@ public class SystemGroupBackend extends AbstractGroupBackend {
} }
@Override @Override
public Collection<GroupReference> suggest(String name, ProjectControl project) { public Collection<GroupReference> suggest(String name, ProjectState project) {
String nameLC = name.toLowerCase(Locale.US); String nameLC = name.toLowerCase(Locale.US);
SortedMap<String, GroupReference> matches = names.tailMap(nameLC); SortedMap<String, GroupReference> matches = names.tailMap(nameLC);
if (matches.isEmpty()) { if (matches.isEmpty()) {

View File

@@ -24,9 +24,9 @@ public class ChildProjectResource implements RestResource {
new TypeLiteral<RestView<ChildProjectResource>>() {}; new TypeLiteral<RestView<ChildProjectResource>>() {};
private final ProjectResource parent; private final ProjectResource parent;
private final ProjectControl child; private final ProjectState child;
public ChildProjectResource(ProjectResource parent, ProjectControl child) { public ChildProjectResource(ProjectResource parent, ProjectState child) {
this.parent = parent; this.parent = parent;
this.child = child; this.child = child;
} }
@@ -35,12 +35,12 @@ public class ChildProjectResource implements RestResource {
return parent; return parent;
} }
public ProjectControl getChild() { public ProjectState getChild() {
return child; return child;
} }
public boolean isDirectChild() { public boolean isDirectChild() {
ProjectState firstParent = Iterables.getFirst(child.getProjectState().parents(), null); ProjectState firstParent = Iterables.getFirst(child.parents(), null);
return firstParent != null && parent.getNameKey().equals(firstParent.getProject().getNameKey()); return firstParent != null && parent.getNameKey().equals(firstParent.getProject().getNameKey());
} }
} }

View File

@@ -55,7 +55,7 @@ public class ChildProjectsCollection
ProjectResource p = projectsCollection.parse(TopLevelResource.INSTANCE, id); ProjectResource p = projectsCollection.parse(TopLevelResource.INSTANCE, id);
for (ProjectState pp : p.getControl().getProjectState().parents()) { for (ProjectState pp : p.getControl().getProjectState().parents()) {
if (parent.getNameKey().equals(pp.getProject().getNameKey())) { if (parent.getNameKey().equals(pp.getProject().getNameKey())) {
return new ChildProjectResource(parent, p.getControl()); return new ChildProjectResource(parent, p.getProjectState());
} }
} }
throw new ResourceNotFoundException(id); throw new ResourceNotFoundException(id);

View File

@@ -38,7 +38,7 @@ class CommitIncludedIn implements RestReadView<CommitResource> {
public IncludedInInfo apply(CommitResource rsrc) public IncludedInInfo apply(CommitResource rsrc)
throws RestApiException, OrmException, IOException { throws RestApiException, OrmException, IOException {
RevCommit commit = rsrc.getCommit(); RevCommit commit = rsrc.getCommit();
Project.NameKey project = rsrc.getProject().getProject().getNameKey(); Project.NameKey project = rsrc.getProjectState().getProject().getNameKey();
return includedIn.apply(project, commit.getId().getName()); return includedIn.apply(project, commit.getId().getName());
} }
} }

View File

@@ -31,8 +31,8 @@ public class CommitResource implements RestResource {
this.commit = commit; this.commit = commit;
} }
public ProjectControl getProject() { public ProjectState getProjectState() {
return project.getControl(); return project.getProjectState();
} }
public RevCommit getCommit() { public RevCommit getCommit() {

View File

@@ -91,7 +91,6 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
private final Provider<GroupsCollection> groupsCollection; private final Provider<GroupsCollection> groupsCollection;
private final DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners; private final DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners;
private final ProjectJson json; private final ProjectJson json;
private final ProjectControl.GenericFactory projectControlFactory;
private final GitRepositoryManager repoManager; private final GitRepositoryManager repoManager;
private final DynamicSet<NewProjectCreatedListener> createdListeners; private final DynamicSet<NewProjectCreatedListener> createdListeners;
private final ProjectCache projectCache; private final ProjectCache projectCache;
@@ -112,7 +111,6 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
Provider<GroupsCollection> groupsCollection, Provider<GroupsCollection> groupsCollection,
ProjectJson json, ProjectJson json,
DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners, DynamicSet<ProjectCreationValidationListener> projectCreationValidationListeners,
ProjectControl.GenericFactory projectControlFactory,
GitRepositoryManager repoManager, GitRepositoryManager repoManager,
DynamicSet<NewProjectCreatedListener> createdListeners, DynamicSet<NewProjectCreatedListener> createdListeners,
ProjectCache projectCache, ProjectCache projectCache,
@@ -130,7 +128,6 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
this.groupsCollection = groupsCollection; this.groupsCollection = groupsCollection;
this.projectCreationValidationListeners = projectCreationValidationListeners; this.projectCreationValidationListeners = projectCreationValidationListeners;
this.json = json; this.json = json;
this.projectControlFactory = projectControlFactory;
this.repoManager = repoManager; this.repoManager = repoManager;
this.createdListeners = createdListeners; this.createdListeners = createdListeners;
this.projectCache = projectCache; this.projectCache = projectCache;
@@ -163,7 +160,7 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
String parentName = String parentName =
MoreObjects.firstNonNull(Strings.emptyToNull(input.parent), allProjects.get()); MoreObjects.firstNonNull(Strings.emptyToNull(input.parent), allProjects.get());
args.newParent = projectsCollection.get().parse(parentName, false).getControl(); args.newParent = projectsCollection.get().parse(parentName, false).getNameKey();
args.createEmptyCommit = input.createEmptyCommit; args.createEmptyCommit = input.createEmptyCommit;
args.permissionsOnly = input.permissionsOnly; args.permissionsOnly = input.permissionsOnly;
args.projectDescription = Strings.emptyToNull(input.description); args.projectDescription = Strings.emptyToNull(input.description);
@@ -203,25 +200,17 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
} }
} }
Project p = createProject(args); ProjectState projectState = createProject(args);
ProjectControl projectControl;
try {
projectControl = projectControlFactory.controlFor(p.getNameKey(), identifiedUser.get());
} catch (NoSuchProjectException e) {
throw new ResourceNotFoundException(p.getName());
}
if (input.pluginConfigValues != null) { if (input.pluginConfigValues != null) {
ConfigInput in = new ConfigInput(); ConfigInput in = new ConfigInput();
in.pluginConfigValues = input.pluginConfigValues; in.pluginConfigValues = input.pluginConfigValues;
putConfig.get().apply(projectControl, in); putConfig.get().apply(projectState, in);
} }
return Response.created(json.format(projectControl)); return Response.created(json.format(projectState));
} }
private Project createProject(CreateProjectArgs args) private ProjectState createProject(CreateProjectArgs args)
throws BadRequestException, ResourceConflictException, IOException, ConfigInvalidException { throws BadRequestException, ResourceConflictException, IOException, ConfigInvalidException {
final Project.NameKey nameKey = args.getProject(); final Project.NameKey nameKey = args.getProject();
try { try {
@@ -246,7 +235,7 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
fire(nameKey, head); fire(nameKey, head);
return projectCache.get(nameKey).getProject(); return projectCache.get(nameKey);
} }
} catch (RepositoryCaseMismatchException e) { } catch (RepositoryCaseMismatchException e) {
throw new ResourceConflictException( throw new ResourceConflictException(
@@ -281,7 +270,7 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
newProject.setRequireChangeID(args.changeIdRequired); newProject.setRequireChangeID(args.changeIdRequired);
newProject.setMaxObjectSizeLimit(args.maxObjectSizeLimit); newProject.setMaxObjectSizeLimit(args.maxObjectSizeLimit);
if (args.newParent != null) { if (args.newParent != null) {
newProject.setParentName(args.newParent.getProject().getNameKey()); newProject.setParentName(args.newParent);
} }
if (!args.ownerIds.isEmpty()) { if (!args.ownerIds.isEmpty()) {

View File

@@ -24,7 +24,7 @@ public class CreateProjectArgs {
private Project.NameKey projectName; private Project.NameKey projectName;
public List<AccountGroup.UUID> ownerIds; public List<AccountGroup.UUID> ownerIds;
public ProjectControl newParent; public Project.NameKey newParent;
public String projectDescription; public String projectDescription;
public SubmitType submitType; public SubmitType submitType;
public InheritableBoolean contributorAgreements; public InheritableBoolean contributorAgreements;

View File

@@ -32,30 +32,30 @@ public class FileResource implements RestResource {
new TypeLiteral<RestView<FileResource>>() {}; new TypeLiteral<RestView<FileResource>>() {};
public static FileResource create( public static FileResource create(
GitRepositoryManager repoManager, ProjectControl project, ObjectId rev, String path) GitRepositoryManager repoManager, ProjectState projectState, ObjectId rev, String path)
throws ResourceNotFoundException, IOException { throws ResourceNotFoundException, IOException {
try (Repository repo = repoManager.openRepository(project.getProject().getNameKey()); try (Repository repo = repoManager.openRepository(projectState.getProject().getNameKey());
RevWalk rw = new RevWalk(repo)) { RevWalk rw = new RevWalk(repo)) {
RevTree tree = rw.parseTree(rev); RevTree tree = rw.parseTree(rev);
if (TreeWalk.forPath(repo, path, tree) != null) { if (TreeWalk.forPath(repo, path, tree) != null) {
return new FileResource(project, rev, path); return new FileResource(projectState, rev, path);
} }
} }
throw new ResourceNotFoundException(IdString.fromDecoded(path)); throw new ResourceNotFoundException(IdString.fromDecoded(path));
} }
private final ProjectControl project; private final ProjectState projectState;
private final ObjectId rev; private final ObjectId rev;
private final String path; private final String path;
public FileResource(ProjectControl project, ObjectId rev, String path) { public FileResource(ProjectState projectState, ObjectId rev, String path) {
this.project = project; this.projectState = projectState;
this.rev = rev; this.rev = rev;
this.path = path; this.path = path;
} }
public ProjectControl getProject() { public ProjectState getProjectState() {
return project; return projectState;
} }
public ObjectId getRev() { public ObjectId getRev() {

View File

@@ -45,7 +45,7 @@ public class FilesCollection implements ChildCollection<BranchResource, FileReso
public FileResource parse(BranchResource parent, IdString id) public FileResource parse(BranchResource parent, IdString id)
throws ResourceNotFoundException, IOException { throws ResourceNotFoundException, IOException {
return FileResource.create( return FileResource.create(
repoManager, parent.getControl(), ObjectId.fromString(parent.getRevision()), id.get()); repoManager, parent.getProjectState(), ObjectId.fromString(parent.getRevision()), id.get());
} }
@Override @Override

View File

@@ -46,9 +46,9 @@ public class FilesInCommitCollection implements ChildCollection<CommitResource,
public FileResource parse(CommitResource parent, IdString id) public FileResource parse(CommitResource parent, IdString id)
throws ResourceNotFoundException, IOException { throws ResourceNotFoundException, IOException {
if (Patch.isMagic(id.get())) { if (Patch.isMagic(id.get())) {
return new FileResource(parent.getProject(), parent.getCommit(), id.get()); return new FileResource(parent.getProjectState(), parent.getCommit(), id.get());
} }
return FileResource.create(repoManager, parent.getProject(), parent.getCommit(), id.get()); return FileResource.create(repoManager, parent.getProjectState(), parent.getCommit(), id.get());
} }
@Override @Override

View File

@@ -35,7 +35,6 @@ public class GetContent implements RestReadView<FileResource> {
@Override @Override
public BinaryResult apply(FileResource rsrc) public BinaryResult apply(FileResource rsrc)
throws ResourceNotFoundException, BadRequestException, IOException { throws ResourceNotFoundException, BadRequestException, IOException {
return fileContentUtil.getContent( return fileContentUtil.getContent(rsrc.getProjectState(), rsrc.getRev(), rsrc.getPath(), null);
rsrc.getProject().getProjectState(), rsrc.getRev(), rsrc.getPath(), null);
} }
} }

View File

@@ -16,14 +16,12 @@ package com.google.gerrit.server.project;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@Singleton @Singleton
public class GetDescription implements RestReadView<ProjectResource> { public class GetDescription implements RestReadView<ProjectResource> {
@Override @Override
public String apply(ProjectResource resource) { public String apply(ProjectResource rsrc) {
Project project = resource.getControl().getProject(); return Strings.nullToEmpty(rsrc.getProjectState().getProject().getDescription());
return Strings.nullToEmpty(project.getDescription());
} }
} }

View File

@@ -59,7 +59,7 @@ public class GetHead implements RestReadView<ProjectResource> {
} else if (head.isSymbolic()) { } else if (head.isSymbolic()) {
String n = head.getTarget().getName(); String n = head.getTarget().getName();
permissionBackend permissionBackend
.user(rsrc.getControl().getUser()) .user(rsrc.getUser())
.project(rsrc.getNameKey()) .project(rsrc.getNameKey())
.ref(n) .ref(n)
.check(RefPermission.READ); .check(RefPermission.READ);

View File

@@ -31,7 +31,7 @@ class GetParent implements RestReadView<ProjectResource> {
@Override @Override
public String apply(ProjectResource resource) { public String apply(ProjectResource resource) {
Project project = resource.getControl().getProject(); Project project = resource.getProjectState().getProject();
Project.NameKey parentName = project.getParent(allProjectsName); Project.NameKey parentName = project.getParent(allProjectsName);
return parentName != null ? parentName.get() : ""; return parentName != null ? parentName.get() : "";
} }

View File

@@ -31,6 +31,6 @@ class GetProject implements RestReadView<ProjectResource> {
@Override @Override
public ProjectInfo apply(ProjectResource rsrc) { public ProjectInfo apply(ProjectResource rsrc) {
return json.format(rsrc.getControl()); return json.format(rsrc.getProjectState());
} }
} }

View File

@@ -71,13 +71,13 @@ class ListDashboards implements RestReadView<ProjectResource> {
throws ResourceNotFoundException, IOException, PermissionBackendException { throws ResourceNotFoundException, IOException, PermissionBackendException {
String project = rsrc.getName(); String project = rsrc.getName();
if (!inherited) { if (!inherited) {
return scan(rsrc.getControl(), project, true); return scan(rsrc.getProjectState(), project, true);
} }
List<List<DashboardInfo>> all = new ArrayList<>(); List<List<DashboardInfo>> all = new ArrayList<>();
boolean setDefault = true; boolean setDefault = true;
for (ProjectState ps : tree(rsrc)) { for (ProjectState ps : tree(rsrc)) {
List<DashboardInfo> list = scan(ps.controlFor(user.get()), project, setDefault); List<DashboardInfo> list = scan(ps, project, setDefault);
for (DashboardInfo d : list) { for (DashboardInfo d : list) {
if (d.isDefault != null && Boolean.TRUE.equals(d.isDefault)) { if (d.isDefault != null && Boolean.TRUE.equals(d.isDefault)) {
setDefault = false; setDefault = false;
@@ -100,17 +100,17 @@ class ListDashboards implements RestReadView<ProjectResource> {
return tree.values(); return tree.values();
} }
private List<DashboardInfo> scan(ProjectControl ctl, String project, boolean setDefault) private List<DashboardInfo> scan(ProjectState state, String project, boolean setDefault)
throws ResourceNotFoundException, IOException, PermissionBackendException { throws ResourceNotFoundException, IOException, PermissionBackendException {
Project.NameKey projectName = ctl.getProject().getNameKey(); Project.NameKey projectName = state.getProject().getNameKey();
PermissionBackend.ForProject perm = PermissionBackend.ForProject perm =
permissionBackend.user(user).project(ctl.getProject().getNameKey()); permissionBackend.user(user).project(state.getProject().getNameKey());
try (Repository git = gitManager.openRepository(projectName); try (Repository git = gitManager.openRepository(projectName);
RevWalk rw = new RevWalk(git)) { RevWalk rw = new RevWalk(git)) {
List<DashboardInfo> all = new ArrayList<>(); List<DashboardInfo> all = new ArrayList<>();
for (Ref ref : git.getRefDatabase().getRefs(REFS_DASHBOARDS).values()) { for (Ref ref : git.getRefDatabase().getRefs(REFS_DASHBOARDS).values()) {
if (perm.ref(ref.getName()).test(RefPermission.READ)) { if (perm.ref(ref.getName()).test(RefPermission.READ)) {
all.addAll(scanDashboards(ctl.getProject(), git, rw, ref, project, setDefault)); all.addAll(scanDashboards(state.getProject(), git, rw, ref, project, setDefault));
} }
} }
return all; return all;

View File

@@ -122,12 +122,11 @@ public class ListTags implements RestReadView<ProjectResource> {
PermissionBackend.ForProject perm = permissionBackend.user(user).project(resource.getNameKey()); PermissionBackend.ForProject perm = permissionBackend.user(user).project(resource.getNameKey());
try (Repository repo = getRepository(resource.getNameKey()); try (Repository repo = getRepository(resource.getNameKey());
RevWalk rw = new RevWalk(repo)) { RevWalk rw = new RevWalk(repo)) {
ProjectControl pctl = resource.getControl();
Map<String, Ref> all = Map<String, Ref> all =
visibleTags(pctl, repo, repo.getRefDatabase().getRefs(Constants.R_TAGS)); visibleTags(
resource.getProjectState(), repo, repo.getRefDatabase().getRefs(Constants.R_TAGS));
for (Ref ref : all.values()) { for (Ref ref : all.values()) {
tags.add( tags.add(createTagInfo(perm.ref(ref.getName()), ref, rw, resource.getNameKey(), links));
createTagInfo(perm.ref(ref.getName()), ref, rw, pctl.getProject().getNameKey(), links));
} }
} }
@@ -157,16 +156,17 @@ public class ListTags implements RestReadView<ProjectResource> {
tagName = Constants.R_TAGS + tagName; tagName = Constants.R_TAGS + tagName;
} }
Ref ref = repo.getRefDatabase().exactRef(tagName); Ref ref = repo.getRefDatabase().exactRef(tagName);
ProjectControl pctl = resource.getControl(); if (ref != null
if (ref != null && !visibleTags(pctl, repo, ImmutableMap.of(ref.getName(), ref)).isEmpty()) { && !visibleTags(resource.getProjectState(), repo, ImmutableMap.of(ref.getName(), ref))
.isEmpty()) {
return createTagInfo( return createTagInfo(
permissionBackend permissionBackend
.user(pctl.getUser()) .user(resource.getUser())
.project(resource.getNameKey()) .project(resource.getNameKey())
.ref(ref.getName()), .ref(ref.getName()),
ref, ref,
rw, rw,
pctl.getProject().getNameKey(), resource.getNameKey(),
links); links);
} }
} }
@@ -213,11 +213,7 @@ public class ListTags implements RestReadView<ProjectResource> {
} }
} }
private Map<String, Ref> visibleTags( private Map<String, Ref> visibleTags(ProjectState state, Repository repo, Map<String, Ref> tags) {
ProjectControl pctl, Repository repo, Map<String, Ref> tags) { return refFilterFactory.create(state, repo).setShowMetadata(false).filter(tags, true);
return refFilterFactory
.create(pctl.getProjectState(), repo)
.setShowMetadata(false)
.filter(tags, true);
} }
} }

View File

@@ -42,10 +42,10 @@ public class ProjectJson {
this.webLinks = webLinks; this.webLinks = webLinks;
} }
public ProjectInfo format(ProjectControl ctl) { public ProjectInfo format(ProjectState state) {
ProjectInfo info = format(ctl.getProject()); ProjectInfo info = format(state.getProject());
info.labels = new HashMap<>(); info.labels = new HashMap<>();
for (LabelType t : ctl.getLabelTypes().getLabelTypes()) { for (LabelType t : state.getLabelTypes().getLabelTypes()) {
LabelTypeInfo labelInfo = new LabelTypeInfo(); LabelTypeInfo labelInfo = new LabelTypeInfo();
labelInfo.values = labelInfo.values =
t.getValues() t.getValues()

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.project;
import com.google.gerrit.extensions.restapi.RestResource; import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView; import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
public class ProjectResource implements RestResource { public class ProjectResource implements RestResource {
@@ -45,6 +46,10 @@ public class ProjectResource implements RestResource {
return control.getProjectState(); return control.getProjectState();
} }
public CurrentUser getUser() {
return getControl().getUser();
}
public ProjectControl getControl() { public ProjectControl getControl() {
return control; return control;
} }

View File

@@ -100,12 +100,12 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
if (!rsrc.getControl().isOwner()) { if (!rsrc.getControl().isOwner()) {
throw new AuthException("restricted to project owner"); throw new AuthException("restricted to project owner");
} }
return apply(rsrc.getControl(), input); return apply(rsrc.getProjectState(), input);
} }
public ConfigInfo apply(ProjectControl ctrl, ConfigInput input) public ConfigInfo apply(ProjectState projectState, ConfigInput input)
throws ResourceNotFoundException, BadRequestException, ResourceConflictException { throws ResourceNotFoundException, BadRequestException, ResourceConflictException {
Project.NameKey projectName = ctrl.getProject().getNameKey(); Project.NameKey projectName = projectState.getProject().getNameKey();
if (input == null) { if (input == null) {
throw new BadRequestException("config is required"); throw new BadRequestException("config is required");
} }
@@ -172,7 +172,7 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
} }
if (input.pluginConfigValues != null) { if (input.pluginConfigValues != null) {
setPluginConfigValues(ctrl.getProjectState(), projectConfig, input.pluginConfigValues); setPluginConfigValues(projectState, projectConfig, input.pluginConfigValues);
} }
md.setMessage("Modified project settings\n"); md.setMessage("Modified project settings\n");

View File

@@ -190,7 +190,8 @@ public class SetAccess implements RestModifyView<ProjectResource, ProjectAccessI
setParent setParent
.get() .get()
.validateParentUpdate( .validateParentUpdate(
projectControl, projectControl.getProject().getNameKey(),
projectControl.getUser().asIdentifiedUser(),
MoreObjects.firstNonNull(newParentProjectName, allProjects).get(), MoreObjects.firstNonNull(newParentProjectName, allProjects).get(),
true); true);
} catch (UnprocessableEntityException e) { } catch (UnprocessableEntityException e) {

View File

@@ -74,10 +74,11 @@ public class SetParent implements RestModifyView<ProjectResource, Input> {
public String apply(ProjectResource rsrc, Input input, boolean checkIfAdmin) public String apply(ProjectResource rsrc, Input input, boolean checkIfAdmin)
throws AuthException, ResourceConflictException, ResourceNotFoundException, throws AuthException, ResourceConflictException, ResourceNotFoundException,
UnprocessableEntityException, IOException, PermissionBackendException { UnprocessableEntityException, IOException, PermissionBackendException {
ProjectControl ctl = rsrc.getControl(); IdentifiedUser user = rsrc.getUser().asIdentifiedUser();
String parentName = String parentName =
MoreObjects.firstNonNull(Strings.emptyToNull(input.parent), allProjects.get()); MoreObjects.firstNonNull(Strings.emptyToNull(input.parent), allProjects.get());
validateParentUpdate(ctl, parentName, checkIfAdmin); validateParentUpdate(
rsrc.getProjectState().getProject().getNameKey(), user, parentName, checkIfAdmin);
try (MetaDataUpdate md = updateFactory.create(rsrc.getNameKey())) { try (MetaDataUpdate md = updateFactory.create(rsrc.getNameKey())) {
ProjectConfig config = ProjectConfig.read(md); ProjectConfig config = ProjectConfig.read(md);
Project project = config.getProject(); Project project = config.getProject();
@@ -89,10 +90,10 @@ public class SetParent implements RestModifyView<ProjectResource, Input> {
} else if (!msg.endsWith("\n")) { } else if (!msg.endsWith("\n")) {
msg += "\n"; msg += "\n";
} }
md.setAuthor(ctl.getUser().asIdentifiedUser()); md.setAuthor(user);
md.setMessage(msg); md.setMessage(msg);
config.commit(md); config.commit(md);
cache.evict(ctl.getProject()); cache.evict(rsrc.getProjectState().getProject());
Project.NameKey parent = project.getParent(allProjects); Project.NameKey parent = project.getParent(allProjects);
checkNotNull(parent); checkNotNull(parent);
@@ -105,15 +106,15 @@ public class SetParent implements RestModifyView<ProjectResource, Input> {
} }
} }
public void validateParentUpdate(ProjectControl ctl, String newParent, boolean checkIfAdmin) public void validateParentUpdate(
Project.NameKey project, IdentifiedUser user, String newParent, boolean checkIfAdmin)
throws AuthException, ResourceConflictException, UnprocessableEntityException, throws AuthException, ResourceConflictException, UnprocessableEntityException,
PermissionBackendException { PermissionBackendException {
IdentifiedUser user = ctl.getUser().asIdentifiedUser();
if (checkIfAdmin) { if (checkIfAdmin) {
permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER); permissionBackend.user(user).check(GlobalPermission.ADMINISTRATE_SERVER);
} }
if (ctl.getProject().getNameKey().equals(allProjects)) { if (project.equals(allProjects)) {
throw new ResourceConflictException("cannot set parent of " + allProjects.get()); throw new ResourceConflictException("cannot set parent of " + allProjects.get());
} }
@@ -127,14 +128,11 @@ public class SetParent implements RestModifyView<ProjectResource, Input> {
if (Iterables.tryFind( if (Iterables.tryFind(
parent.tree(), parent.tree(),
p -> { p -> {
return p.getProject().getNameKey().equals(ctl.getProject().getNameKey()); return p.getProject().getNameKey().equals(project);
}) })
.isPresent()) { .isPresent()) {
throw new ResourceConflictException( throw new ResourceConflictException(
"cycle exists between " "cycle exists between " + project.get() + " and " + parent.getProject().getName());
+ ctl.getProject().getName()
+ " and "
+ parent.getProject().getName());
} }
} }
} }