Use HostIndex to display subtrees of repositories If a repository does not exist try to list the repositories that use that prefix, or 404 if the GitilesAccess instance returns no matches. This allows listing a subtree of repositories without needing to build up the entire HostIndex result set. Change-Id: Ie3e046101919b6bedcc26198e455dface881315b
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java index 2d52359..aa2208a 100644 --- a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java +++ b/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
@@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; import com.google.gson.reflect.TypeToken; +import com.google.template.soy.data.SoyData; import com.google.template.soy.data.SoyListData; import com.google.template.soy.data.SoyMapData; @@ -37,9 +38,12 @@ import java.io.IOException; import java.io.Writer; import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -56,16 +60,12 @@ this.urls = checkNotNull(urls, "urls"); } - private Map<String, RepositoryDescription> getDescriptions(HttpServletRequest req, - HttpServletResponse res) throws IOException { - return getDescriptions(req, res, parseShowBranch(req)); - } - - private Map<String, RepositoryDescription> getDescriptions(HttpServletRequest req, - HttpServletResponse res, Set<String> branches) throws IOException { + private Map<String, RepositoryDescription> list( + HttpServletRequest req, HttpServletResponse res, String prefix, + Set<String> branches) throws IOException { Map<String, RepositoryDescription> descs; try { - descs = getAccess(req).listRepositories(branches); + descs = getAccess(req).listRepositories(prefix, branches); } catch (RepositoryNotFoundException e) { res.sendError(SC_NOT_FOUND); return null; @@ -85,12 +85,17 @@ res.sendError(SC_SERVICE_UNAVAILABLE); return null; } + if (prefix != null && descs.isEmpty()) { + res.sendError(SC_NOT_FOUND); + return null; + } return descs; } - private SoyMapData toSoyMapData(RepositoryDescription desc, GitilesView view) { + private SoyMapData toSoyMapData(RepositoryDescription desc, + @Nullable String prefix, GitilesView view) { return new SoyMapData( - "name", desc.name, + "name", stripPrefix(prefix, desc.name), "description", Strings.nullToEmpty(desc.description), "url", GitilesView.repositoryIndex() .copyFrom(view) @@ -100,25 +105,37 @@ @Override protected void doGetHtml(HttpServletRequest req, HttpServletResponse res) throws IOException { - Map<String, RepositoryDescription> descs = getDescriptions(req, res); + GitilesView view = ViewFilter.getView(req); + String prefix = view.getRepositoryPrefix(); + Map<String, RepositoryDescription> descs = list(req, res, prefix, parseShowBranch(req)); if (descs == null) { return; } + SoyListData repos = new SoyListData(); for (RepositoryDescription desc : descs.values()) { - repos.add(toSoyMapData(desc, ViewFilter.getView(req))); + repos.add(toSoyMapData(desc, prefix, view)); } + String hostName = urls.getHostName(req); + List<Map<String, String>> breadcrumbs = null; + if (prefix != null) { + hostName = hostName + '/' + prefix; + breadcrumbs = view.getBreadcrumbs(); + } renderHtml(req, res, "gitiles.hostIndex", ImmutableMap.of( - "hostName", urls.getHostName(req), + "hostName", hostName, + "breadcrumbs", SoyData.createFromExistingData(breadcrumbs), "baseUrl", urls.getBaseGitUrl(req), + "prefix", prefix != null ? prefix + '/' : "", "repositories", repos)); } @Override protected void doGetText(HttpServletRequest req, HttpServletResponse res) throws IOException { + String prefix = ViewFilter.getView(req).getRepositoryPrefix(); Set<String> branches = parseShowBranch(req); - Map<String, RepositoryDescription> descs = getDescriptions(req, res, branches); + Map<String, RepositoryDescription> descs = list(req, res, prefix, branches); if (descs == null) { return; } @@ -134,7 +151,7 @@ writer.write(ref); writer.write(' '); } - writer.write(GitilesUrls.NAME_ESCAPER.apply(repo.name)); + writer.write(GitilesUrls.NAME_ESCAPER.apply(stripPrefix(prefix, repo.name))); writer.write('\n'); } writer.flush(); @@ -143,13 +160,25 @@ @Override protected void doGetJson(HttpServletRequest req, HttpServletResponse res) throws IOException { - Map<String, RepositoryDescription> descs = getDescriptions(req, res); + String prefix = ViewFilter.getView(req).getRepositoryPrefix(); + Map<String, RepositoryDescription> descs = list(req, res, prefix, parseShowBranch(req)); if (descs == null) { return; } + if (prefix != null) { + Map<String, RepositoryDescription> r = new LinkedHashMap<>(); + for (Map.Entry<String, RepositoryDescription> e : descs.entrySet()) { + r.put(stripPrefix(prefix, e.getKey()), e.getValue()); + } + descs = r; + } renderJson(req, res, descs, new TypeToken<Map<String, RepositoryDescription>>() {}.getType()); } + private static String stripPrefix(@Nullable String prefix, String name) { + return prefix != null ? name.substring(prefix.length() + 1) : name; + } + private static Set<String> parseShowBranch(HttpServletRequest req) { // Roughly match Gerrit Code Review's /projects/ API by supporting // both show-branch and b as query parameters.