Delegate RefRight category filtering to ProjectState
Allow the ProjectState class to implement the filtering of each RefRight instance by category, rather than repeating the logic in the classes that use them. This opens the door for the state to cache the filtered collections at some later point in time, and may help accelerate common action category lookups like for READ or Push Branch. Change-Id: I6ddddd031afe59fc04c4226a01d656cca14277d0 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -130,20 +130,18 @@ final class PatchSetPublishDetailFactory extends Handler<PatchSetPublishDetail>
|
|||||||
final ProjectState pe = projectCache.get(change.getProject());
|
final ProjectState pe = projectCache.get(change.getProject());
|
||||||
for (ApprovalCategory.Id category : approvalTypes.getApprovalCategories()) {
|
for (ApprovalCategory.Id category : approvalTypes.getApprovalCategories()) {
|
||||||
List<RefRight> categoryRights = new ArrayList<RefRight>();
|
List<RefRight> categoryRights = new ArrayList<RefRight>();
|
||||||
categoryRights.addAll(filterMatching(pe.getLocalRights(), category));
|
categoryRights.addAll(filterMatching(pe.getLocalRights(category)));
|
||||||
categoryRights.addAll(filterMatching(pe.getInheritedRights(), category));
|
categoryRights.addAll(filterMatching(pe.getInheritedRights(category)));
|
||||||
Collections.sort(categoryRights, RefRight.REF_PATTERN_ORDER);
|
Collections.sort(categoryRights, RefRight.REF_PATTERN_ORDER);
|
||||||
categoryRights = RefControl.filterMostSpecific(categoryRights);
|
categoryRights = RefControl.filterMostSpecific(categoryRights);
|
||||||
computeAllowed(am, categoryRights, category);
|
computeAllowed(am, categoryRights, category);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RefRight> filterMatching(Collection<RefRight> rights,
|
private List<RefRight> filterMatching(Collection<RefRight> rights) {
|
||||||
ApprovalCategory.Id category) {
|
|
||||||
List<RefRight> result = new ArrayList<RefRight>();
|
List<RefRight> result = new ArrayList<RefRight>();
|
||||||
for (RefRight right : rights) {
|
for (RefRight right : rights) {
|
||||||
if (RefControl.matches(change.getDest().get(), right.getRefPattern())
|
if (RefControl.matches(change.getDest().get(), right.getRefPattern())) {
|
||||||
&& category.equals(right.getApprovalCategoryId())) {
|
|
||||||
result.add(right);
|
result.add(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ import com.google.gerrit.server.config.WildProjectName;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/** Cached information on a project. */
|
/** Cached information on a project. */
|
||||||
@@ -80,6 +82,16 @@ public class ProjectState {
|
|||||||
return localRights;
|
return localRights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the rights that pertain only to this project.
|
||||||
|
*
|
||||||
|
* @param action the category requested.
|
||||||
|
* @return immutable collection of rights for the requested category.
|
||||||
|
*/
|
||||||
|
public Collection<RefRight> getLocalRights(ApprovalCategory.Id action) {
|
||||||
|
return filter(getLocalRights(), action);
|
||||||
|
}
|
||||||
|
|
||||||
/** Get the rights this project inherits from the wild project. */
|
/** Get the rights this project inherits from the wild project. */
|
||||||
public Collection<RefRight> getInheritedRights() {
|
public Collection<RefRight> getInheritedRights() {
|
||||||
if (isSpecialWildProject()) {
|
if (isSpecialWildProject()) {
|
||||||
@@ -88,6 +100,19 @@ public class ProjectState {
|
|||||||
return inheritedRights.get();
|
return inheritedRights.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the rights this project inherits from the wild project.
|
||||||
|
*
|
||||||
|
* @param action the category requested.
|
||||||
|
* @return immutable collection of rights for the requested category.
|
||||||
|
*/
|
||||||
|
public Collection<RefRight> getInheritedRights(ApprovalCategory.Id action) {
|
||||||
|
if (action.canInheritFromWildProject()) {
|
||||||
|
return filter(getInheritedRights(), action);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/** Is this the special wild project which manages inherited rights? */
|
/** Is this the special wild project which manages inherited rights? */
|
||||||
public boolean isSpecialWildProject() {
|
public boolean isSpecialWildProject() {
|
||||||
return project.getNameKey().equals(wildProject);
|
return project.getNameKey().equals(wildProject);
|
||||||
@@ -104,4 +129,21 @@ public class ProjectState {
|
|||||||
public ProjectControl controlFor(final CurrentUser user) {
|
public ProjectControl controlFor(final CurrentUser user) {
|
||||||
return new ProjectControl(user, this);
|
return new ProjectControl(user, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Collection<RefRight> filter(Collection<RefRight> all,
|
||||||
|
ApprovalCategory.Id actionId) {
|
||||||
|
if (all.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
final Collection<RefRight> mine = new ArrayList<RefRight>(all.size());
|
||||||
|
for (final RefRight right : all) {
|
||||||
|
if (right.getApprovalCategoryId().equals(actionId)) {
|
||||||
|
mine.add(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mine.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableCollection(mine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -273,16 +273,11 @@ public class RefControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<RefRight> getLocalRights(ApprovalCategory.Id actionId) {
|
private List<RefRight> getLocalRights(ApprovalCategory.Id actionId) {
|
||||||
return filter(projectControl.getProjectState().getLocalRights(), actionId);
|
return filter(getProjectState().getLocalRights(actionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RefRight> getInheritedRights(ApprovalCategory.Id actionId) {
|
private List<RefRight> getInheritedRights(ApprovalCategory.Id actionId) {
|
||||||
if (actionId.canInheritFromWildProject()) {
|
return filter(getProjectState().getInheritedRights(actionId));
|
||||||
return filter(projectControl.getProjectState().getInheritedRights(),
|
|
||||||
actionId);
|
|
||||||
} else {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RefRight> getAllRights(final ApprovalCategory.Id id) {
|
public List<RefRight> getAllRights(final ApprovalCategory.Id id) {
|
||||||
@@ -293,18 +288,20 @@ public class RefControl {
|
|||||||
return Collections.unmodifiableList(RefControl.filterMostSpecific(l));
|
return Collections.unmodifiableList(RefControl.filterMostSpecific(l));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RefRight> filter(Collection<RefRight> all,
|
private List<RefRight> filter(Collection<RefRight> all) {
|
||||||
ApprovalCategory.Id actionId) {
|
|
||||||
List<RefRight> mine = new ArrayList<RefRight>(all.size());
|
List<RefRight> mine = new ArrayList<RefRight>(all.size());
|
||||||
for (RefRight right : all) {
|
for (RefRight right : all) {
|
||||||
if (matches(getRefName(), right.getRefPattern())
|
if (matches(getRefName(), right.getRefPattern())) {
|
||||||
&& right.getApprovalCategoryId().equals(actionId)) {
|
|
||||||
mine.add(right);
|
mine.add(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mine;
|
return mine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ProjectState getProjectState() {
|
||||||
|
return projectControl.getProjectState();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean matches(String refName, String refPattern) {
|
public static boolean matches(String refName, String refPattern) {
|
||||||
if (refPattern.endsWith("/*")) {
|
if (refPattern.endsWith("/*")) {
|
||||||
String prefix = refPattern.substring(0, refPattern.length() - 1);
|
String prefix = refPattern.substring(0, refPattern.length() - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user