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());
|
||||
for (ApprovalCategory.Id category : approvalTypes.getApprovalCategories()) {
|
||||
List<RefRight> categoryRights = new ArrayList<RefRight>();
|
||||
categoryRights.addAll(filterMatching(pe.getLocalRights(), category));
|
||||
categoryRights.addAll(filterMatching(pe.getInheritedRights(), category));
|
||||
categoryRights.addAll(filterMatching(pe.getLocalRights(category)));
|
||||
categoryRights.addAll(filterMatching(pe.getInheritedRights(category)));
|
||||
Collections.sort(categoryRights, RefRight.REF_PATTERN_ORDER);
|
||||
categoryRights = RefControl.filterMostSpecific(categoryRights);
|
||||
computeAllowed(am, categoryRights, category);
|
||||
}
|
||||
}
|
||||
|
||||
private List<RefRight> filterMatching(Collection<RefRight> rights,
|
||||
ApprovalCategory.Id category) {
|
||||
private List<RefRight> filterMatching(Collection<RefRight> rights) {
|
||||
List<RefRight> result = new ArrayList<RefRight>();
|
||||
for (RefRight right : rights) {
|
||||
if (RefControl.matches(change.getDest().get(), right.getRefPattern())
|
||||
&& category.equals(right.getApprovalCategoryId())) {
|
||||
if (RefControl.matches(change.getDest().get(), right.getRefPattern())) {
|
||||
result.add(right);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,11 @@ import com.google.gerrit.server.config.WildProjectName;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Cached information on a project. */
|
||||
@@ -80,6 +82,16 @@ public class ProjectState {
|
||||
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. */
|
||||
public Collection<RefRight> getInheritedRights() {
|
||||
if (isSpecialWildProject()) {
|
||||
@@ -88,6 +100,19 @@ public class ProjectState {
|
||||
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? */
|
||||
public boolean isSpecialWildProject() {
|
||||
return project.getNameKey().equals(wildProject);
|
||||
@@ -104,4 +129,21 @@ public class ProjectState {
|
||||
public ProjectControl controlFor(final CurrentUser user) {
|
||||
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) {
|
||||
return filter(projectControl.getProjectState().getLocalRights(), actionId);
|
||||
return filter(getProjectState().getLocalRights(actionId));
|
||||
}
|
||||
|
||||
private List<RefRight> getInheritedRights(ApprovalCategory.Id actionId) {
|
||||
if (actionId.canInheritFromWildProject()) {
|
||||
return filter(projectControl.getProjectState().getInheritedRights(),
|
||||
actionId);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return filter(getProjectState().getInheritedRights(actionId));
|
||||
}
|
||||
|
||||
public List<RefRight> getAllRights(final ApprovalCategory.Id id) {
|
||||
@@ -293,18 +288,20 @@ public class RefControl {
|
||||
return Collections.unmodifiableList(RefControl.filterMostSpecific(l));
|
||||
}
|
||||
|
||||
private List<RefRight> filter(Collection<RefRight> all,
|
||||
ApprovalCategory.Id actionId) {
|
||||
private List<RefRight> filter(Collection<RefRight> all) {
|
||||
List<RefRight> mine = new ArrayList<RefRight>(all.size());
|
||||
for (RefRight right : all) {
|
||||
if (matches(getRefName(), right.getRefPattern())
|
||||
&& right.getApprovalCategoryId().equals(actionId)) {
|
||||
if (matches(getRefName(), right.getRefPattern())) {
|
||||
mine.add(right);
|
||||
}
|
||||
}
|
||||
return mine;
|
||||
}
|
||||
|
||||
private ProjectState getProjectState() {
|
||||
return projectControl.getProjectState();
|
||||
}
|
||||
|
||||
public static boolean matches(String refName, String refPattern) {
|
||||
if (refPattern.endsWith("/*")) {
|
||||
String prefix = refPattern.substring(0, refPattern.length() - 1);
|
||||
|
||||
Reference in New Issue
Block a user