From f721eb5772f1fbb43d9b16fb4d33ca82c162151f Mon Sep 17 00:00:00 2001 From: Luca Milanesio Date: Wed, 9 Jul 2014 10:05:28 +0100 Subject: [PATCH] Auto register static/init.js as JavaScript plugin When plugin does not expose Guice Modules explicitly, auto discover and register static/init.js as WebUi extension if found by the plugin content scanner. This simplify JavaScript development from now on no Java (or other scripting) code/classes are required to extend Gerrit WebUi. (based on the idea and initial patch by Dariusz: Ia5b3cb63f62) Change-Id: I8c793764ac1876dc62d740d28c0d4cf6b9409b10 --- .../extensions/webui/JavaScriptPlugin.java | 3 +++ .../HttpAutoRegisterModuleGenerator.java | 21 ++++++++++++++++-- .../httpd/plugins/HttpPluginModule.java | 3 ++- .../server/plugins/AutoRegisterModules.java | 22 ++++++++++++++++++- .../server/plugins/HttpModuleGenerator.java | 19 ++++++++++++++++ .../plugins/PluginGuiceEnvironment.java | 6 ++--- 6 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 gerrit-server/src/main/java/com/google/gerrit/server/plugins/HttpModuleGenerator.java diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/webui/JavaScriptPlugin.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/webui/JavaScriptPlugin.java index 89a4f33595..4619a06a66 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/webui/JavaScriptPlugin.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/webui/JavaScriptPlugin.java @@ -16,6 +16,9 @@ package com.google.gerrit.extensions.webui; /** Configures a web UI plugin written using JavaScript. */ public class JavaScriptPlugin extends WebUiPlugin { + public static final String INIT_JS = "init.js"; + public static final String STATIC_INIT_JS = "static/" + INIT_JS; + private final String fileName; /** diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpAutoRegisterModuleGenerator.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpAutoRegisterModuleGenerator.java index d1c617f069..0e81a0d9c8 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpAutoRegisterModuleGenerator.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpAutoRegisterModuleGenerator.java @@ -14,14 +14,18 @@ package com.google.gerrit.httpd.plugins; +import static com.google.common.base.Preconditions.checkState; import static com.google.gerrit.server.plugins.AutoRegisterUtil.calculateBindAnnotation; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.gerrit.extensions.annotations.Export; +import com.google.gerrit.extensions.registration.DynamicSet; +import com.google.gerrit.extensions.webui.JavaScriptPlugin; +import com.google.gerrit.extensions.webui.WebUiPlugin; +import com.google.gerrit.server.plugins.HttpModuleGenerator; import com.google.gerrit.server.plugins.InvalidPluginException; -import com.google.gerrit.server.plugins.ModuleGenerator; import com.google.inject.Module; import com.google.inject.Scopes; import com.google.inject.TypeLiteral; @@ -33,9 +37,10 @@ import java.util.Map; import javax.servlet.http.HttpServlet; class HttpAutoRegisterModuleGenerator extends ServletModule - implements ModuleGenerator { + implements HttpModuleGenerator { private final Map> serve = Maps.newHashMap(); private final Multimap, Class> listeners = LinkedListMultimap.create(); + private String javascript; @Override protected void configureServlets() { @@ -53,6 +58,10 @@ class HttpAutoRegisterModuleGenerator extends ServletModule Annotation n = calculateBindAnnotation(impl); bind(type).annotatedWith(n).to(impl); } + if (javascript != null) { + DynamicSet.bind(binder(), WebUiPlugin.class).toInstance( + new JavaScriptPlugin(javascript)); + } } @Override @@ -79,6 +88,14 @@ class HttpAutoRegisterModuleGenerator extends ServletModule } } + @Override + public void export(String javascript) { + checkState(this.javascript == null, + "Multiple JavaScript plugins detected: %s, %s", this.javascript, + javascript); + this.javascript = javascript; + } + @Override public void listen(TypeLiteral tl, Class clazz) { listeners.put(tl, clazz); diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginModule.java index 5dc7e2e74d..ba5df51595 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginModule.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginModule.java @@ -15,6 +15,7 @@ package com.google.gerrit.httpd.plugins; import com.google.gerrit.server.cache.CacheModule; +import com.google.gerrit.server.plugins.HttpModuleGenerator; import com.google.gerrit.server.plugins.ModuleGenerator; import com.google.gerrit.server.plugins.ReloadPluginListener; import com.google.gerrit.server.plugins.StartPluginListener; @@ -37,7 +38,7 @@ public class HttpPluginModule extends ServletModule { .annotatedWith(UniqueAnnotations.create()) .to(HttpPluginServlet.class); - bind(ModuleGenerator.class) + bind(HttpModuleGenerator.class) .to(HttpAutoRegisterModuleGenerator.class); install(new CacheModule() { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/AutoRegisterModules.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/AutoRegisterModules.java index 6f1204be86..759700ec3f 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/AutoRegisterModules.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/AutoRegisterModules.java @@ -23,12 +23,17 @@ import com.google.common.collect.Sets; import com.google.gerrit.extensions.annotations.Export; import com.google.gerrit.extensions.annotations.ExtensionPoint; import com.google.gerrit.extensions.annotations.Listen; +import com.google.gerrit.extensions.webui.JavaScriptPlugin; import com.google.gerrit.server.plugins.PluginContentScanner.ExtensionMetaData; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.Scopes; import com.google.inject.TypeLiteral; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.util.Arrays; @@ -36,12 +41,14 @@ import java.util.Map; import java.util.Set; class AutoRegisterModules { + private static final Logger log = LoggerFactory.getLogger(AutoRegisterModules.class); + private final String pluginName; private final PluginGuiceEnvironment env; private final PluginContentScanner scanner; private final ClassLoader classLoader; private final ModuleGenerator sshGen; - private final ModuleGenerator httpGen; + private final HttpModuleGenerator httpGen; private Set> sysSingletons; private Multimap, Class> sysListen; @@ -117,6 +124,19 @@ class AutoRegisterModules { for (ExtensionMetaData listener : extensions.get(Listen.class)) { listen(listener); } + exportInitJs(); + } + + private void exportInitJs() { + try { + if (scanner.getEntry(JavaScriptPlugin.STATIC_INIT_JS).isPresent()) { + httpGen.export(JavaScriptPlugin.INIT_JS); + } + } catch (IOException e) { + log.warn(String.format("Cannot access %s from plugin %s: " + + "JavaScript auto-discovered plugin will not be registered", + JavaScriptPlugin.STATIC_INIT_JS, pluginName), e); + } } private void export(ExtensionMetaData def) throws InvalidPluginException { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/HttpModuleGenerator.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/HttpModuleGenerator.java new file mode 100644 index 0000000000..44b24342bf --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/HttpModuleGenerator.java @@ -0,0 +1,19 @@ +// Copyright (C) 2014 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.server.plugins; + +public interface HttpModuleGenerator extends ModuleGenerator { + void export(String javascript); +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java index 5b63a21561..fbc95c99c4 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginGuiceEnvironment.java @@ -83,7 +83,7 @@ public class PluginGuiceEnvironment { private Module httpModule; private Provider sshGen; - private Provider httpGen; + private Provider httpGen; private Map, DynamicItem> sysItems; private Map, DynamicItem> sshItems; @@ -187,7 +187,7 @@ public class PluginGuiceEnvironment { public void setHttpInjector(Injector injector) { httpModule = copy(injector); - httpGen = injector.getProvider(ModuleGenerator.class); + httpGen = injector.getProvider(HttpModuleGenerator.class); httpItems = dynamicItemsOf(injector); httpSets = dynamicSetsOf(injector); httpMaps = dynamicMapsOf(injector); @@ -204,7 +204,7 @@ public class PluginGuiceEnvironment { return httpModule; } - ModuleGenerator newHttpModuleGenerator() { + HttpModuleGenerator newHttpModuleGenerator() { return httpGen.get(); }