Sunday, July 3, 2011

Re: Pluggable modules

Hi Mike,

How are the modules loaded and how are they invoked?

Berto

On Jun 22, 2:10 pm, manstis <michael.ans...@gmail.com> wrote:
> Great, lots to play with :)
>
> Before I look into writing my own JSNI bridge, I've still been trying
> to use gwt-exporter, but.....
>
> I've three GWT applications:-
> (1) Plugin (inherits "Common")
> (2) Backend (inherits "Common")
> (3) Common
>
> "Plugin"
> --------
> Contains:-
>
>   ...
>   echoButton.addClickHandler(new ClickHandler() {
>
>     public void onClick(ClickEvent event) {
>       //Debugging statements shown --> shows 'callback' is not null
>       PluginCallback<String> callback = getPluginCallback();
>       Window.alert("Plugin.onModuleLoad.onClick.callback is " +
> (callback != null ? "not " : "") + "null");
>
>       echo(text.getText(), callback);
>     }
>
>   });
>   ...
>
>   private native void echo(String text, PluginCallback<String>
> callback) /*-{
>     //Debugging statements shown --> shows 'callback' is not null
>     alert("Plugin.echo.callback is " + (callback != null ? "not " :
> "") + "null");
>
>     $wnd.com.anstis.pluginserver.CommonService.echo(text, callback);
>   }-*/;
>
> "Backend"
> --------
> Contains:-
>
>   public void onModuleLoad() {
>     //Use gwt-exporter to generate the JSNI for CommonService.class
>     GWT.create(CommonService.class);
>   }
>
> CommonService is:-
>
>   @Export
>   public class CommonService implements Exportable {
>
>     private static final EchoServiceAsync echoService =
> GWT.create(EchoService.class);
>
>     public static void echo(String input, PluginCallback<String>
> callback) {
>       //Debugging statements shown --> shows 'callback' is null
>       Window.alert("CommonService.echo.callback is " + (callback !=
> null ? "not " : "") + "null");
>       try {
>
>         //The guts of the method, invoke a GWT-RPC call --> RTE, as
> 'callback' is null
>         echoService.echo(input, callback);
>
>       } catch (Exception e) {
>         e.fillInStackTrace();
>         e.printStackTrace(System.out);
>         Window.alert(e.getMessage());
>       }
>     }
>
>   }
>
> "Common"
> --------
> Simply defines PluginCallback, as follows:-
>
>   public class PluginCallback<T> implements AsyncCallback<T> {
>     public void onFailure(Throwable caught) {}
>     public void onSuccess(T result) {}
>   }
>
> My problem is that the PluginCallback instance is proven to be non-
> null in "Plugin" (both Java and JSNI methods), but is reported as null
> in "Backends" CommonService.
>
> Somewhere it is getting munged, but I only pass a Java Object from
> "Plugin" to JSNI (echo) to Java (CommonService) so don't understand
> why it's being nulled?!?!
>
> Any ideas (I'll post as a new question if you don't see anything
> wrong, so it gets seen by a new audience as opposed to those just
> following this thread).
>
> Thanks,
>
> Mike
>
> On Jun 21, 7:32 pm,lemaiol<lema...@gmail.com> wrote:
>
>
>
>
>
>
>
> > Hi Mike,
>
> > > I am growing to believe I need to deploy each plug-in as a separate
> > > WAR on a web-server. Is this true, or have I missed something?
>
> > In the case of my architecture, it is even a requirement that every
> > plugin will be deployed as an own WAR file. It allows different teams
> > working in parallel in completely independent applications (plugins)
> > which have a common "message data model". When inside the plugins
> > container, they receive messages with this "common data model". When
> > out of the plugins container, the show a simplified UI to let the
> > developer pass a "message" generated by hand and therefore test the
> > application.
>
> > > I am also using gwt-exporter to make the JSNI messaging mechanism;
> > > i.e. I just write an "Exportable" class and use the resulting JS API
> > > from my plugins. I am hoping to use gwt-api-interop to remove the need
> > > to use the JS API.
>
> > I have seen gwt-exporter but do not know gwt-api-interop.
>
> > > I assume the JS "bridge" between GWT applications handles the
> > > messaging between them (i.e. plugins register callbacks to handle
> > > messages sent from the "host"?)
>
> > Yes.
>
> > > If I understand correctly, adding additional script tags to my
> > > "loader" page and having each plug-in as a separate WAR I avoid the
> > > need to inherit in my gwt.xml file?
>
> > My common model and plugin base classes live in a common GWT module
> > that each plugin inherits.
>
> > > An example of your use of JavaScriptObject in your messaging sub-
> > > system would be interesting....
>
> > // Application specific common model
> >  public final class CustomerInfo extends ModuleInfo {
> >     protected CustomerInfo() {
> >     }
>
> >     public native String getId() /*-{
> >         return this.id;
> >     }-*/;
>
> >     public native void setId(String id) /*-{
> >         this.id = id;
> >     }-*/;
>
> > }
>
> > // Base class for common models - no functionality as of now
> > public class ModuleInfo extends JavaScriptObject {
> >     protected ModuleInfo() {
> >     }
>
> > }
>
> > // To be implemented by every module
> > public interface IModule<T extends ModuleInfo> {
> >     public String getName();
> >     public void dispatch(String containerId, T moduleInfo);
>
> > }
>
> > // To be implemented by the main module or classes interested in
> > module lifecycle events
> > public interface IModuleAware<T extends ModuleInfo> {
> >     public void onModuleAttached(Module<T> module);
>
> > }
>
> > // Durable callback implementation - Because it uses JSNI, can be
> > inherited from GWT modules but it is interoperable. Avoids using gwt-
> > exporter
> > public final class ModuleListener<T extends ModuleInfo> extends
> > JavaScriptObject {
> >     protected ModuleListener() {
> >     }
>
> >     public void onModuleAttached(Module<T> module) {
> >         invokeCallback(getCallback(), module);
> >     }
>
> >     private native void invokeCallback(JavaScriptObject callback,
> > Module<T> module) /*-{
> >         this.callback(module);
> >     }-*/;
>
> >     private native JavaScriptObject getCallback() /*-{
> >         return this.callback;
> >     }-*/;
>
> >     public native void setCallback(JavaScriptObject callback) /*-{
> >         this.callback = callback;
> >     }-*/;
>
> > }
>
> > // Support for common modules functionality (static methods)
> > public abstract class ModulesSupport {
> >     public static <T extends ModuleInfo> boolean
> > registerAsListener(IModuleAware<T> instance) {
> >         ModulesConfig<T> modulesConfig = getModulesConfig();
> >         boolean result = null != modulesConfig;
> >         if (result) {
> >             modulesConfig.registerListener(createListener(instance));
> >         }
> >         return result;
> >     }
>
> >     public static <T extends ModuleInfo> boolean
> > registerAsModule(IModule<T> module) {
> >         ModulesConfig modulesConfig = ModulesConfig.get();
> >         boolean result = null != modulesConfig;
> >         if (result) {
> >             modulesConfig.attach(module.getName(),
> > createDispatchCallback(module));
> >         }
> >         return result;
> >     }
>
> >     public static <T extends ModuleInfo> ModulesConfig<T>
> > getModulesConfig() {
> >         return ModulesConfig.get();
> >     }
>
> >     private static <T extends ModuleInfo> ModuleListener<T>
> > createListener(IModuleAware<T> instance) {
> >         ModuleListener<T> result =
> > JavaScriptObject.createObject().cast();
> >         result.setCallback(createListenerCallback(instance));
> >         return result;
> >     }
>
> >     private static native JavaScriptObject
> > createListenerCallback(IModuleAware instance) /*-{
> >         return function(module) {
>
> > instan...@org.myexample.modules.client.IModuleAware::onModuleAttached(Lorg/
> > myexample/modules/client/Module;)(module);
> >         };
> >     }-*/;
>
> >     private static native JavaScriptObject
> > createDispatchCallback(IModule instance) /*-{
> >         return function(containerId, moduleInfo) {
>
> > instan...@org.myexample.modules.client.IModule::dispatch(Ljava/lang/
> > String;Lorg/myexample/modules/client/ModuleInfo;)(containerId,
> > moduleInfo);
> >         };
> >     }-*/;
>
> > }
>
> > Hope it helps,
> > Berto

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

No comments:

Post a Comment