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:
Shawn O. Pearce
2010-04-20 18:30:58 -07:00
parent 93951e0e13
commit 4cade210a5
3 changed files with 54 additions and 17 deletions

View File

@@ -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);
} }
} }

View File

@@ -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);
}
} }

View File

@@ -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);