Hi guys, I've improved the original plugin infrastructure, please find the 2nd revision of UI Plugins proof-of-concept (PoC) patch attached.
Here's a quick summary of changes: * PluginSourcePageServlet looks up the actual plugin code in local filesystem (<pluginName>.js), so you can experiment with different plugins. If you want to add new plugins, just modify WebadminDynamicHostingServlet.writeAdditionalJsData() method. * PluginManager now calls UiInit function on plugins (plugin objects) within the scope of WebAdmin main section (user has logged in, main section UI is initialized and ready), and disables plugin execution outside main section (e.g. when the user logs out) . (Please find a sample plugin code attached as well. PluginSourcePageServlet tries to load it from a hard-coded location in local filesystem, you probably want to modify this to suit your environment.) UiInit function is a special event handler function that gets called once, after plugin reports as ready, and before other event handler functions are called. UiInit function would be a good place to extend default WebAdmin UI (adding main tab, etc.). This is illustrated on the following use case: 1. user requests WebAdmin page, during initialization a plugin iframe gets created and attached to DOM, plugin HTML page gets requested asynchronously, application init code still runs so iframe plugin code evaluation is blocked (this is because of JavaScript runtime being single-threaded in its nature) 2. application init code finishes, plugin code gets evaluated, plugin registers itself into pluginApi.plugins and reports back as ready (calls the ready function) 3. since the user is still in login section (not logged into WebAdmin), plugin invocation is disabled, until the user logs in 4. user logs into the application, UI redirects to main section, and after UI gets initialized, plugin invocation is enabled 5. UiInit function is called on the plugin 6. <NOT IMPLEMENTED YET> user performs some actions and WebAdmin calls different functions on the plugin 7. assume the user logs out, plugin invocation is disabled, until the user logs in again 8. user logs in again, but UiInit isn't called now because it has been called already before 9. goto step 6 The reason why UiInit is called just once (after visiting main section for the first time), is because WebAdmin UI (Views) are mostly singletons, so even when you switch to different section (login section) and go to main section again, singleton Views will still be there, with any adjustments/extensions made previously by plugins. Now, as for the next steps, we can proceed with actual tasks Itamar outlined in his email: * use UiInit event to extend UI (add main tab, etc.) * define other events (table context menu event, etc.) * allow plugins to do REST API calls through pluginApi object I've tried to implement "add main tab" functionality. Unfortunately, this isn't quite easy to do with GWT-Platform (GWTP) framework we use. Each tab in WebAdmin has some place (GWT history token = URL hash fragment) associated. The way GWTP handles tabs is that individual tabs (Presenter) reveal themselves into tab container (TabContainerPresenter), with presenter reveal flow being processed bottom-up. I strongly suggest to go through [http://code.google.com/p/gwt-platform/wiki/GettingStarted] to get some basic understanding of GWTP framework and how tabs work in general. Long story short, to add tabs dynamically in a proper way, we need to write custom presenter proxy, here are some links on this matter: Discussion [https://groups.google.com/forum/#!topic/gwt-platform/aJrGOf9Gu04/discussion ] Dynamic tab example [http://code.google.com/r/goudreauchristian-update/source/browse/ ] Working demo [http://olivier.monaco.free.fr/lab/gwtp-editor/] So adding main/sub tabs is a task that will require some additional work, especially since we wish to combine both static tabs and dynamic tabs in one tab container. I'll try to work on this one. On the other hand, it would be great if others could take the latest PoC patch (attached), and experiment with other stuff like context menu events, REST API calls, etc. You can always reach me on #ovirt (vszocs) if you have a question or need help with anything. Cheers, Vojtech
myPlugin.js.example
Description: Binary data
From 68a36755c1f8588224de0ce36910c574b33a64e6 Mon Sep 17 00:00:00 2001 From: Vojtech Szocs <vsz...@redhat.com> Date: Thu, 19 Jul 2012 14:48:40 +0200 Subject: [PATCH] WIP: UI Plugins PoC, revision 2 Change-Id: Id28812ddbe90574de0178f0c07da713fe9fd8cda Signed-off-by: Vojtech Szocs <vsz...@redhat.com> --- .../server/gwt/GwtDynamicHostPageServlet.java | 1 + .../server/gwt/PluginSourcePageServlet.java | 111 +++++++++++ .../server/gwt/WebadminDynamicHostingServlet.java | 4 + .../ovirt/engine/ui/webadmin/gin/SystemModule.java | 4 + .../ui/webadmin/plugin/PluginDefinitions.java | 30 +++ .../ui/webadmin/plugin/PluginEventHandler.java | 23 +++ .../engine/ui/webadmin/plugin/PluginManager.java | 199 ++++++++++++++++++++ .../main/presenter/MainSectionPresenter.java | 17 ++- .../webadmin/src/main/webapp/WEB-INF/web.xml | 10 + 9 files changed, 398 insertions(+), 1 deletions(-) create mode 100644 frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/PluginSourcePageServlet.java create mode 100644 frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginDefinitions.java create mode 100644 frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginEventHandler.java create mode 100644 frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginManager.java diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java index f19739a..685e685 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GwtDynamicHostPageServlet.java @@ -46,6 +46,7 @@ public abstract class GwtDynamicHostPageServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter writer = response.getWriter(); response.setContentType("text/html; charset=UTF-8"); //$NON-NLS-1$ + response.setHeader("Cache-Control", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$ writer.append("<!DOCTYPE html><html><head>"); //$NON-NLS-1$ writer.append("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">"); //$NON-NLS-1$ diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/PluginSourcePageServlet.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/PluginSourcePageServlet.java new file mode 100644 index 0000000..b0342a8 --- /dev/null +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/PluginSourcePageServlet.java @@ -0,0 +1,111 @@ +package org.ovirt.engine.ui.frontend.server.gwt; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Renders the HTML source page for the given UI plugin. + */ +public class PluginSourcePageServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private static Log logger = LogFactory.getLog(PluginSourcePageServlet.class); + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + // Read plugin name as HTTP request parameter + String pluginName = request.getParameter("plugin"); //$NON-NLS-1$ + if (pluginName == null) { + logger.error("Missing plugin name request parameter"); //$NON-NLS-1$ + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return; + } + + // Locate plugin code in local file system + // TODO hard-coded plugin location + File pluginCodeLocation = new File("/home/vszocs/Downloads"); //$NON-NLS-1$ + File pluginCodeFile = new File(pluginCodeLocation, pluginName + ".js"); //$NON-NLS-1$ + if (!pluginCodeFile.isFile() || !pluginCodeFile.canRead()) { + logger.error("Cannot read plugin code: " + pluginCodeFile.getAbsolutePath()); //$NON-NLS-1$ + response.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + + // TODO simulate plugin dependencies + List<String> pluginDependencyList = + Arrays.asList("https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"); //$NON-NLS-1$ + + // TODO simulate plugin configuration + String pluginConfigurationObject = "{ \"foo\": 123 }"; //$NON-NLS-1$ + + // Render HTML source page to the output + response.setContentType("text/html; charset=UTF-8"); //$NON-NLS-1$ + response.setHeader("Cache-Control", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$ + + Reader in = null; + Writer out = null; + + try { + in = new BufferedReader(new InputStreamReader(new FileInputStream(pluginCodeFile), "UTF-8")); //$NON-NLS-1$ + out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8")); //$NON-NLS-1$ + + renderPluginSourcePage(in, pluginDependencyList, pluginConfigurationObject, out); + out.flush(); + } finally { + if (in != null) { + in.close(); + } + } + } + + void renderPluginSourcePage(Reader pluginCodeInput, List<String> pluginDependencyList, + String pluginConfigurationObject, Writer output) throws IOException { + output.write("<!DOCTYPE html><html><head>"); //$NON-NLS-1$ + output.write("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">"); //$NON-NLS-1$ + + for (String dependency : pluginDependencyList) { + output.write("<script type=\"text/javascript\" src=\""); //$NON-NLS-1$ + output.write(dependency); + output.write("\"></script>"); //$NON-NLS-1$ + } + + output.write("</head><body>"); //$NON-NLS-1$ + output.write("<script type=\"text/javascript\">"); //$NON-NLS-1$ + output.write("(function( pluginApi, pluginConfig ) {"); //$NON-NLS-1$ + + copyChars(pluginCodeInput, output); + + output.write("}) ( parent.pluginApi, "); //$NON-NLS-1$ + output.write(pluginConfigurationObject); + output.write(" );"); //$NON-NLS-1$ + output.write("</script>"); //$NON-NLS-1$ + output.write("</body></html>"); //$NON-NLS-1$ + } + + void copyChars(Reader in, Writer out) throws IOException { + char[] buffer = new char[4 * 1024]; // Use 4 kB buffer + int numRead = 0; + + while ((numRead = in.read(buffer, 0, buffer.length)) > 0) { + out.write(buffer, 0, numRead); + } + } + +} diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebadminDynamicHostingServlet.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebadminDynamicHostingServlet.java index 428dcc5..dcaf49a 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebadminDynamicHostingServlet.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/WebadminDynamicHostingServlet.java @@ -36,6 +36,10 @@ public class WebadminDynamicHostingServlet extends GwtDynamicHostPageServlet { appModeData.put("value", String.valueOf(applicationMode)); //$NON-NLS-1$ writeJsObject(writer, "applicationMode", appModeData); //$NON-NLS-1$ } + + Map<String, String> pluginDefinitions = new HashMap<String, String>(); + pluginDefinitions.put("myPlugin", "/webadmin/webadmin/PluginSourcePage?plugin=myPlugin"); //$NON-NLS-1$ //$NON-NLS-2$ + writeJsObject(writer, "pluginDefinitions", pluginDefinitions); //$NON-NLS-1$ } private Integer getApplicationMode(HttpServletRequest request) { diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java index 3069b99..b049683 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/SystemModule.java @@ -9,6 +9,8 @@ import org.ovirt.engine.ui.webadmin.ApplicationResources; import org.ovirt.engine.ui.webadmin.ApplicationTemplates; import org.ovirt.engine.ui.webadmin.place.ApplicationPlaces; import org.ovirt.engine.ui.webadmin.place.WebAdminPlaceManager; +import org.ovirt.engine.ui.webadmin.plugin.PluginEventHandler; +import org.ovirt.engine.ui.webadmin.plugin.PluginManager; import org.ovirt.engine.ui.webadmin.system.ApplicationInit; import org.ovirt.engine.ui.webadmin.system.InternalConfiguration; @@ -31,6 +33,8 @@ public class SystemModule extends BaseSystemModule { bind(PlaceManager.class).to(WebAdminPlaceManager.class).in(Singleton.class); bind(ApplicationInit.class).asEagerSingleton(); bind(InternalConfiguration.class).asEagerSingleton(); + bind(PluginManager.class).asEagerSingleton(); + bind(PluginEventHandler.class).asEagerSingleton(); } void bindConfiguration() { diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginDefinitions.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginDefinitions.java new file mode 100644 index 0000000..d1118cb --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginDefinitions.java @@ -0,0 +1,30 @@ +package org.ovirt.engine.ui.webadmin.plugin; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArrayString; + +/** + * Overlay type for {@code pluginDefinitions} global JS object. + */ +public final class PluginDefinitions extends JavaScriptObject { + + protected PluginDefinitions() { + } + + public static native PluginDefinitions instance() /*-{ + return $wnd.pluginDefinitions; + }-*/; + + public native JsArrayString getPluginNames() /*-{ + var pluginNames = []; + for (var key in this) { + pluginNames.push(key); + } + return pluginNames; + }-*/; + + public native String getPluginSourcePageUrl(String pluginName) /*-{ + return this[pluginName]; + }-*/; + +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginEventHandler.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginEventHandler.java new file mode 100644 index 0000000..cbafb2f --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginEventHandler.java @@ -0,0 +1,23 @@ +package org.ovirt.engine.ui.webadmin.plugin; + +import com.google.gwt.event.shared.EventBus; +import com.google.inject.Inject; + +/** + * Handles WebAdmin application events (extension points) to be consumed by UI plugins. + * <p> + * Should be bound as GIN eager singleton, created early on during application startup. + */ +public class PluginEventHandler { + + @Inject + public PluginEventHandler(EventBus eventBus, PluginManager manager) { +// eventBus.addHandler(ExtUserLoginEvent.getType(), new ExtUserLoginHandler() { +// @Override +// public void onExtUserLogin(ExtUserLoginEvent event) { +// invokePlugins("UserLogin"); +// } +// }); + } + +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginManager.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginManager.java new file mode 100644 index 0000000..5663a09 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/plugin/PluginManager.java @@ -0,0 +1,199 @@ +package org.ovirt.engine.ui.webadmin.plugin; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArrayString; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.IFrameElement; +import com.google.gwt.dom.client.Style.BorderStyle; +import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.Style.Unit; + +/** + * The main component of WebAdmin UI plugin infrastructure. + * <p> + * Should be bound as GIN eager singleton, created early on during application startup. + */ +public class PluginManager { + + private static final Logger logger = Logger.getLogger(PluginManager.class.getName()); + + // Maps plugin names to corresponding iframe elements + private final Map<String, IFrameElement> pluginIFrames = new HashMap<String, IFrameElement>(); + + // Maps plugin names to corresponding plugin objects (only for plugins which are currently ready) + private final Map<String, JavaScriptObject> pluginObjects = new HashMap<String, JavaScriptObject>(); + + // Contains plugin names for plugins that have been initialized + // (UiInit event handler function was already called on corresponding plugin objects) + private final Set<String> initializedPlugins = new HashSet<String>(); + + // Controls plugin invocation, allowing WebAdmin to call plugins only within a specific application context + private boolean canInvokePlugins = false; + + public PluginManager() { + exposePluginApi(); + loadPlugins(); + } + + /** + * Called when WebAdmin enters the state that allows plugins to be invoked. + */ + public void enablePluginInvocation() { + canInvokePlugins = true; + + // Try to initialize all plugins which are currently ready + for (String pluginName : pluginObjects.keySet()) { + initPlugin(pluginName); + } + } + + /** + * Called when WebAdmin leaves the state that allows plugins to be invoked. + */ + public void disablePluginInvocation() { + canInvokePlugins = false; + } + + boolean isPluginReady(String pluginName) { + return pluginObjects.containsKey(pluginName); + } + + boolean isPluginInitialized(String pluginName) { + return initializedPlugins.contains(pluginName); + } + + /** + * Initialize the given plugin by calling UiInit event handler function on the corresponding plugin object. + * <p> + * Note that UiInit event handler function will be called just once during the lifetime of a plugin. + */ + void initPlugin(String pluginName) { + if (canInvokePlugins && isPluginReady(pluginName) && !isPluginInitialized(pluginName)) { + JavaScriptObject pluginObject = pluginObjects.get(pluginName); + invokePlugin(pluginObject, "UiInit", null); //$NON-NLS-1$ + + initializedPlugins.add(pluginName); + } + } + + /** + * Invokes an event handler function on all plugins which are currently ready. + */ + public void invokePlugins(String functionName, JavaScriptObject contextObject) { + if (canInvokePlugins) { + for (String pluginName : pluginObjects.keySet()) { + if (isPluginInitialized(pluginName)) { + invokePlugin(pluginObjects.get(pluginName), functionName, contextObject); + } + } + } + } + + /** + * Invokes an event handler function on the given plugin object. + */ + private native void invokePlugin(JavaScriptObject pluginObject, String functionName, JavaScriptObject contextObject) /*-{ + var handlerFunction = pluginObject[functionName]; + + if (typeof handlerFunction === 'function') { + if (contextObject != null) { + handlerFunction(contextObject); + } else { + handlerFunction(); + } + } + }-*/; + + /** + * Loads all plugins that were detected when serving WebAdmin host page. + */ + void loadPlugins() { + PluginDefinitions defs = PluginDefinitions.instance(); + + if (defs != null) { + JsArrayString pluginNames = defs.getPluginNames(); + + for (int i = 0; i < pluginNames.length(); i++) { + String name = pluginNames.get(i); + String sourcePageUrl = defs.getPluginSourcePageUrl(name); + + logger.info("Loading plugin [" + name + "] from URL " + sourcePageUrl); //$NON-NLS-1$ //$NON-NLS-2$ + loadPlugin(name, sourcePageUrl); + } + } + } + + /** + * Loads a plugin using its source page (HTML page that executes the actual plugin code). + * <p> + * WebAdmin requires all plugins to have a source page because each plugin runs within the context of an iframe. + */ + void loadPlugin(String pluginName, String pluginSourcePageUrl) { + if (pluginIFrames.containsKey(pluginName)) { + logger.warning("Plugin [" + pluginName + "] is already loaded"); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } + + // Create an iframe used to load the plugin source page + IFrameElement iframe = Document.get().createIFrameElement(); + iframe.setSrc(pluginSourcePageUrl); + iframe.setFrameBorder(0); + iframe.getStyle().setPosition(Position.ABSOLUTE); + iframe.getStyle().setWidth(0, Unit.PT); + iframe.getStyle().setHeight(0, Unit.PT); + iframe.getStyle().setBorderStyle(BorderStyle.NONE); + pluginIFrames.put(pluginName, iframe); + + // Attach the iframe to DOM document body + Document.get().getBody().appendChild(iframe); + } + + /** + * Indicates that the given plugin is ready for use. + */ + void pluginReady(String pluginName, JavaScriptObject pluginObject) { + if (pluginName == null) { + logger.warning("Plugin name is null or undefined"); //$NON-NLS-1$ + return; + } + + if (!pluginIFrames.containsKey(pluginName)) { + logger.warning("Plugin [" + pluginName + "] reports in as ready, but has no iframe associated"); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } + + // Register the plugin object + pluginObjects.put(pluginName, pluginObject); + logger.info("Plugin [" + pluginName + "] is ready for use"); //$NON-NLS-1$ //$NON-NLS-2$ + + // Try to initialize the plugin + initPlugin(pluginName); + } + + private native void exposePluginApi() /*-{ + var instance = this; + + // Expose the global pluginApi object + $wnd.pluginApi = { + + // Plugins will register themselves into this object by adding new property: + // - property name is the name of the plugin + // - property value is the plugin object containing event handler functions + plugins: {}, + + // Plugins will call this function to indicate that they are ready for use + ready: function(pluginName) { + var pluginObject = this.plugins[pluginName]; + instan...@org.ovirt.engine.ui.webadmin.plugin.PluginManager::pluginReady(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)(pluginName,pluginObject); + } + + }; + }-*/; + +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/MainSectionPresenter.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/MainSectionPresenter.java index 718d8fc..15b887c 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/MainSectionPresenter.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/MainSectionPresenter.java @@ -1,5 +1,7 @@ package org.ovirt.engine.ui.webadmin.section.main.presenter; +import org.ovirt.engine.ui.webadmin.plugin.PluginManager; + import com.google.gwt.event.shared.EventBus; import com.google.gwt.event.shared.GwtEvent.Type; import com.google.inject.Inject; @@ -28,11 +30,13 @@ public class MainSectionPresenter extends Presenter<MainSectionPresenter.ViewDef public static final Type<RevealContentHandler<?>> TYPE_SetMainContent = new Type<RevealContentHandler<?>>(); private final HeaderPresenterWidget header; + private final PluginManager pluginManager; @Inject - public MainSectionPresenter(EventBus eventBus, ViewDef view, ProxyDef proxy, HeaderPresenterWidget header) { + public MainSectionPresenter(EventBus eventBus, ViewDef view, ProxyDef proxy, HeaderPresenterWidget header, PluginManager pluginManager) { super(eventBus, view, proxy); this.header = header; + this.pluginManager = pluginManager; getView().setUiHandlers(header); } @@ -46,6 +50,17 @@ public class MainSectionPresenter extends Presenter<MainSectionPresenter.ViewDef super.onReveal(); setInSlot(TYPE_SetHeader, header); + + // Enable plugin invocation within the scope of main section + pluginManager.enablePluginInvocation(); + } + + @Override + protected void onHide() { + super.onHide(); + + // Disable plugin invocation outside the scope of main section + pluginManager.disablePluginInvocation(); } } diff --git a/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml b/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml index a50f8aa..62f0312 100644 --- a/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml +++ b/frontend/webadmin/modules/webadmin/src/main/webapp/WEB-INF/web.xml @@ -23,6 +23,16 @@ <url-pattern>/webadmin/WebAdmin.html</url-pattern> </servlet-mapping> + <servlet> + <servlet-name>PluginSourcePage</servlet-name> + <servlet-class>org.ovirt.engine.ui.frontend.server.gwt.PluginSourcePageServlet</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>PluginSourcePage</servlet-name> + <url-pattern>/webadmin/PluginSourcePage</url-pattern> + </servlet-mapping> + <!-- Default page to serve --> <welcome-file-list> <welcome-file>index.html</welcome-file> -- 1.7.4.4
_______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel