Support different color pallete when not signed in

If the user is not signed in a different theme of colors can be
applied to the UI, making it more obvious that login is necessary.

Bug: issue 913
Change-Id: Id8c780042740b3b93dcee7ed84b3f9f6be06d9de
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 2e8d5a4..b288c89 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1795,7 +1795,8 @@
 open changes table or the account dashboard. The value must be a
 valid HTML hex color code, or standard color name.
 +
-By default white, `FFFFFF`.
+By default white, `FFFFFF` for signed-out theme and `FCFEEF` (creme)
+for signed-in theme.
 
 [[theme.topMenuColor]]theme.topMenuColor::
 +
@@ -1830,6 +1831,19 @@
 +
 By default a shade of yellow, `FFFFCC`.
 
+A different theme may be used for signed-in vs. signed-out user status
+by using the "signed-in" and "signed-out" theme sections. Variables
+not specified in a section are inherited from the default theme.
+
+----
+[theme]
+  backgroundColor = FFFFFF
+[theme "signed-in"]
+  backgroundColor = C0C0C0
+[theme "signed-out"]
+  backgroundColor = 00FFFF
+----
+
 [[trackingid]] Section trackingid
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
index 2e6be7e..9bb87ab 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
@@ -42,12 +42,6 @@
   protected List<RegexFindReplace> commentLinks;
   protected boolean documentationAvailable;
 
-  protected String backgroundColor;
-  protected String topMenuColor;
-  protected String textColor;
-  protected String trimColor;
-  protected String selectionColor;
-
   public String getRegisterUrl() {
     return registerUrl;
   }
@@ -166,44 +160,4 @@
   public void setDocumentationAvailable(final boolean available) {
     documentationAvailable = available;
   }
-
-  public String getBackgroundColor() {
-    return backgroundColor;
-  }
-
-  public void setBackgroundColor(String color) {
-    backgroundColor = color;
-  }
-
-  public String getTopMenuColor() {
-    return topMenuColor;
-  }
-
-  public void setTopMenuColor(String color) {
-    topMenuColor = color;
-  }
-
-  public String getTextColor() {
-    return textColor;
-  }
-
-  public void setTextColor(String color) {
-    textColor = color;
-  }
-
-  public String getTrimColor() {
-    return trimColor;
-  }
-
-  public void setTrimColor(String color) {
-    trimColor = color;
-  }
-
-  public String getSelectionColor() {
-    return selectionColor;
-  }
-
-  public void setSelectionColor(String color) {
-    selectionColor = color;
-  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
index 717a492..66b0c3b 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
@@ -22,4 +22,13 @@
   public Account account;
   public AccountDiffPreference accountDiffPref;
   public GerritConfig config;
+  public Theme theme;
+
+  public static class Theme {
+    public String backgroundColor;
+    public String topMenuColor;
+    public String textColor;
+    public String trimColor;
+    public String selectionColor;
+  }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index c2afb84..d0e5192 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -72,6 +72,7 @@
 
   private static String myHost;
   private static GerritConfig myConfig;
+  private static HostPageData.Theme myTheme;
   private static Account myAccount;
   private static AccountDiffPreference myAccountDiffPref;
 
@@ -183,6 +184,11 @@
     return myConfig;
   }
 
+  /** Site theme information (site specific colors)/ */
+  public static HostPageData.Theme getTheme() {
+    return myTheme;
+  }
+
   /** @return the currently signed in user's account data; null if no account */
   public static Account getUserAccount() {
     return myAccount;
@@ -264,6 +270,7 @@
     hpd.load(new GerritCallback<HostPageData>() {
       public void onSuccess(final HostPageData result) {
         myConfig = result.config;
+        myTheme = result.theme;
         if (result.account != null) {
           myAccount = result.account;
         }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index c81920d..a281393 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -38,11 +38,11 @@
 @def norm-font  Arial Unicode MS, Arial, sans-serif;
 @def mono-font 'Lucida Console', 'Lucida Sans Typewriter', Monaco, monospace;
 
-@eval backgroundColor com.google.gerrit.client.Gerrit.getConfig().getBackgroundColor();
-@eval topMenuColor com.google.gerrit.client.Gerrit.getConfig().getTopMenuColor();
-@eval textColor com.google.gerrit.client.Gerrit.getConfig().getTextColor();;
-@eval trimColor com.google.gerrit.client.Gerrit.getConfig().getTrimColor();
-@eval selectionColor com.google.gerrit.client.Gerrit.getConfig().getSelectionColor();
+@eval backgroundColor com.google.gerrit.client.Gerrit.getTheme().backgroundColor;
+@eval topMenuColor com.google.gerrit.client.Gerrit.getTheme().topMenuColor;
+@eval textColor com.google.gerrit.client.Gerrit.getTheme().textColor;
+@eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
+@eval selectionColor com.google.gerrit.client.Gerrit.getTheme().selectionColor;
 
 
 @sprite .greenCheckClass {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gwt_override.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gwt_override.css
index b238292..ed0b32c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gwt_override.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gwt_override.css
@@ -23,10 +23,10 @@
 @external .gwt-TabPanel;
 @external .gwt-TabPanelBottom;
 
-@eval backgroundColor com.google.gerrit.client.Gerrit.getConfig().getBackgroundColor();
-@eval textColor com.google.gerrit.client.Gerrit.getConfig().getTextColor();;
-@eval trimColor com.google.gerrit.client.Gerrit.getConfig().getTrimColor();
-@eval selectionColor com.google.gerrit.client.Gerrit.getConfig().getSelectionColor();
+@eval backgroundColor com.google.gerrit.client.Gerrit.getTheme().backgroundColor;
+@eval textColor com.google.gerrit.client.Gerrit.getTheme().textColor;
+@eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
+@eval selectionColor com.google.gerrit.client.Gerrit.getTheme().selectionColor;
 
 body {
   background: backgroundColor;
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
index e51731d..dd2ef69 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
@@ -149,28 +149,9 @@
     }
     config.setCommentLinks(links);
 
-    config.setBackgroundColor(getThemeColor("backgroundColor", "#FFFFFF"));
-    config.setTextColor(getThemeColor("textColor", "#000000"));
-    config.setTrimColor(getThemeColor("trimColor", "#D4E9A9"));
-    config.setSelectionColor(getThemeColor("selectionColor", "#FFFFCC"));
-
-    config
-        .setTopMenuColor(getThemeColor("topMenuColor", config.getTrimColor()));
-
     return config;
   }
 
-  private String getThemeColor(String name, String defaultValue) {
-    String v = cfg.getString("theme", null, name);
-    if (v == null || v.isEmpty()) {
-      v = defaultValue;
-    }
-    if (!v.startsWith("#") && v.matches("^[0-9a-fA-F]{2,6}$")) {
-      v = "#" + v;
-    }
-    return v;
-  }
-
   @Override
   public GerritConfig get() {
     try {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java
index 4521348..1c2e5b8 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/HostPageServlet.java
@@ -62,6 +62,8 @@
 
   private final Provider<CurrentUser> currentUser;
   private final GerritConfig config;
+  private final HostPageData.Theme signedOutTheme;
+  private final HostPageData.Theme signedInTheme;
   private final SitePaths site;
   private final Document template;
   private final String noCacheName;
@@ -70,10 +72,12 @@
 
   @Inject
   HostPageServlet(final Provider<CurrentUser> cu, final SitePaths sp,
-      final GerritConfig gc, final ServletContext servletContext)
-      throws IOException, ServletException {
+      final ThemeFactory themeFactory, final GerritConfig gc,
+      final ServletContext servletContext) throws IOException, ServletException {
     currentUser = cu;
     config = gc;
+    signedOutTheme = themeFactory.getSignedOutTheme();
+    signedInTheme = themeFactory.getSignedInTheme();
     site = sp;
 
     final String pageName = "HostPage.html";
@@ -158,12 +162,16 @@
       w.write(HPD_ID + ".account=");
       json(((IdentifiedUser) user).getAccount(), w);
       w.write(";");
+
       w.write(HPD_ID + ".accountDiffPref=");
       json(((IdentifiedUser) user).getAccountDiffPreference(), w);
       w.write(";");
 
-      final byte[] userData = w.toString().getBytes("UTF-8");
+      w.write(HPD_ID + ".theme=");
+      json(signedInTheme, w);
+      w.write(";");
 
+      final byte[] userData = w.toString().getBytes("UTF-8");
       raw = concat(page.part1, userData, page.part2);
     } else {
       raw = page.full;
@@ -303,7 +311,14 @@
         }
         part1 = raw.substring(0, p).getBytes("UTF-8");
         part2 = raw.substring(raw.indexOf('>', p) + 1).getBytes("UTF-8");
-        full = concat(part1, part2, new byte[0]);
+
+        final StringWriter w = new StringWriter();
+        w.write(HPD_ID + ".theme=");
+        json(signedOutTheme, w);
+        w.write(";");
+
+        final byte[] themeData = w.toString().getBytes("UTF-8");
+        full = concat(part1, themeData, part2);
         full_gz = HtmlDomUtil.compress(full);
       }
     }
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
new file mode 100644
index 0000000..a1e09f9
--- /dev/null
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
@@ -0,0 +1,66 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.httpd.raw;
+
+import com.google.gerrit.common.data.HostPageData;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.inject.Inject;
+
+import org.eclipse.jgit.lib.Config;
+
+class ThemeFactory {
+  private final Config cfg;
+
+  @Inject
+  ThemeFactory(@GerritServerConfig Config cfg) {
+    this.cfg = cfg;
+  }
+
+  HostPageData.Theme getSignedOutTheme() {
+    return getTheme("signed-out");
+  }
+
+  HostPageData.Theme getSignedInTheme() {
+    return getTheme("signed-in");
+  }
+
+  private HostPageData.Theme getTheme(String name) {
+    HostPageData.Theme theme = new HostPageData.Theme();
+    theme.backgroundColor = color(name, "backgroundColor", "#FFFFFF");
+    theme.textColor = color(name, "textColor", "#000000");
+    theme.trimColor = color(name, "trimColor", "#D4E9A9");
+    theme.selectionColor = color(name, "selectionColor", "#FFFFCC");
+    theme.topMenuColor = color(name, "topMenuColor", theme.trimColor);
+    return theme;
+  }
+
+  private String color(String section, String name, String defaultValue) {
+    String v = cfg.getString("theme", section, name);
+    if (v == null || v.isEmpty()) {
+      v = cfg.getString("theme", null, name);
+      if (v == null || v.isEmpty()) {
+        if ("signed-in".equals(section) && "backgroundColor".equals(name)) {
+          v = "#FCFEEF";
+        } else {
+          v = defaultValue;
+        }
+      }
+    }
+    if (!v.startsWith("#") && v.matches("^[0-9a-fA-F]{2,6}$")) {
+      v = "#" + v;
+    }
+    return v;
+  }
+}