XPages MVC: Experiment I

May 22, 2012, 5:28 PM

Tags: xpages mvc
  1. XPages MVC: Experiment I
  2. XPages MVC: Experiment II, Part 1
  3. XPages MVC: Experiment II, Part 2
  4. XPages MVC: Experiment II, Part 3
  5. XPages MVC: Experiment II, Part 4

Now that I've had a bit of time, I've started trying out some ideas for new ways to do XPage development. Specifically, I'm trying out the "XPages as the Controller" setup I pondered last time. The general goal is this:

  • There would be one XPage for each zone of concern (I don't know the right terminology): Posts.xsp, Users.xsp, etc.
  • The XPage itself would have almost nothing on it - it would exist as a trigger for the server to load an appropriate Controller class, which would in turn handle the output, usually by picking a custom control by name.
  • The custom control will handle all the appearance logic... and ONLY the appearance logic. The Controller will feed in any variables and data sources that are needed, and then the custom control will just reference those values entirely via EL.
  • The Controller will marshal will either create Domino View data sources directly or will use some wrapper Model class, in order to allow the XSP environment to handle efficiency and serialization.

So far, I've made some interesting progress. I originally set out to use a ViewHandler class to find the action and feed in the variables, but I ran into trouble getting to the viewScope or an equivalent in time for on-page-load value bindings to access them - either I was too early (before createView) or too late (after createView). What I really wanted was the beforePageLoad event, so I did just that: I created a view-scoped managed bean called "controller" that has some code to check what XPage is being loaded and to find a Controller class of the equivalent name (e.g. "Posts.xsp" → "xsp.controller.Posts"). Then, I do beforePageLoad="#{controller.control}" (I apologize for the names - I may change it to "router"), and it works nicely. The controller manager thing loads the class, asks it to figure out the current action ("list", "tag", etc.), and then tries to call a method by that name via reflection.

It sounds a bit weird, and the implementation is sort of half-baked, but the result is that you end up with a class with a structure like this (with actual implementation stuff removed):

public class Posts extends AbstractController { public void list() { ... } public void show() { ... } public void tag() { ... } }

Each of those methods corresponds to an action that can either be implied (like "list" being the default for Posts.xsp, established via other code) or derived from the URL, like "/Posts.xsp/show/1" to show the post with ID "1". The code in the method would fetch the appropriate object or collection and attach it to the XPage (as a dynamically-added data source, for example). Then, the XPage would load up an appropriate custom control for the action (for example, "pages_list" or "pages_show"), which would know what values to look for in the view scope.

I'm going to keep working on this, but I can think of a couple potential muddy areas:

  • I'm not sure how real data-backed custom controls (e.g. a list of posts by month in the sidebar) work into this. You can add beforePageLoad code in a custom control, but the view root is still the main page you're loading, so it's not as clean.
  • I'm not sure if it's worth trying to shuttle data source actions through the controller (like "save" for a document) or best to reference the methods in the model from the XPage directly. Since the environment is already "impure", I don't know how much bending-over-backwards is warranted.
  • The whole thing may be an exercise in cramming Rails-isms where they don't fit, like when someone familiar with SQL first starts programming for Domino. Just because something works doesn't mean it's correct for the platform.

I'm sure there will be more sticking points, too. Overall, though, this feels mostly good, or at least conceptually better than the other development paradigms I've tried with XPages. As the post title indicates, though, I expect this to be experiment number 1 of many.

Commenter Photo

Maksim Ravnovesov - May 24, 2012, 7:03 AM

Great Idea !

After learning Ruby and Ruby on Rails i was also struck by the lack of clear and recommended MVC implementation for XPages.

I see how strong the RoR influences your mindflow and it makes me happy too :)

Due to the fact that i've also spent some time, trying to figure out what is the best way to programm MVC way in XPAges, i can imagine that if you share whatever is developed up to date, i would jump in, trying to absorb your ideas and probably bringing my own.

Therefore, how do you think, would it be possible for you to upload whatever you have to OpenNTF (or to GitHub) so that i (and possibly others) could also use it ?

thanks,

was very glad to see your Blog entry :)

maksim

Commenter Photo

Jesse Gallagher - May 24, 2012, 8:26 AM

I definitely plan to upload any successful new code I write for these experiments. Most likely, I'll use whatever I figure out in the blog itself and then update its GitHub project. In the mean time, though, the dev copy is hopelessly broken and useless, so it's not suitable for the light of day.

Commenter Photo

Maksim Ravnovesov - May 24, 2012, 5:43 PM

ok, see your point :)

wish you then the fast and desirable results, which i'll be eager to participate in !

New Comment