Redirect rule for GitHub import wizard.

Introduce the ability to control forwarding or
redirecting to the next wizard step.

Forward rule:
wizardFlow = account.gh => repositories.html

Redirect rule example:
wizardFlow = account.gh R> /

The value of forward is the ability
to keep the HTTP Request with all associated parameters
and send them to the target page / servlet.
The drawback is the Browser URL not being updated
and the target page / servlet should behave
consistently with the different target URL in the request
and associated parameters.

Change-Id: I37bd5724183ac0042c1cc59cd0e97f930f94388e
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubConfig.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubConfig.java
index 9c80aa6..ddada01 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubConfig.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/GitHubConfig.java
@@ -19,6 +19,7 @@
 
 import org.eclipse.jgit.lib.Config;
 
+import com.google.common.collect.Maps;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
@@ -29,11 +30,21 @@
 public class GitHubConfig extends GitHubOAuthConfig {
 
   private static final String CONF_WIZARD_FLOW = "wizardFlow";
-  private HashMap<String, String> wizardFromTo = new HashMap<String, String>();
+  private HashMap<String, NextPage> wizardFromTo = Maps.newHashMap();
   private static final String FROM_TO_SEPARATOR = "=>";
-
+  private static final String FROM_TO_REDIRECT_SEPARATOR = "R>";
   public final File gitDir;
 
+  public static class NextPage {
+    public final String uri;
+    public final boolean redirect;
+
+    public NextPage(final String pageUri, final boolean redirect) {
+      this.uri = pageUri;
+      this.redirect = redirect;
+    }
+  }
+
 
   @Inject
   public GitHubConfig(@GerritServerConfig Config config, final SitePaths site)
@@ -42,10 +53,12 @@
     String[] wizardFlows =
         config.getStringList(CONF_SECTION, null, CONF_WIZARD_FLOW);
     for (String fromTo : wizardFlows) {
-      int sepPos = getSepPos(fromTo);
+      boolean redirect = fromTo.indexOf(FROM_TO_REDIRECT_SEPARATOR) > 0;
+      int sepPos = getSepPos(fromTo, redirect);
       String fromPage = fromTo.substring(0, sepPos).trim();
-      String toPage =
-          fromTo.substring(sepPos + FROM_TO_SEPARATOR.length() + 1).trim();
+      NextPage toPage =
+          new NextPage(fromTo.substring(
+              sepPos + getSeparator(redirect).length() + 1).trim(), redirect);
       wizardFromTo.put(fromPage, toPage);
     }
     gitDir = site.resolve(config.getString("gerrit", null, "basePath"));
@@ -54,15 +67,21 @@
     }
   }
 
-  private int getSepPos(String fromTo) {
-    int sepPos = fromTo.indexOf(FROM_TO_SEPARATOR);
+  private String getSeparator(boolean redirect) {
+    String separator =
+        redirect ? FROM_TO_REDIRECT_SEPARATOR : FROM_TO_SEPARATOR;
+    return separator;
+  }
+
+  private int getSepPos(String fromTo, boolean redirect) {
+    int sepPos = fromTo.indexOf(getSeparator(redirect));
     if (sepPos < 0) {
       throw new InvalidGitHubConfigException(fromTo);
     }
     return sepPos;
   }
 
-  public String getNextPage(String sourcePage) {
+  public NextPage getNextPage(String sourcePage) {
     return wizardFromTo.get(sourcePage);
   }
 }
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/velocity/VelocityViewServlet.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/velocity/VelocityViewServlet.java
index 45b195c..b17f858 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/velocity/VelocityViewServlet.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/velocity/VelocityViewServlet.java
@@ -37,6 +37,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
+import com.googlesource.gerrit.plugins.github.GitHubConfig.NextPage;
 import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
 
 @Singleton
@@ -70,11 +71,12 @@
     HttpServletResponse resp = (HttpServletResponse) response;
 
     String servletPath = req.getServletPath();
-    String destUrl = (String) req.getAttribute("destUrl");
-    if (destUrl != null && !destUrl.startsWith("/")) {
+    NextPage nextPage = (NextPage) req.getAttribute("destUrl");
+    String destUrl = null;
+    if (nextPage != null && !nextPage.uri.startsWith("/")) {
       destUrl =
           servletPath.substring(0, servletPath.lastIndexOf("/")) + "/"
-              + destUrl;
+              + nextPage.uri;
     }
 
     String pathInfo = Objects.firstNonNull(destUrl, servletPath);
diff --git a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/VelocityControllerServlet.java b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/VelocityControllerServlet.java
index 9790176..c68d82a 100644
--- a/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/VelocityControllerServlet.java
+++ b/github-plugin/src/main/java/com/googlesource/gerrit/plugins/github/wizard/VelocityControllerServlet.java
@@ -36,6 +36,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.github.GitHubConfig;
+import com.googlesource.gerrit.plugins.github.GitHubConfig.NextPage;
 import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
 import com.googlesource.gerrit.plugins.github.velocity.PluginVelocityModel;
 
@@ -130,11 +131,16 @@
     if (queryStringStart > 0) {
       sourcePage = sourcePage.substring(0, queryStringStart);
     }
-    String nextPage = githubConfig.getNextPage(sourcePage);
+    NextPage nextPage = githubConfig.getNextPage(sourcePage);
     if (nextPage != null) {
-      RequestDispatcher requestDispatcher = req.getRequestDispatcher(nextPage);
-      req.setAttribute("destUrl", nextPage);
-      requestDispatcher.forward(req, resp);
+      if (nextPage.redirect) {
+        resp.sendRedirect(nextPage.uri);
+      } else {
+        RequestDispatcher requestDispatcher =
+            req.getRequestDispatcher(nextPage.uri);
+        req.setAttribute("destUrl", nextPage);
+        requestDispatcher.forward(req, resp);
+      }
     }
   }