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
.get()
.validateParentUpdate(
projectControl,
projectControl.getProject().getNameKey(),
projectControl.getUser().asIdentifiedUser(),
MoreObjects.firstNonNull(parentProjectName, allProjects).get(),
checkIfOwner);
} 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.index.change.ChangeField;
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.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.InternalChangeQuery;
@ -108,7 +108,7 @@ public class ReviewerRecommender {
public List<Account.Id> suggestReviewers(
ChangeNotes changeNotes,
SuggestReviewers suggestReviewers,
ProjectControl projectControl,
ProjectState projectState,
List<Account.Id> candidateList)
throws OrmException, IOException, ConfigInvalidException {
String query = suggestReviewers.getQuery();
@ -118,7 +118,7 @@ public class ReviewerRecommender {
if (Strings.isNullOrEmpty(query)) {
reviewerScores = baseRankingForEmptyQuery(baseWeight);
} 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
@ -135,7 +135,7 @@ public class ReviewerRecommender {
.getProvider()
.get()
.suggestReviewers(
projectControl.getProject().getNameKey(),
projectState.getProject().getNameKey(),
changeNotes.getChangeId(),
query,
reviewerScores.keySet()));
@ -227,7 +227,7 @@ public class ReviewerRecommender {
}
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 {
// Get each reviewer's activity based on number of applied labels
// (weighted 10d), number of comments (weighted 0.5d) and number of owned
@ -240,11 +240,11 @@ public class ReviewerRecommender {
for (Account.Id id : candidates) {
try {
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
// 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());
for (LabelType type : labelTypes) {
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.notedb.ChangeNotes;
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.AccountQueryBuilder;
import com.google.gerrit.server.query.account.AccountQueryProcessor;
@ -145,7 +145,7 @@ public class ReviewersUtil {
public List<SuggestedReviewerInfo> suggestReviewers(
ChangeNotes changeNotes,
SuggestReviewers suggestReviewers,
ProjectControl projectControl,
ProjectState projectState,
VisibilityControl visibilityControl,
boolean excludeGroups)
throws IOException, OrmException, ConfigInvalidException {
@ -162,7 +162,7 @@ public class ReviewersUtil {
}
List<Account.Id> sortedRecommendations =
recommendAccounts(changeNotes, suggestReviewers, projectControl, candidateList);
recommendAccounts(changeNotes, suggestReviewers, projectState, candidateList);
// Filter accounts by visibility and enforce limit
List<Account.Id> filteredRecommendations = new ArrayList<>();
@ -183,10 +183,7 @@ public class ReviewersUtil {
// important.
suggestedReviewer.addAll(
suggestAccountGroups(
suggestReviewers,
projectControl,
visibilityControl,
limit - suggestedReviewer.size()));
suggestReviewers, projectState, visibilityControl, limit - suggestedReviewer.size()));
}
if (suggestedReviewer.size() <= limit) {
@ -215,12 +212,12 @@ public class ReviewersUtil {
private List<Account.Id> recommendAccounts(
ChangeNotes changeNotes,
SuggestReviewers suggestReviewers,
ProjectControl projectControl,
ProjectState projectState,
List<Account.Id> candidateList)
throws OrmException, IOException, ConfigInvalidException {
try (Timer0.Context ctx = metrics.recommendAccountsLatency.start()) {
return reviewerRecommender.suggestReviewers(
changeNotes, suggestReviewers, projectControl, candidateList);
changeNotes, suggestReviewers, projectState, candidateList);
}
}
@ -247,16 +244,16 @@ public class ReviewersUtil {
private List<SuggestedReviewerInfo> suggestAccountGroups(
SuggestReviewers suggestReviewers,
ProjectControl projectControl,
ProjectState projectState,
VisibilityControl visibilityControl,
int limit)
throws OrmException, IOException {
try (Timer0.Context ctx = metrics.queryGroupsLatency.start()) {
List<SuggestedReviewerInfo> groups = new ArrayList<>();
for (GroupReference g : suggestAccountGroups(suggestReviewers, projectControl)) {
for (GroupReference g : suggestAccountGroups(suggestReviewers, projectState)) {
GroupAsReviewer result =
suggestGroupAsReviewer(
suggestReviewers, projectControl.getProject(), g, visibilityControl);
suggestReviewers, projectState.getProject(), g, visibilityControl);
if (result.allowed || result.allowedWithConfirmation) {
GroupBaseInfo info = new GroupBaseInfo();
info.id = Url.encode(g.getUUID().get());
@ -278,10 +275,11 @@ public class ReviewersUtil {
}
private List<GroupReference> suggestAccountGroups(
SuggestReviewers suggestReviewers, ProjectControl ctl) {
SuggestReviewers suggestReviewers, ProjectState projectState) {
return Lists.newArrayList(
Iterables.limit(
groupBackend.suggest(suggestReviewers.getQuery(), ctl), suggestReviewers.getLimit()));
groupBackend.suggest(suggestReviewers.getQuery(), projectState),
suggestReviewers.getLimit()));
}
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.reviewdb.client.AccountGroup;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import java.util.Collection;
/** 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);
/** @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. */
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.gerrit.common.Nullable;
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.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.
*
* @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.
*
* @param groupBackend the group backend
@ -56,7 +56,7 @@ public class GroupBackends {
*/
@Nullable
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);
if (refs.size() == 1) {
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.
*
* @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.
*
* @param groupBackend the group backend
@ -94,7 +94,7 @@ public class GroupBackends {
*/
@Nullable
public static GroupReference findExactSuggestion(
GroupBackend groupBackend, String name, ProjectControl project) {
GroupBackend groupBackend, String name, ProjectState project) {
Collection<GroupReference> refs = groupBackend.suggest(name, project);
for (GroupReference ref : refs) {
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.reviewdb.client.AccountGroup;
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.Singleton;
import java.util.Collection;
@ -64,7 +64,7 @@ public class InternalGroupBackend implements GroupBackend {
}
@Override
public Collection<GroupReference> suggest(String name, ProjectControl project) {
public Collection<GroupReference> suggest(String name, ProjectState project) {
return groupCache
.all()
.stream()

View File

@ -31,7 +31,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.StartupCheck;
import com.google.gerrit.server.StartupException;
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.Singleton;
import java.util.Collection;
@ -87,7 +87,7 @@ public class UniversalGroupBackend implements GroupBackend {
}
@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);
for (GroupBackend g : backends) {
groups.addAll(g.suggest(name, project));

View File

@ -277,7 +277,7 @@ public class ProjectApiImpl implements ProjectApi {
if (project == null) {
throw new ResourceNotFoundException(name);
}
return projectJson.format(project.getControl());
return projectJson.format(project.getProjectState());
}
@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.auth.ldap.Helper.LdapSchema;
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.Provider;
import com.google.inject.name.Named;
@ -158,7 +158,7 @@ public class LdapGroupBackend implements GroupBackend {
}
@Override
public Collection<GroupReference> suggest(String name, ProjectControl project) {
public Collection<GroupReference> suggest(String name, ProjectState project) {
AccountGroup.UUID uuid = new AccountGroup.UUID(name);
if (isLdapUUID(uuid)) {
GroupDescription.Basic g = get(uuid);

View File

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

View File

@ -194,7 +194,7 @@ public class CreateChange
ObjectId parentCommit;
List<String> groups;
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) {
throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
}
@ -253,7 +253,7 @@ public class CreateChange
}
c =
newMergeCommit(
git, oi, rw, rsrc.getControl(), mergeTip, input.merge, author, commitMessage);
git, oi, rw, rsrc.getProjectState(), mergeTip, input.merge, author, commitMessage);
} else {
// create an empty commit
c = newCommit(oi, rw, author, mergeTip, commitMessage);
@ -310,7 +310,7 @@ public class CreateChange
Repository repo,
ObjectInserter oi,
RevWalk rw,
ProjectControl projectControl,
ProjectState projectState,
RevCommit mergeTip,
MergeInput merge,
PersonIdent authorIdent,
@ -320,13 +320,12 @@ public class CreateChange
throw new BadRequestException("merge.source must be non-empty");
}
ProjectState state = projectControl.getProjectState();
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);
}
MergeUtil mergeUtil = mergeUtilFactory.create(state);
MergeUtil mergeUtil = mergeUtilFactory.create(projectState);
// default merge strategy from project settings
String mergeStrategy =
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.project.CommitsCollection;
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.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper;
@ -79,6 +79,7 @@ public class CreateMergePatchSet
private final PatchSetUtil psUtil;
private final MergeUtil.Factory mergeUtilFactory;
private final PatchSetInserter.Factory patchSetInserterFactory;
private final ProjectCache projectCache;
@Inject
CreateMergePatchSet(
@ -91,7 +92,8 @@ public class CreateMergePatchSet
PatchSetUtil psUtil,
MergeUtil.Factory mergeUtilFactory,
RetryHelper retryHelper,
PatchSetInserter.Factory patchSetInserterFactory) {
PatchSetInserter.Factory patchSetInserterFactory,
ProjectCache projectCache) {
super(retryHelper);
this.db = db;
this.gitManager = gitManager;
@ -102,6 +104,7 @@ public class CreateMergePatchSet
this.psUtil = psUtil;
this.mergeUtilFactory = mergeUtilFactory;
this.patchSetInserterFactory = patchSetInserterFactory;
this.projectCache = projectCache;
}
@Override
@ -117,8 +120,7 @@ public class CreateMergePatchSet
}
PatchSet ps = psUtil.current(db.get(), rsrc.getNotes());
ProjectControl projectControl = rsrc.getControl().getProjectControl();
ProjectState state = projectControl.getProjectState();
ProjectState projectState = projectCache.checkedGet(rsrc.getProject());
Change change = rsrc.getChange();
Project.NameKey project = change.getProject();
Branch.NameKey dest = change.getDest();
@ -128,7 +130,7 @@ public class CreateMergePatchSet
RevWalk rw = new RevWalk(reader)) {
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
if (!commits.canRead(state, git, sourceCommit)) {
if (!commits.canRead(projectState, git, sourceCommit)) {
throw new ResourceNotFoundException(
"cannot find source commit: " + merge.source + " to merge.");
}
@ -140,7 +142,7 @@ public class CreateMergePatchSet
RevCommit newCommit =
createMergeCommit(
in,
projectControl,
projectState,
dest,
git,
oi,
@ -172,7 +174,7 @@ public class CreateMergePatchSet
private RevCommit createMergeCommit(
MergePatchSetInput in,
ProjectControl projectControl,
ProjectState projectState,
Branch.NameKey dest,
Repository git,
ObjectInserter oi,
@ -210,7 +212,7 @@ public class CreateMergePatchSet
String mergeStrategy =
MoreObjects.firstNonNull(
Strings.emptyToNull(in.merge.strategy),
mergeUtilFactory.create(projectControl.getProjectState()).mergeStrategyName());
mergeUtilFactory.create(projectState).mergeStrategyName());
return MergeUtil.createMergeCommit(
oi, git.getConfig(), mergeTip, sourceCommit, mergeStrategy, author, commitMsg, rw);

View File

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

View File

@ -302,11 +302,12 @@ public class ListGroups implements RestReadView<TopLevelResource> {
throw new BadRequestException(
"You should only have no more than one --project and -n with --suggest");
}
List<GroupReference> groupRefs =
Lists.newArrayList(
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)));
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.ListGroupMembership;
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.Singleton;
import java.util.ArrayList;
@ -156,7 +156,7 @@ public class SystemGroupBackend extends AbstractGroupBackend {
}
@Override
public Collection<GroupReference> suggest(String name, ProjectControl project) {
public Collection<GroupReference> suggest(String name, ProjectState project) {
String nameLC = name.toLowerCase(Locale.US);
SortedMap<String, GroupReference> matches = names.tailMap(nameLC);
if (matches.isEmpty()) {

View File

@ -24,9 +24,9 @@ public class ChildProjectResource implements RestResource {
new TypeLiteral<RestView<ChildProjectResource>>() {};
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.child = child;
}
@ -35,12 +35,12 @@ public class ChildProjectResource implements RestResource {
return parent;
}
public ProjectControl getChild() {
public ProjectState getChild() {
return child;
}
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());
}
}

View File

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

View File

@ -38,7 +38,7 @@ class CommitIncludedIn implements RestReadView<CommitResource> {
public IncludedInInfo apply(CommitResource rsrc)
throws RestApiException, OrmException, IOException {
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());
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,9 +46,9 @@ public class FilesInCommitCollection implements ChildCollection<CommitResource,
public FileResource parse(CommitResource parent, IdString id)
throws ResourceNotFoundException, IOException {
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

View File

@ -35,7 +35,6 @@ public class GetContent implements RestReadView<FileResource> {
@Override
public BinaryResult apply(FileResource rsrc)
throws ResourceNotFoundException, BadRequestException, IOException {
return fileContentUtil.getContent(
rsrc.getProject().getProjectState(), rsrc.getRev(), rsrc.getPath(), null);
return fileContentUtil.getContent(rsrc.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.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Singleton;
@Singleton
public class GetDescription implements RestReadView<ProjectResource> {
@Override
public String apply(ProjectResource resource) {
Project project = resource.getControl().getProject();
return Strings.nullToEmpty(project.getDescription());
public String apply(ProjectResource rsrc) {
return Strings.nullToEmpty(rsrc.getProjectState().getProject().getDescription());
}
}

View File

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

View File

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

View File

@ -31,6 +31,6 @@ class GetProject implements RestReadView<ProjectResource> {
@Override
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 {
String project = rsrc.getName();
if (!inherited) {
return scan(rsrc.getControl(), project, true);
return scan(rsrc.getProjectState(), project, true);
}
List<List<DashboardInfo>> all = new ArrayList<>();
boolean setDefault = true;
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) {
if (d.isDefault != null && Boolean.TRUE.equals(d.isDefault)) {
setDefault = false;
@ -100,17 +100,17 @@ class ListDashboards implements RestReadView<ProjectResource> {
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 {
Project.NameKey projectName = ctl.getProject().getNameKey();
Project.NameKey projectName = state.getProject().getNameKey();
PermissionBackend.ForProject perm =
permissionBackend.user(user).project(ctl.getProject().getNameKey());
permissionBackend.user(user).project(state.getProject().getNameKey());
try (Repository git = gitManager.openRepository(projectName);
RevWalk rw = new RevWalk(git)) {
List<DashboardInfo> all = new ArrayList<>();
for (Ref ref : git.getRefDatabase().getRefs(REFS_DASHBOARDS).values()) {
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;

View File

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

View File

@ -42,10 +42,10 @@ public class ProjectJson {
this.webLinks = webLinks;
}
public ProjectInfo format(ProjectControl ctl) {
ProjectInfo info = format(ctl.getProject());
public ProjectInfo format(ProjectState state) {
ProjectInfo info = format(state.getProject());
info.labels = new HashMap<>();
for (LabelType t : ctl.getLabelTypes().getLabelTypes()) {
for (LabelType t : state.getLabelTypes().getLabelTypes()) {
LabelTypeInfo labelInfo = new LabelTypeInfo();
labelInfo.values =
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.RestView;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.inject.TypeLiteral;
public class ProjectResource implements RestResource {
@ -45,6 +46,10 @@ public class ProjectResource implements RestResource {
return control.getProjectState();
}
public CurrentUser getUser() {
return getControl().getUser();
}
public ProjectControl getControl() {
return control;
}

View File

@ -100,12 +100,12 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
if (!rsrc.getControl().isOwner()) {
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 {
Project.NameKey projectName = ctrl.getProject().getNameKey();
Project.NameKey projectName = projectState.getProject().getNameKey();
if (input == null) {
throw new BadRequestException("config is required");
}
@ -172,7 +172,7 @@ public class PutConfig implements RestModifyView<ProjectResource, ConfigInput> {
}
if (input.pluginConfigValues != null) {
setPluginConfigValues(ctrl.getProjectState(), projectConfig, input.pluginConfigValues);
setPluginConfigValues(projectState, projectConfig, input.pluginConfigValues);
}
md.setMessage("Modified project settings\n");

View File

@ -190,7 +190,8 @@ public class SetAccess implements RestModifyView<ProjectResource, ProjectAccessI
setParent
.get()
.validateParentUpdate(
projectControl,
projectControl.getProject().getNameKey(),
projectControl.getUser().asIdentifiedUser(),
MoreObjects.firstNonNull(newParentProjectName, allProjects).get(),
true);
} 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)
throws AuthException, ResourceConflictException, ResourceNotFoundException,
UnprocessableEntityException, IOException, PermissionBackendException {
ProjectControl ctl = rsrc.getControl();
IdentifiedUser user = rsrc.getUser().asIdentifiedUser();
String parentName =
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())) {
ProjectConfig config = ProjectConfig.read(md);
Project project = config.getProject();
@ -89,10 +90,10 @@ public class SetParent implements RestModifyView<ProjectResource, Input> {
} else if (!msg.endsWith("\n")) {
msg += "\n";
}
md.setAuthor(ctl.getUser().asIdentifiedUser());
md.setAuthor(user);
md.setMessage(msg);
config.commit(md);
cache.evict(ctl.getProject());
cache.evict(rsrc.getProjectState().getProject());
Project.NameKey parent = project.getParent(allProjects);
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,
PermissionBackendException {
IdentifiedUser user = ctl.getUser().asIdentifiedUser();
if (checkIfAdmin) {
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());
}
@ -127,14 +128,11 @@ public class SetParent implements RestModifyView<ProjectResource, Input> {
if (Iterables.tryFind(
parent.tree(),
p -> {
return p.getProject().getNameKey().equals(ctl.getProject().getNameKey());
return p.getProject().getNameKey().equals(project);
})
.isPresent()) {
throw new ResourceConflictException(
"cycle exists between "
+ ctl.getProject().getName()
+ " and "
+ parent.getProject().getName());
"cycle exists between " + project.get() + " and " + parent.getProject().getName());
}
}
}

@ -1 +1 @@
Subproject commit 50d04dd09a747868cd2f2707d1aac3d9b2a2d630
Subproject commit 262ba951fbb24af6094be40637fbd261d5e08218