Unify debug launch configs and auto-detect browser

Use the same permutation selector applied by the server at runtime to
automatically detect the browser making the request and build/refresh
that UI permutation.

Change-Id: I31603a80e23a8e4e2c46325be4dac808d8f98a5c
diff --git a/Documentation/dev-eclipse.txt b/Documentation/dev-eclipse.txt
index eeee5a3..50236a2 100644
--- a/Documentation/dev-eclipse.txt
+++ b/Documentation/dev-eclipse.txt
@@ -37,7 +37,7 @@
 Duplicate the existing launch configuration:
 
 * Run -> Debug Configurations ...
-* Java Application -> `buck_daemon_ui_*`
+* Java Application -> `gerrit_daemon`
 * Right click, Duplicate
 
 * Modify the name to be unique.
diff --git a/gerrit-pgm/BUCK b/gerrit-pgm/BUCK
index 67b28ac..2d84af7 100644
--- a/gerrit-pgm/BUCK
+++ b/gerrit-pgm/BUCK
@@ -90,6 +90,7 @@
     '//gerrit-cache-h2:cache-h2',
     '//gerrit-common:server',
     '//gerrit-extension-api:api',
+    '//gerrit-gwtexpui:linker_server',
     '//gerrit-gwtexpui:server',
     '//gerrit-httpd:httpd',
     '//gerrit-lucene:lucene',
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java
index 4a19109..c5c812a 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java
@@ -26,6 +26,7 @@
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.util.TimeUtil;
+import com.google.gwtexpui.linker.server.UserAgentRule;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
@@ -558,60 +559,53 @@
     }
     dir = dir.getParentFile(); // pop classes
 
-    if ("buck-out".equals(dir.getName())) {
-      final File dstwar = makeWarTempDir();
-      String pkg = "gerrit-gwtui";
-      String target = targetForBrowser(System.getProperty("gerrit.browser"));
-      final File gen = new File(dir, "gen");
-      String out = new File(new File(gen, pkg), target).getAbsolutePath();
-      final File zip = new File(out + ".zip");
-      final File root = dir.getParentFile();
-      final String name = "//" + pkg + ":" + target;
-
-      File ui = new File(dstwar, "gerrit_ui");
-      File p = new File(ui, "permutations");
-      mkdir(ui);
-      p.createNewFile();
-      p.deleteOnExit();
-
-      app.addFilter(new FilterHolder(new Filter() {
-        private long last;
-
-        @Override
-        public void doFilter(ServletRequest request, ServletResponse res,
-            FilterChain chain) throws IOException, ServletException {
-          HttpServletRequest req = (HttpServletRequest) request;
-          build(root, gen, name);
-          if (last != zip.lastModified()) {
-            last = zip.lastModified();
-            unpack(zip, dstwar);
-          }
-          chain.doFilter(req, res);
-        }
-
-        @Override
-        public void init(FilterConfig config) {
-        }
-        @Override
-        public void destroy() {
-        }
-      }), "/", EnumSet.of(DispatcherType.REQUEST));
-      return Resource.newResource(dstwar.toURI());
-    } else if ("target".equals(dir.getName())) {
-      return useMavenDeveloperBuild(dir);
-    } else {
+    if (!"buck-out".equals(dir.getName())) {
       throw new FileNotFoundException("Cannot find web root from " + u);
     }
-  }
 
-  private static String targetForBrowser(String browser) {
-    if (browser == null || browser.isEmpty()) {
-      return "ui_dbg";
-    } else if (browser.startsWith("ui_")) {
-      return browser;
-    } else {
-      return "ui_" + browser;
-    }
+    final File gen = new File(dir, "gen");
+    final File root = dir.getParentFile();
+    final File dstwar = makeWarTempDir();
+    File ui = new File(dstwar, "gerrit_ui");
+    File p = new File(ui, "permutations");
+    mkdir(ui);
+    p.createNewFile();
+    p.deleteOnExit();
+
+    app.addFilter(new FilterHolder(new Filter() {
+      private final UserAgentRule rule = new UserAgentRule();
+      private String lastTarget;
+      private long lastTime;
+
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse res,
+          FilterChain chain) throws IOException, ServletException {
+        String pkg = "gerrit-gwtui";
+        String target = "ui_" + rule.select((HttpServletRequest) request);
+        File zip = new File(new File(gen, pkg), target + ".zip");
+
+        synchronized (this) {
+          build(root, gen, "//" + pkg + ":" + target);
+
+          if (!target.equals(lastTarget) || lastTime != zip.lastModified()) {
+            lastTarget = target;
+            lastTime = zip.lastModified();
+            unpack(zip, dstwar);
+          }
+        }
+
+        chain.doFilter(request, res);
+      }
+
+      @Override
+      public void init(FilterConfig config) {
+      }
+
+      @Override
+      public void destroy() {
+      }
+    }), "/", EnumSet.of(DispatcherType.REQUEST));
+    return Resource.newResource(dstwar.toURI());
   }
 
   private static void build(File root, File gen, String target)
@@ -664,25 +658,4 @@
     }
     return properties;
   }
-
-  private Resource useMavenDeveloperBuild(File dir) throws IOException {
-    dir = dir.getParentFile(); // pop target
-    dir = dir.getParentFile(); // pop the module we are in
-
-    // Drop down into gerrit-gwtui to find the WAR assets we need.
-    //
-    dir = new File(new File(dir, "gerrit-gwtui"), "target");
-    final File[] entries = dir.listFiles();
-    if (entries == null) {
-      throw new FileNotFoundException("No " + dir);
-    }
-    for (File e : entries) {
-      if (e.isDirectory() /* must be a directory */
-          && e.getName().startsWith("gerrit-gwtui-")
-          && new File(e, "gerrit_ui/gerrit_ui.nocache.js").isFile()) {
-        return Resource.newResource(e.toURI());
-      }
-    }
-    throw new FileNotFoundException("No " + dir + "/gerrit-gwtui-*");
-  }
 }
diff --git a/tools/eclipse/buck_daemon_ui_dbg.launch b/tools/eclipse/buck_daemon_ui_dbg.launch
deleted file mode 100644
index a345f8a..0000000
--- a/tools/eclipse/buck_daemon_ui_dbg.launch
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/gerrit/gerrit-main/src/main/java/Main.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="Main"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="daemon --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../test_site"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgerrit.browser=ui_dbg"/>
-</launchConfiguration>
diff --git a/tools/eclipse/buck_daemon_ui_firefox.launch b/tools/eclipse/buck_daemon_ui_firefox.launch
deleted file mode 100644
index 383b051..0000000
--- a/tools/eclipse/buck_daemon_ui_firefox.launch
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/gerrit/gerrit-main/src/main/java/Main.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="Main"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="daemon --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../test_site"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgerrit.browser=ui_firefox"/>
-</launchConfiguration>
diff --git a/tools/eclipse/buck_daemon_ui_ie9.launch b/tools/eclipse/buck_daemon_ui_ie9.launch
deleted file mode 100644
index 18863e7..0000000
--- a/tools/eclipse/buck_daemon_ui_ie9.launch
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/gerrit/gerrit-main/src/main/java/Main.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="Main"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="daemon --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../test_site"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgerrit.browser=ui_ie9"/>
-</launchConfiguration>
diff --git a/tools/eclipse/buck_daemon_ui_safari.launch b/tools/eclipse/buck_daemon_ui_safari.launch
deleted file mode 100644
index 55259a9..0000000
--- a/tools/eclipse/buck_daemon_ui_safari.launch
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/gerrit/gerrit-main/src/main/java/Main.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="Main"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="daemon --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../test_site"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgerrit.browser=ui_safari"/>
-</launchConfiguration>
diff --git a/tools/eclipse/buck_daemon_ui_chrome.launch b/tools/eclipse/gerrit_daemon.launch
similarity index 89%
rename from tools/eclipse/buck_daemon_ui_chrome.launch
rename to tools/eclipse/gerrit_daemon.launch
index efe2623..c57a368 100644
--- a/tools/eclipse/buck_daemon_ui_chrome.launch
+++ b/tools/eclipse/gerrit_daemon.launch
@@ -9,8 +9,8 @@
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
 </listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="Main"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="daemon --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../test_site"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dgerrit.browser=ui_chrome"/>
 </launchConfiguration>
diff --git a/tools/eclipse/buck_gwt_debug.launch b/tools/eclipse/gerrit_gwt_debug.launch
similarity index 89%
rename from tools/eclipse/buck_gwt_debug.launch
rename to tools/eclipse/gerrit_gwt_debug.launch
index 1723cbf..3526e44 100644
--- a/tools/eclipse/buck_gwt_debug.launch
+++ b/tools/eclipse/gerrit_gwt_debug.launch
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/gerrit/buck-out/gen/lib/gwt/dev/gwt-dev-2.5.0.jar"/>
+<listEntry value="/gerrit/buck-out/gen/lib/gwt/dev/gwt-dev-2.5.1.jar"/>
 </listAttribute>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
 <listEntry value="1"/>
@@ -9,6 +9,7 @@
 <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
 </listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-startupUrl /&#10;-war ${resource_loc:/gerrit}/buck-out/gen/gerrit-gwtui/ui_dbg__tmp/war&#10;-server com.google.gerrit.gwtdebug.GerritDebugLauncher&#10;com.google.gerrit.GerritGwtUI"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>