ListBranches: Use FluentIterable for filter, start, and limit
Factor out predicates and refactor for better readability. Change-Id: I2fdded5cabc455d4a866b2f8befd361f2cffe611
This commit is contained in:
		| @@ -15,9 +15,8 @@ | |||||||
| package com.google.gerrit.server.project; | package com.google.gerrit.server.project; | ||||||
|  |  | ||||||
| import com.google.common.base.Predicate; | import com.google.common.base.Predicate; | ||||||
|  | import com.google.common.base.Strings; | ||||||
| import com.google.common.collect.FluentIterable; | import com.google.common.collect.FluentIterable; | ||||||
| import com.google.common.collect.Iterables; |  | ||||||
| import com.google.common.collect.Lists; |  | ||||||
| import com.google.common.collect.Sets; | import com.google.common.collect.Sets; | ||||||
| import com.google.gerrit.extensions.common.ActionInfo; | import com.google.gerrit.extensions.common.ActionInfo; | ||||||
| import com.google.gerrit.extensions.common.WebLinkInfo; | import com.google.gerrit.extensions.common.WebLinkInfo; | ||||||
| @@ -83,7 +82,7 @@ public class ListBranches implements RestReadView<ProjectResource> { | |||||||
|   @Override |   @Override | ||||||
|   public List<BranchInfo> apply(ProjectResource rsrc) |   public List<BranchInfo> apply(ProjectResource rsrc) | ||||||
|       throws ResourceNotFoundException, IOException, BadRequestException { |       throws ResourceNotFoundException, IOException, BadRequestException { | ||||||
|     List<BranchInfo> branches; |     List<BranchInfo> branchList; | ||||||
|     BranchInfo headBranch = null; |     BranchInfo headBranch = null; | ||||||
|     BranchInfo configBranch = null; |     BranchInfo configBranch = null; | ||||||
|  |  | ||||||
| @@ -102,7 +101,7 @@ public class ListBranches implements RestReadView<ProjectResource> { | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       branches = new ArrayList<>(refs.size()); |       branchList = new ArrayList<>(refs.size()); | ||||||
|       for (Ref ref : refs) { |       for (Ref ref : refs) { | ||||||
|         if (ref.isSymbolic()) { |         if (ref.isSymbolic()) { | ||||||
|           // A symbolic reference to another branch, instead of |           // A symbolic reference to another branch, instead of | ||||||
| @@ -123,7 +122,7 @@ public class ListBranches implements RestReadView<ProjectResource> { | |||||||
|             headBranch = b; |             headBranch = b; | ||||||
|           } else { |           } else { | ||||||
|             b.setCanDelete(targetRefControl.canDelete()); |             b.setCanDelete(targetRefControl.canDelete()); | ||||||
|             branches.add(b); |             branchList.add(b); | ||||||
|           } |           } | ||||||
|           continue; |           continue; | ||||||
|         } |         } | ||||||
| @@ -133,45 +132,34 @@ public class ListBranches implements RestReadView<ProjectResource> { | |||||||
|           if (RefNames.REFS_CONFIG.equals(ref.getName())) { |           if (RefNames.REFS_CONFIG.equals(ref.getName())) { | ||||||
|             configBranch = createBranchInfo(ref, refControl, targets); |             configBranch = createBranchInfo(ref, refControl, targets); | ||||||
|           } else { |           } else { | ||||||
|             branches.add(createBranchInfo(ref, refControl, targets)); |             branchList.add(createBranchInfo(ref, refControl, targets)); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } catch (RepositoryNotFoundException noGitRepository) { |     } catch (RepositoryNotFoundException noGitRepository) { | ||||||
|       throw new ResourceNotFoundException(); |       throw new ResourceNotFoundException(); | ||||||
|     } |     } | ||||||
|     Collections.sort(branches, new Comparator<BranchInfo>() { |     Collections.sort(branchList, new Comparator<BranchInfo>() { | ||||||
|       @Override |       @Override | ||||||
|       public int compare(BranchInfo a, BranchInfo b) { |       public int compare(BranchInfo a, BranchInfo b) { | ||||||
|         return a.ref.compareTo(b.ref); |         return a.ref.compareTo(b.ref); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|     if (configBranch != null) { |     if (configBranch != null) { | ||||||
|       branches.add(0, configBranch); |       branchList.add(0, configBranch); | ||||||
|     } |     } | ||||||
|     if (headBranch != null) { |     if (headBranch != null) { | ||||||
|       branches.add(0, headBranch); |       branchList.add(0, headBranch); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     List<BranchInfo> filteredBranches; |     FluentIterable<BranchInfo> branches = filterBranches(branchList); | ||||||
|     if ((matchSubstring != null && !matchSubstring.isEmpty()) |     if (start > 0) { | ||||||
|         || (matchRegex != null && !matchRegex.isEmpty())) { |       branches = branches.skip(start); | ||||||
|       filteredBranches = filterBranches(branches); |  | ||||||
|     } else { |  | ||||||
|       filteredBranches = branches; |  | ||||||
|     } |     } | ||||||
|     if (!filteredBranches.isEmpty()) { |     if (limit > 0) { | ||||||
|       int end = filteredBranches.size(); |       branches = branches.limit(limit); | ||||||
|       if (limit > 0 && start + limit < end) { |  | ||||||
|         end = start + limit; |  | ||||||
|       } |  | ||||||
|       if (start <= end) { |  | ||||||
|         filteredBranches = filteredBranches.subList(start, end); |  | ||||||
|       } else { |  | ||||||
|         filteredBranches = Collections.emptyList(); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     return filteredBranches; |     return branches.toList(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static void addRef(Repository db, List<Ref> refs, String name) |   private static void addRef(Repository db, List<Ref> refs, String name) | ||||||
| @@ -182,52 +170,60 @@ public class ListBranches implements RestReadView<ProjectResource> { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private List<BranchInfo> filterBranches(List<BranchInfo> branches) |   private FluentIterable<BranchInfo> filterBranches(List<BranchInfo> branchList) | ||||||
|       throws BadRequestException { |       throws BadRequestException { | ||||||
|     if (matchSubstring != null) { |     FluentIterable<BranchInfo> branches = FluentIterable.from(branchList); | ||||||
|       return Lists.newArrayList(Iterables.filter(branches, |     if (!Strings.isNullOrEmpty(matchSubstring)) { | ||||||
|           new Predicate<BranchInfo>() { |       branches = branches.filter(new SubstringPredicate(matchSubstring)); | ||||||
|             @Override |     } else if (!Strings.isNullOrEmpty(matchRegex)) { | ||||||
|             public boolean apply(BranchInfo in) { |       branches = branches.filter(new RegexPredicate(matchRegex)); | ||||||
|               if (!in.ref.startsWith(Constants.R_HEADS)){ |     } | ||||||
|                 return in.ref.toLowerCase(Locale.US).contains( |     return branches; | ||||||
|                     matchSubstring.toLowerCase(Locale.US)); |   } | ||||||
|               } else { |  | ||||||
|                 return in.ref.substring(Constants.R_HEADS.length()) |   private static class SubstringPredicate implements Predicate<BranchInfo> { | ||||||
|                     .toLowerCase(Locale.US) |     private final String substring; | ||||||
|                     .contains(matchSubstring.toLowerCase(Locale.US)); |  | ||||||
|               } |     private SubstringPredicate(String substring) { | ||||||
|             } |       this.substring = substring.toLowerCase(Locale.US); | ||||||
|           })); |     } | ||||||
|     } else if (matchRegex != null) { |  | ||||||
|       if (matchRegex.startsWith("^")) { |     @Override | ||||||
|         matchRegex = matchRegex.substring(1); |     public boolean apply(BranchInfo in) { | ||||||
|         if (matchRegex.endsWith("$") && !matchRegex.endsWith("\\$")) { |       String ref = in.ref; | ||||||
|           matchRegex = matchRegex.substring(0, matchRegex.length() - 1); |       if (ref.startsWith(Constants.R_HEADS)) { | ||||||
|  |         ref = ref.substring(Constants.R_HEADS.length()); | ||||||
|  |       } | ||||||
|  |       ref = ref.toLowerCase(Locale.US); | ||||||
|  |       return ref.contains(substring); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private static class RegexPredicate implements Predicate<BranchInfo> { | ||||||
|  |     private final RunAutomaton a; | ||||||
|  |  | ||||||
|  |     private RegexPredicate(String regex) throws BadRequestException { | ||||||
|  |       if (regex.startsWith("^")) { | ||||||
|  |         regex = regex.substring(1); | ||||||
|  |         if (regex.endsWith("$") && !regex.endsWith("\\$")) { | ||||||
|  |           regex = regex.substring(0, regex.length() - 1); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       if (matchRegex.equals(".*")) { |  | ||||||
|         return branches; |  | ||||||
|       } |  | ||||||
|       try { |       try { | ||||||
|         final RunAutomaton a = |         a = new RunAutomaton(new RegExp(regex).toAutomaton()); | ||||||
|             new RunAutomaton(new RegExp(matchRegex).toAutomaton()); |  | ||||||
|         return Lists.newArrayList(Iterables.filter( |  | ||||||
|             branches, new Predicate<BranchInfo>() { |  | ||||||
|               @Override |  | ||||||
|               public boolean apply(BranchInfo in) { |  | ||||||
|                 if (!in.ref.startsWith(Constants.R_HEADS)){ |  | ||||||
|                   return a.run(in.ref); |  | ||||||
|                 } else { |  | ||||||
|                   return a.run(in.ref.substring(Constants.R_HEADS.length())); |  | ||||||
|                 } |  | ||||||
|               } |  | ||||||
|             })); |  | ||||||
|       } catch (IllegalArgumentException e) { |       } catch (IllegalArgumentException e) { | ||||||
|         throw new BadRequestException(e.getMessage()); |         throw new BadRequestException(e.getMessage()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return branches; |  | ||||||
|  |     @Override | ||||||
|  |     public boolean apply(BranchInfo in) { | ||||||
|  |       if (!in.ref.startsWith(Constants.R_HEADS)){ | ||||||
|  |         return a.run(in.ref); | ||||||
|  |       } else { | ||||||
|  |         return a.run(in.ref.substring(Constants.R_HEADS.length())); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private BranchInfo createBranchInfo(Ref ref, RefControl refControl, |   private BranchInfo createBranchInfo(Ref ref, RefControl refControl, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Dave Borowitz
					Dave Borowitz