An XPage As A Tree: Implications

Wed Apr 16 17:41:28 EDT 2014

Tags: xpages

A few posts ago, I talked about how the skeletal nature of an XPage is really a very abstract representation of a UI. At its core, it isn't conceptually tied to the web - and, indeed, the probable bulk of the work done by JSF is to push against the normal rules of the web.

The goal of XPages/JSF is to abstract away the messy business of writing web pages, much like a cross-platform mobile framework attempts to abstract away the chore of writing to iOS or Android directly.

In practice, I've found this to be both a brilliant and awful idea. I'm not alone in this: if you look around, you'll find proponents of methods of web programming that don't go against the grain so much, and they have excellent points. However, the "abstraction" route isn't without its benefits. So, off the top of my head, I can think of a number of pros and cons of the XPages "component" conceit. In the spirit of suspiciously defying convention, I'll start with the cons.

Cons

  • The abstraction leaks like a sieve. Case in point: the style and styleClass properties. In an ideal world, those have no place in an abstracted framework - in XPages, it should be the job of themes and renderers to sweat those details. But in reality, they're vital.
  • It's harder to write a clean page. Because you're working at a high level, you're relinquishing control of much of the structure of your page to the components' renderers, which will likely spit out all sorts of oddball divs, spans, and the like. Theoretically, you can fix this, but:
  • Writing renderer classes is a colossal PITA. Java has its share of virtues, but writing code to spit out other code is not among them. Writing a renderer for even a basic control is an exercise in verbosity and fighting Java's inferior literal strings. This means:
  • It's harder to keep up with the times. Because you're largely dependent on the implementor of the renderer for the control's HTML/JS, you're likely to run into situations where the HTML is atrocious (see: radio and checkbox groups) or runs counter to the structure you want for your page (see: using pagers on a Bootstrap-ified site). That's not to mention significantly-different programming models like AngularJS.
  • They're a poor match for the realities of HTML/HTTP. The whole conceit of JSF - that you have this tree of Java objects sitting on the server that you're interacting with as if it's a desktop app - requires tremendous code and conceptual overhead to glom onto a stateless network protocol like HTTP.

Pros

  • The abstraction level is often just about right. When you want to create an entity on your page that is conceptually common but has no representation in HTML - say, a widget container or tabbed table - the component model shines. The code you end up writing is extraordinarily task-focused: you're creating a widgetContainer, not a bunch of divs with class names that happen to match the CSS/JS framework of the day. Along those lines:
  • It's easier to keep up with the times. I am aware that the inverse of this is in the "cons" list, but they're both true. Though it can be harder to adapt your components to modern standards, if you do the job well, the component model makes it easier to bring older apps forward. If you app consists entirely of standardized components like applicationLayout, formTable, and the like, a set of new renderers can adapt these conceptually-common controls to a new framework that wasn't in use when you wrote them originally.
  • You can write your own. Since, in spite of the difficulty, JSF actually succeeds in presenting an idealized Java world, it's a minor conceptual leap (though a large code-writing one) to go from using common components to building ones that match your needs. This is where Custom Controls shine, and do the job well either as-is or a starting point for building more "baked in" Java components.
  • HTML is no prize pig either. As much as it's easy to extol the virtues of going with the grain of HTML/HTTP/etc., it's still a huge pain to do so. The closer you get to the "metal", the more you have to deal with non-semantic markup elements, browser bugs, HTML entity escaping, and so forth. It's a fool's errand to do it by hand, so the task is just picking a set of abstractions that strike your fancy.

So what's the best route? Beats me! To a large extent, it doesn't matter, because no web framework lasts forever. For my part, I find the XPages/JSF abstraction to be a fine tool, and I plan to continue refining my ability to write to its strengths.

Commenter Photo

Nathan T. Freeman - Wed Apr 16 22:01:14 EDT 2014

The problem with the Component tree, IMO, is that present day components are too tied to an implementation. Why should we have <xp:label>, <xp:radioGroup>, <xp:checkboxGroup>, <xp:djNumberTextBox>? Why don't we just have <xp:input type="integer"> or <xp:input constrained="true" allowMultiple="true"> and then leave the UI constructs up to the renderkit and/or theme?

That way we could make structurally sound components that didn't dictate the actual implementation until runtime, where it knows the target platform, associated data, and preferred protocol.

This would be, I think, a vastly superior way to design applications that focus on a conceptual model that adapts to future changes with a single point of entry. The way XPages work today simply locks customers into the same problem they've had with Notes for the last two decades: applications which can only be adapted to new user conditions by touching each and every code point in production systems. They're still frozen in amber from the moment they're deployed.

Commenter Photo

Jesse Gallagher - Wed Apr 16 22:31:32 EDT 2014

Yes, that's something I've thought a bit about when writing these posts. Since web browsers just POST key/value pairs anyway without regard to input type, there's no reason that the controls couldn't be one or just a few primary types, maybe with hints towards "preferred" types in some cases, and then let the renderer pick an HTML (or other language) control based on data type, browser/client type, and so forth.

That particularly applies to input controls (especially since users seem to barely know the difference between radio buttons and checkboxes anyway), but could also apply to larger conceptual units as well - forms, layouts, action bars, etc.. Basic line-of-business data-centric apps are best described as data schemas anyway, and even more-complicated pages or apps can often be done at a higher level.

Commenter Photo

Dan Sickles - Wed Apr 16 22:33:38 EDT 2014

If jurassicpark.com wasn't taken, I'd start a company and give new life to....on second thought, I'm allergic to amber.

Commenter Photo

Paul Withers - Thu Apr 17 04:57:24 EDT 2014

The stateful nature of JSF/XPages is a huge benefit. Which of us, after the time we've spent coding XPages, would prefer to manually pass all the variables we might need to store in cookies. Not me.

One of the pains of XPages though is that any component can go anywhere, so the ID has to be dynamic. That's a pain when you inherit a CSS (look at Connections for example) that has used IDs to manage styles. (I'll leave the debate of whether or not using IDs in CSS is bad practice.)

Components are a huge strength. I'm one of those who coded AJAX requests before XPages. It is excruciatingly painful to write JavaScript to asynchronously call a server-side process, which you then write and output JSON (which was without a standard library to ensure good JSON), then write the JavaScript to parse and act on the result. Partial refreshes are a god-send for interacting with the server.

Commenter Photo

Tim Tripcony - Thu Apr 17 05:01:25 EDT 2014

Food for thought: imagine a structure where the consumer (browser, mobile app, whatever) is fed two JSON streams: one defines data, one defines representation -- but still abstractly, like Nathan's saying: only send enough information for said consumer to know what is required of any user interface vector it might choose to provide to the user (e.g. it wouldn't be valid for the browser to display a radio button or a mobile app to display an on/off switch if {"allowMultiple":true}). Hm... maybe we should implement something like... oh, wait. We did.

New Comment