This reverts commit 9551b628d0 (i.e. this is a rollfoward for https://cl.tvl.fyi/c/depot/+/2817)
Change-Id: Iaffcf1cdbe119d26ecb09cc88f9a56436b374c08
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2870
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
		
	
			
		
			
				
	
	
		
			217 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 152fd4ed4cc45d467fd56945debb759870cd53ca Mon Sep 17 00:00:00 2001
 | 
						|
From: Luke Granger-Brown <git@lukegb.com>
 | 
						|
Date: Thu, 2 Jul 2020 23:03:02 +0100
 | 
						|
Subject: [PATCH 4/7] Add titles to CLs over HTTP
 | 
						|
 | 
						|
---
 | 
						|
 .../gerrit/httpd/raw/IndexHtmlUtil.java       | 13 +++-
 | 
						|
 .../google/gerrit/httpd/raw/IndexServlet.java |  8 ++-
 | 
						|
 .../google/gerrit/httpd/raw/StaticModule.java |  6 +-
 | 
						|
 .../gerrit/httpd/raw/TitleComputer.java       | 67 +++++++++++++++++++
 | 
						|
 .../gerrit/httpd/raw/PolyGerritIndexHtml.soy  |  4 +-
 | 
						|
 5 files changed, 90 insertions(+), 8 deletions(-)
 | 
						|
 create mode 100644 java/com/google/gerrit/httpd/raw/TitleComputer.java
 | 
						|
 | 
						|
diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 | 
						|
index 8d52f5ad50..a9cfceb3b6 100644
 | 
						|
--- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 | 
						|
+++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 | 
						|
@@ -39,6 +39,7 @@ import java.util.Arrays;
 | 
						|
 import java.util.Collections;
 | 
						|
 import java.util.HashMap;
 | 
						|
 import java.util.Map;
 | 
						|
+import java.util.Optional;
 | 
						|
 import java.util.Set;
 | 
						|
 import java.util.function.Function;
 | 
						|
 
 | 
						|
@@ -60,13 +61,14 @@ public class IndexHtmlUtil {
 | 
						|
       String faviconPath,
 | 
						|
       Map<String, String[]> urlParameterMap,
 | 
						|
       Function<String, SanitizedContent> urlInScriptTagOrdainer,
 | 
						|
-      String requestedURL)
 | 
						|
+      String requestedURL,
 | 
						|
+      TitleComputer titleComputer)
 | 
						|
       throws URISyntaxException, RestApiException {
 | 
						|
     ImmutableMap.Builder<String, Object> data = ImmutableMap.builder();
 | 
						|
     data.putAll(
 | 
						|
             staticTemplateData(
 | 
						|
                 canonicalURL, cdnPath, faviconPath, urlParameterMap, urlInScriptTagOrdainer))
 | 
						|
-        .putAll(dynamicTemplateData(gerritApi, requestedURL));
 | 
						|
+        .putAll(dynamicTemplateData(gerritApi, requestedURL, titleComputer));
 | 
						|
     Set<String> enabledExperiments = experimentFeatures.getEnabledExperimentFeatures();
 | 
						|
 
 | 
						|
     if (!enabledExperiments.isEmpty()) {
 | 
						|
@@ -77,7 +79,9 @@ public class IndexHtmlUtil {
 | 
						|
 
 | 
						|
   /** Returns dynamic parameters of {@code index.html}. */
 | 
						|
   public static ImmutableMap<String, Object> dynamicTemplateData(
 | 
						|
-      GerritApi gerritApi, String requestedURL) throws RestApiException, URISyntaxException {
 | 
						|
+      GerritApi gerritApi,
 | 
						|
+      String requestedURL,
 | 
						|
+      TitleComputer titleComputer) throws RestApiException, URISyntaxException {
 | 
						|
     ImmutableMap.Builder<String, Object> data = ImmutableMap.builder();
 | 
						|
     Map<String, SanitizedContent> initialData = new HashMap<>();
 | 
						|
     Server serverApi = gerritApi.config().server();
 | 
						|
@@ -128,6 +132,9 @@ public class IndexHtmlUtil {
 | 
						|
       // Don't render data
 | 
						|
     }
 | 
						|
 
 | 
						|
+    Optional<String> title = titleComputer.computeTitle(requestedURL);
 | 
						|
+    title.ifPresent(s -> data.put("title", s));
 | 
						|
+
 | 
						|
     data.put("gerritInitialData", initialData);
 | 
						|
     return data.build();
 | 
						|
   }
 | 
						|
diff --git a/java/com/google/gerrit/httpd/raw/IndexServlet.java b/java/com/google/gerrit/httpd/raw/IndexServlet.java
 | 
						|
index 3f2c2028ae..7861c007df 100644
 | 
						|
--- a/java/com/google/gerrit/httpd/raw/IndexServlet.java
 | 
						|
+++ b/java/com/google/gerrit/httpd/raw/IndexServlet.java
 | 
						|
@@ -46,13 +46,15 @@ public class IndexServlet extends HttpServlet {
 | 
						|
   private final ExperimentFeatures experimentFeatures;
 | 
						|
   private final SoySauce soySauce;
 | 
						|
   private final Function<String, SanitizedContent> urlOrdainer;
 | 
						|
+  private TitleComputer titleComputer;
 | 
						|
 
 | 
						|
   IndexServlet(
 | 
						|
       @Nullable String canonicalUrl,
 | 
						|
       @Nullable String cdnPath,
 | 
						|
       @Nullable String faviconPath,
 | 
						|
       GerritApi gerritApi,
 | 
						|
-      ExperimentFeatures experimentFeatures) {
 | 
						|
+      ExperimentFeatures experimentFeatures,
 | 
						|
+      TitleComputer titleComputer) {
 | 
						|
     this.canonicalUrl = canonicalUrl;
 | 
						|
     this.cdnPath = cdnPath;
 | 
						|
     this.faviconPath = faviconPath;
 | 
						|
@@ -67,6 +69,7 @@ public class IndexServlet extends HttpServlet {
 | 
						|
         (s) ->
 | 
						|
             UnsafeSanitizedContentOrdainer.ordainAsSafe(
 | 
						|
                 s, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
 | 
						|
+    this.titleComputer = titleComputer;
 | 
						|
   }
 | 
						|
 
 | 
						|
   @Override
 | 
						|
@@ -85,7 +88,8 @@ public class IndexServlet extends HttpServlet {
 | 
						|
               faviconPath,
 | 
						|
               parameterMap,
 | 
						|
               urlOrdainer,
 | 
						|
-              requestUrl);
 | 
						|
+              requestUrl,
 | 
						|
+              titleComputer);
 | 
						|
       renderer = soySauce.renderTemplate("com.google.gerrit.httpd.raw.Index").setData(templateData);
 | 
						|
     } catch (URISyntaxException | RestApiException e) {
 | 
						|
       throw new IOException(e);
 | 
						|
diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java
 | 
						|
index cac716feb9..6b17d8ea6f 100644
 | 
						|
--- a/java/com/google/gerrit/httpd/raw/StaticModule.java
 | 
						|
+++ b/java/com/google/gerrit/httpd/raw/StaticModule.java
 | 
						|
@@ -223,11 +223,13 @@ public class StaticModule extends ServletModule {
 | 
						|
         @CanonicalWebUrl @Nullable String canonicalUrl,
 | 
						|
         @GerritServerConfig Config cfg,
 | 
						|
         GerritApi gerritApi,
 | 
						|
-        ExperimentFeatures experimentFeatures) {
 | 
						|
+        ExperimentFeatures experimentFeatures,
 | 
						|
+        TitleComputer titleComputer) {
 | 
						|
       String cdnPath =
 | 
						|
           options.useDevCdn() ? options.devCdn() : cfg.getString("gerrit", null, "cdnPath");
 | 
						|
       String faviconPath = cfg.getString("gerrit", null, "faviconPath");
 | 
						|
-      return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi, experimentFeatures);
 | 
						|
+      return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi,
 | 
						|
+          experimentFeatures, titleComputer);
 | 
						|
     }
 | 
						|
 
 | 
						|
     @Provides
 | 
						|
diff --git a/java/com/google/gerrit/httpd/raw/TitleComputer.java b/java/com/google/gerrit/httpd/raw/TitleComputer.java
 | 
						|
new file mode 100644
 | 
						|
index 0000000000..8fd2053ad0
 | 
						|
--- /dev/null
 | 
						|
+++ b/java/com/google/gerrit/httpd/raw/TitleComputer.java
 | 
						|
@@ -0,0 +1,67 @@
 | 
						|
+package com.google.gerrit.httpd.raw;
 | 
						|
+
 | 
						|
+import com.google.common.flogger.FluentLogger;
 | 
						|
+import com.google.gerrit.entities.Change;
 | 
						|
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | 
						|
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | 
						|
+import com.google.gerrit.server.change.ChangeResource;
 | 
						|
+import com.google.gerrit.server.permissions.PermissionBackendException;
 | 
						|
+import com.google.gerrit.server.restapi.change.ChangesCollection;
 | 
						|
+import com.google.inject.Inject;
 | 
						|
+import com.google.inject.Provider;
 | 
						|
+import com.google.inject.Singleton;
 | 
						|
+
 | 
						|
+import java.net.MalformedURLException;
 | 
						|
+import java.net.URL;
 | 
						|
+import java.util.Optional;
 | 
						|
+import java.util.regex.Matcher;
 | 
						|
+import java.util.regex.Pattern;
 | 
						|
+
 | 
						|
+@Singleton
 | 
						|
+public class TitleComputer {
 | 
						|
+  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 | 
						|
+
 | 
						|
+  @Inject
 | 
						|
+  public TitleComputer(Provider<ChangesCollection> changes) {
 | 
						|
+    this.changes = changes;
 | 
						|
+  }
 | 
						|
+
 | 
						|
+  public Optional<String> computeTitle(String requestedURI) {
 | 
						|
+    URL url = null;
 | 
						|
+    try {
 | 
						|
+      url = new URL(requestedURI);
 | 
						|
+    } catch (MalformedURLException e) {
 | 
						|
+      logger.atWarning().log("Failed to turn %s into a URL.", requestedURI);
 | 
						|
+      return Optional.empty();
 | 
						|
+    }
 | 
						|
+
 | 
						|
+    // Try to turn this into a change.
 | 
						|
+    Optional<Change.Id> changeId = tryExtractChange(url.getPath());
 | 
						|
+    if (changeId.isPresent()) {
 | 
						|
+      return titleFromChangeId(changeId.get());
 | 
						|
+    }
 | 
						|
+
 | 
						|
+    return Optional.empty();
 | 
						|
+  }
 | 
						|
+
 | 
						|
+  private static final Pattern extractChangeIdRegex = Pattern.compile("^/(?:c/.*/\\+/)?(?<changeId>[0-9]+)(?:/[0-9]+)?(?:/.*)?$");
 | 
						|
+  private final Provider<ChangesCollection> changes;
 | 
						|
+
 | 
						|
+  private Optional<Change.Id> tryExtractChange(String path) {
 | 
						|
+    Matcher m = extractChangeIdRegex.matcher(path);
 | 
						|
+    if (!m.matches()) {
 | 
						|
+      return Optional.empty();
 | 
						|
+    }
 | 
						|
+    return Change.Id.tryParse(m.group("changeId"));
 | 
						|
+  }
 | 
						|
+
 | 
						|
+  private Optional<String> titleFromChangeId(Change.Id changeId) {
 | 
						|
+    ChangesCollection changesCollection = changes.get();
 | 
						|
+    try {
 | 
						|
+      ChangeResource changeResource = changesCollection.parse(changeId);
 | 
						|
+      return Optional.of(changeResource.getChange().getSubject());
 | 
						|
+    } catch (ResourceConflictException | ResourceNotFoundException | PermissionBackendException e) {
 | 
						|
+      return Optional.empty();
 | 
						|
+    }
 | 
						|
+  }
 | 
						|
+}
 | 
						|
diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 | 
						|
index 93584c6b05..6e6a1e5401 100644
 | 
						|
--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 | 
						|
+++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 | 
						|
@@ -33,10 +33,12 @@
 | 
						|
   {@param? defaultDashboardHex: ?}
 | 
						|
   {@param? dashboardQuery: ?}
 | 
						|
   {@param? userIsAuthenticated: ?}
 | 
						|
+  {@param? title: ?}
 | 
						|
   <!DOCTYPE html>{\n}
 | 
						|
   <html lang="en">{\n}
 | 
						|
   <meta charset="utf-8">{\n}
 | 
						|
-  <meta name="description" content="Gerrit Code Review">{\n}
 | 
						|
+  {if $title}<title>{$title} · Gerrit Code Review</title>{\n}{/if}
 | 
						|
+  <meta name="description" content="{if $title}{$title} · {/if}Gerrit Code Review">{\n}
 | 
						|
   <meta name="referrer" content="never">{\n}
 | 
						|
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">{\n}
 | 
						|
 
 | 
						|
-- 
 | 
						|
2.29.2
 | 
						|
 |