MVP with multiple EntryPoints

317 views
Skip to first unread message

Cristian Rinaldi

unread,
Sep 11, 2012, 6:53:57 PM9/11/12
to google-we...@googlegroups.com
We have an application with multiple EntryPoints. Each EntryPoint contains an MVP configuration with their own PlaceHistoryHandler, PlaceHistoryMapper and PlaceController. Depending on the order that the history handlers were configured, the place treatment is overlapped. I think the problem is raised because the implementation of PlaceHistoryHandler invokes PlaceController.goTo(NOWHERE) when the PlaceHistoryMapper do not find the place, because this place is associated with the PlaceHistoryMapper of another EntryPoint. How I can solve this problem? It is right to use MVP with multiple EntryPoints?

Thanks in advance.

- Cristian

Thomas Broyer

unread,
Sep 12, 2012, 4:49:41 AM9/12/12
to google-we...@googlegroups.com

On Wednesday, September 12, 2012 12:53:58 AM UTC+2, Cristian Rinaldi wrote:
We have an application with multiple EntryPoints. Each EntryPoint contains an MVP configuration with their own PlaceHistoryHandler, PlaceHistoryMapper and PlaceController. Depending on the order that the history handlers were configured, the place treatment is overlapped. I think the problem is raised because the implementation of PlaceHistoryHandler invokes PlaceController.goTo(NOWHERE) when the PlaceHistoryMapper do not find the place, because this place is associated with the PlaceHistoryMapper of another EntryPoint. How I can solve this problem? It is right to use MVP with multiple EntryPoints?

First, Places (and Activities) have nothing to do with MVP.

To answer your question, I'd rather say it's not quite right to load several distinct apps in a page that tweak the URL and react to its changes, independently of the others. The thing is, the URL –as its name says– represents some "location" (hence the name "place" in GWT), and if you have several independent things on a page, there's no nothing like *one* location for the whole thing. You could use a "complex" URL containing the "state" of each subparts (e.g. moduleA=a&moduleB=b&moduleC=c), but that would be suboptimal in terms of user experience (back to the UX of frames, except with a bookmarkable URL).

Let's imagine for a second that you make your apps work by "ignoring" unknown places (that's what you were looking for right? avoiding the goTo(NOWHERE) –or whatever is your default place actually– when PlaceHistoryMapper doesn't understand the history token?).
  1. the app loads and displays A1, B1 and C1
  2. user navigates in each module:
    1. A2, B1, C1 ⇒ URL is #A2
    2. A2, B2, C1 ⇒ URL is #B2
    3. A2, B2, C2 ⇒ URL is #C2
  3. user uses his browser's back button ⇒ URL is #B2; nothing changes on screen, because module B is already at B2, and modules A and C ignore the place

Cristian Rinaldi

unread,
Sep 12, 2012, 7:29:25 AM9/12/12
to google-we...@googlegroups.com
Hi Thomas, thanks for your clarifications. Our scenery is a server side OSGI application, where application modules are hot deployed and contains their own GWT views and EntryPoints. 
Our main client GWT application has a dynamic side menu, with hyperlinks pointing to tokens associated with the external EntryPoints having views rendered in a main region.



  SIDE MENU
      |
      V
  -------------------------------------------
  |  A1  |                                  |
  |------  |                                  |
  |  A2  |                                  |
  |------  |                                  |
  |  B1  |                                  |
  |------  |    MAIN REGION        |
  |  B2  |                                  |
  |------  |                                  |
  |  C1  |                                  |
  |------  |                                  |
  |  C2  |                                  |
  -------------------------------------------


What is the right approach to solve this kind of application?

Thanks in advance.

- Cristian Rinaldi
- Andres Testi

Andrei

unread,
Sep 12, 2012, 8:20:05 AM9/12/12
to google-we...@googlegroups.com
Christian,

If you cannot restructure your app, consider using a Launchpad/Start Menu approach. You create the main entry point with a single view that shows a nice menu of apps available to your users. Each menu item is basically a link to a starting URL for a corresponding module (entry point). When a user clicks on it, this module loads and takes over the entire screen. I would also add an icon to each module to go back to the launchpad.

This way users can bookmark a launchpad, or they can bookmark any module directly.

Note that in this approach URL history would work as expected, i.e. if a user goes Launchpad -> A1 -> A2 -> Launchpad -> B1, etc., a user can hit the back button and the browser will go back one step.

Alternatively, each module can open in a new browser tab. Maybe you can give users an option to choose same tab or new tab somewhere in preferences.

Note that all users of smartphones and tablets are familiar with Launchpad/Start Menu approach, which is also used in Mac OS and, soon, Windows 8. An additional benefit is that each module/app has more screen space to work with.

Andrei

Andrei

unread,
Sep 12, 2012, 8:26:00 AM9/12/12
to google-we...@googlegroups.com
Christian,

I should have a mentioned a more obvious solution too.

Don't use PlaceController for the side menu. Make it a widget that contains links to places in your modules. You can include this widget in each module. When a menu item is clicked, the entire page reloads. This way browser history will work as expected.

Andrei

Cristian Rinaldi

unread,
Sep 12, 2012, 11:25:05 AM9/12/12
to google-we...@googlegroups.com
Andrei, thanks for response.
In our architecture we have a MainModule that manages all aspects from Layout visualization, e.g. to request for maximization in the central region, or to request for display another region in the general layout. Also defines common places that are used by other modules, e.g. ConfigurePlace, FindGloblaPlace. In that case, the main module reacts by setting the layout.

This MainModule define some handlers to response a request from the other modules (entry points) over localization in the Layout.
Our MainModule registers all modules in the aplication, exists modules that are entry points and others that are inside distribution (same compilation). The MainModule in itself is an module.

Your proposed solution is ok, but, the fact of reload pages for each link of module, disables the posibility to manage external Layout from a MainModule.
We want to make each module to have their own stack of places, placehistorymapper, placecontroller and placehistoryhandler, event MainModule. 

Joseph Lust

unread,
Sep 12, 2012, 2:30:37 PM9/12/12
to google-we...@googlegroups.com
Christian,

My team has spent the last month porting our large GWT application over to OSGi. Allow me to share:

We too need to load many GWT entry points and show a consolidated home page showing the currently available modules. However, rather than using Activities and Places to get the browser to see the modules, we dynamically registered a new context on the OSGi native container. We also used the module rename-to option to map com.longpkg.module.client.Module to /module.

A new GWT module is deployed as a service bundle (the backend Java) and the GWT css/img/js as a fragment. When a new GWT module is deployed, the service registers itself and also an ApplicationInfo object. The ApplicationInfo object has information such as the context name, like module_b. This context is registered as a servlet to serve up the GWT static content and the RPC servlets are registered below it (/module_b/myRpcServlet).

Finally, the home page calls a servlet to get the list of current registered modules by returning all registered ApplicationInfo objects and draws them to the page. The OSGi beauty if of course that by turning modules on/off, the links automatically appear/disappear from the home page. And, if a user attempts a link to an unregistered context (i.e. removed) then they just get forwarded back to the landing page.


Sing out with any other OSGi GWT issues, I thought we were the only people out there doing this. ;)

Sincerely,
Joseph 
 
 

 

David

unread,
Sep 13, 2012, 10:41:18 AM9/13/12
to google-we...@googlegroups.com

 Great thread.

For simplicity , I use a single EntryPoint for multiple urls.  Code splitting ensures that I'm only bringing in what I need for a given request.    Are there guidelines for moving to multiple EntryPoints.   (besides OSGI).
thanks

Cristian Rinaldi

unread,
Nov 8, 2012, 5:59:27 PM11/8/12
to google-we...@googlegroups.com
Hi Joseph:

Thanks a lot, it was an interesting answer. Beyond GWT, I'm courious about how are you managing dinamyc ORM extensions, i.e. if you are using JPA, how are you merging domain classes from several OSGi bundles.

Best regards.

- Cristian

Joseph Lust

unread,
Nov 8, 2012, 8:53:39 PM11/8/12
to google-we...@googlegroups.com
Christian,

Sorry I missed your gchat the other day. Most gServices are blocked at my office.

Thanks a lot, it was an interesting answer. Beyond GWT, I'm curious about how are you managing dynamic ORM extensions, i.e. if you are using JPA, how are you merging domain classes from several OSGi bundles.

We have a totally isolated model to deal with the domain objects. module_B has its own Spring services running in the OSGi container that serves up the dynamic content for module_B and uses its own schema and JNDI connection pool. The static content (compiled GWT) for module_B is served up by the aforementioned fragment attached to the module_B context. This way module_B and module_A can be upgraded completely independently of each other.

Of course there are some objects which are shared in the GWT codebase (DTO's). These are in a common library inherited by all the modules that use it. Because we use Maven and versioning, we don't have to update all consumers of the common library and can run multiple versions on multiple modules.

There are some shared services that multiple modules use, but these are consumed via JSON and Autobean (have not tried RequestFactory yet) since GWT-RPC is compile dependent for each module.

I hope that helps.

Sincerely,
Joseph

Cristian Rinaldi

unread,
Nov 12, 2012, 11:48:41 AM11/12/12
to google-we...@googlegroups.com
Joseph, thanks a lot for your predisposition!!!!
Another question but no less important:

You are using injection of dependency in the projects, e.g: peaberry with Guice or Weld?

Greetings!!

-Cristian

Joseph R Lust

unread,
Nov 16, 2012, 7:12:21 PM11/16/12
to google-we...@googlegroups.com
Cristian,

We are running Spring, we we use Spring DI in the Spring container.


Sincerely,
Joseph

~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*
Joseph R Lust
(919) 355-8785
joseph...@gmail.com


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/_Am7ZwyGMQkJ.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Reply all
Reply to author
Forward
0 new messages