Using a ViewHandler to Serve a Different XPage
Sat May 03 10:55:26 EDT 2014
I've been using a ViewHandler
class for a while now for a specific purpose: injecting controller objects automatically. However, I hadn't really dug into them further than that. I should have, though: I spent a little time poking around this morning and found that they can help solve two minor annoyances I've had for a while.
For the purposes of this post, the pertinent one of those is the ability to serve a different XPage than the one requested. In normal cases, this isn't a particularly useful ability, though I can think of some pie-in-the-sky ideas like loading the compiled XPage classes from a plugin or Jar (like a homebrewed single copy design). Fortunately, I have an immediate use in mind: first-run config.
If you've used a package like WordPress, you've probably run into its first-run behavior, where it runs you through a wizard to set up the app configuration, database paths, and the like. Normally, this isn't important in a Notes app, but it's needed if you want to ship an empty DB and have people set it up for use. In my own case, I've taken to using a keyed document to store the app configuration, and this document doesn't exist when I reconstitute it from soruce. There are a couple ways I could handle this; for example, I could put code at the start of every page (or in each page's controller) to check for a completed config and, if not present, send a redirection header. Putting it in the ViewHandler
, though, means each individual page doesn't have to care.
Here's the snippet of applicable code from my new ViewHandler
:
public UIViewRoot createView(final FacesContext context, final String pageName) { if(!AppConfig.get().isComplete()) { return super.createView(context, "/appconfig"); } return super.createView(context, pageName); }
Now I have my config bean do a self-check to make sure all the fields required for normal app operation are present and, if not, the code forces the config page to load in place of the requested one. It has the side benefit of not actually causing a redirection, and in that way it's similar to Domino's standard login and error forms.
While this isn't the sort of feature that's going to completely change the way I write XPages apps (most likely), it's good to know about one more ability.
David Newman - Sat May 03 12:50:05 EDT 2014
Is this something that you think could be configured to open a embedded doc link. I have doc links in a document that is served up by an xpage. I want to open the appropriate document in the approriate XPage (the xpage app is separate from the datasource app)
Jesse Gallagher - Tue May 06 12:01:01 EDT 2014
In short: yes, but it would depend on your app whether you want to.
Specifically, what goes on is that, for any request in the DB in the form "whatever.nsf/something.xsp", the XPages framework will ask your ViewHandler to construct a page to match "/something". At that point, your code is free to do as you choose, and one of those options would be to use whatever you like from the request to choose a different string to pass to the delegate (the XPages standard ViewHandler that actually goes the job of finding and building the XPage). You could read the URL parameters, open the document, check the form, and pass through a different string based on that.
The "whether you want to" part comes in because this sort of thing could make your app harder to understand for you and others later. If done judiciously, it could be very powerful, but this sort of thing can easily lead to a "what the heck is going on?" sort of situation.