Thursday, March 18, 2010

Form Generation: now with improved Conditional Attributes

The next release of Metawidget (v0.95) includes a small but useful improvment to JSF conditional attributes.

Previously you could make attributes of your UI 'conditional' by annotating them with UiFacesAttribute. For example:

public class Penguin {
   .
   .
   .
   @UiFacesAttribute( name = HIDDEN, expression = "#{empty penguin.current.condition}" )
   @UiComesAfter( "dateOfBirth" )
   public PenguinCondition getCondition() {
      ...
   }
}

This would hide the condition property if it was empty. In order words, if the JSF EL expression #{empty penguin.current.condition} evaluated to true.

The problem with this code is that, although the annotation is placed on the business object, the EL expression #{penguin.current.condition} relies on the JSF context being properly initialized with a penguin managed bean. This is rather brittle.

As a solution, in v0.95 FacesInspector can inject a this attribute 'just in time' into the FacesContext. So now you can do...

public class Penguin {
   .
   .
   .
   @UiFacesAttribute( name = HIDDEN, expression = "#{empty this.condition}" )
   @UiComesAfter( "dateOfBirth" )
   public PenguinCondition getCondition() {
      ...
   }
}

...and condition will be hidden regardless of how the external JSF environment is configured.

Feedback welcome!

Tuesday, March 9, 2010

Unsung Features of a Web Form Generator: security

Following on from the last blog entry, I thought I'd blog about another feature of Metawidget's id generation. I use this feature in my own apps, but it's not part of the core Metawidget distribution.

Like most things about Metawidget, id generation is pluggable. The Java Server Faces Metawidget comes with a ReadableIdProcessor that attaches ids to UIComponents based on a predictable camel-casing of their value binding. So, for example, if the component has a value binding...

<h:inputText value="#{contact.current.name}" />

...its id will be...

<input type="text" id="contactCurrentName" />

You can swap out this processor for your own, so for example you could generate ids with underscores...

<input type="text" id="contact_current_name" />

...or whatever convention suits your team. But you can plug in a processor to use no convention, or rather to use a completely random convention. Unusually for a Web framework, Java Server Faces actually doesn't much care what the component ids are. It uses them to map from the HTTP request back to the ViewState tree, but it doesn't really use them beyond that. They aren't, for example, used anywhere within the application code. This means they can be completely random if you want. In fact, they can change with every page request.

This makes for some pretty cool security. It makes writing a bot to perform brute-force logins, or post SPAM, much harder if all the field names are constantly changing and completely random. And it makes a Cross Site Request Forgery attack nigh-on impossible.

And best of all, you get it completely for free as part of letting Metawidget generate your ids.

Unsung Features of a Web Form Generator: testability


As part of a performance test I was doing recently, I had to put together some Webtests for a non-Metawidget-based UI. It was a painful experience, and reminded me of an important feature of Metawidget I haven't blogged about before: consistent, predictable ids.

Because Metawidget generates your widgets, it also generates your widget ids. And it can do a much more thorough job of naming these ids in a consistent, predictable manner than any human developer. This makes writing tests for your UIs much easier, because you know (or can deduce) what all your field ids will be in advance:
  • No more using Firefox and Firebug to look up the name of every single field as you go: once you know the first couple, the rest just follow suit.
  • No more getting halfway through writing your test case only to find you've forgotten to sensibly name one of your fields and have to go back and update the app code.
  • No more back-and-forth between the dev team and the test team as to what the field naming convention should be, or where someone hasn't followed it.
In short, less time spent mucking about with the plumbing and more time Getting Stuff Done.

Wednesday, March 3, 2010

Metawidget: Questions & Answers

I received a number of questions following a recent Metawidget presentation. I thought I'd blog the answers here in case they come up again. Please note this Q&A assumes a working knowledge of Metawidget. The snippets in bold are for those that like to skim-read :)



Customisability


Q. How can a user apply the various UI styles required without effectively shifting UI code to inside Metawidget tags? This could include CSS styles, or custom layout requirements?

A. Metawidget has various approaches to help you achieve fidelity between its automatically generated UIs and your own hand-made ones.

The first, and most significant, is that Metawidget does not try to 'own' your UI. It only generates a small piece of each screen, so does not compromise the full power of your UI toolkit to style everything else. Often, this full power of your UI toolkit bleeds back into the Metawidget itself. So, for example, if you're using Swing you can set the Swing Look and Feel and that will style your whole UI, including any Metawidgets (see screenshot). If you're using CSS you can set top-level styles and use CSS selectors (see screenshot). Some component libraries offer skinnable components and so on.

If you need more fine-grained control, Metawidget has WidgetProcessors. WidgetProcessors plug into the Metawidget pipeline on a per-widget basis and process each widget as it is generated. Importantly, WidgetProcessors have access to the same rich set of metadata as the WidgetBuilders and the Inspectors. So you can identify and style widgets not just by name but also by type, by constraints, by label, etc. This makes it straightforward to, say, attach a certain CSS class to all date widgets. Or attach an id for a CSS selector to pick up (see ReadableIdProcessor).

Beyond that, Metawidget has pluggable Layouts that can apply styles around the widgets. So for example HtmlTableLayout renderer can apply CSS style classes to the 'label column' and the 'component column'.



Client JavaScript Customization/plugin


Q. Can you plugin custom JavaScript on your forms/widgets? Many users want to trigger something when a field is touched.

A. Metawidget's WidgetProcessors are very versatile, and can be used to process each widget in an arbitrary number of ways. They can style a widget (see above), attach validators (see StandardValidatorProcessor), converters (see StandardConverterProcessor), bindings (see StandardBindingProcessor), event triggers (see example in the Reference Documentation) and so on.

This capability would extend to attaching JavaScript, though the specifics depend on your particular widget library. In some cases it may be automatic (see the Metawidget ICEfaces example).



Runtime impact, and concerns


Q. Each time a page is requested the form is created dynamically? Is caching per app, per session, per view?

A. Most parts (Inspectors, WidgetBuilders, WidgetProcessors, Layouts, PropertyStyles etc.) of the Metawidget internals are immutable. They are created once and reused for the lifetime of the app. Some parts may, at their own discretion, cache their results. By definition, they will be caching on a per-app basis.

For example, the JavaBeanProperyStyle caches the result of introspecting classes for JavaBean getters and setters. The GroovyPropertyStyle does not do this, because Groovy classes are dynamic.

Q. What happens with pages with many forms?

A. Because so much of Metawidget is immutable, there should be relatively little overhead with multiple instances. See also this previous blog entry.




Benchmarks between applications?


Q. I would like to see this. Perhaps flush out an existing app, with Metawidget being the only variable. Beat on the two apps for a while and see what's different?

A. Metawidget ships with 3 examples of existing apps and their Metawidget equivalents. So the apps are there, and we tried beating on them. See this previous blog entry.



How do you handle cross component library issues?


Q. Is there a widget builder for each combination?

A. No. Each WidgetBuilder is generally responsible for only one component library. There is a CompositeWidgetBuilder which handles mixing multiple widget libraries in the same app, and prioritising them (see this video).

Q. When you layout do you use your own code, or widgets from the UI? For example do you create your own <table> or let the widget set do this?

A. Generally we let the widget set do this (see TabPanelLayoutDecorator), though for specific requirements we sometimes handle it ourselves (see HtmlDivLayoutRenderer).

Q. Are there ways to override layouts?

A. Yes. Layouts are pluggable. They are also decoratable, so one layout can be wrapped around another (see this blog entry).

Q. What other UI widgets do you handle? Data tables (with forms for data input)? Or strictly standard forms like address, credit card, etc

A. It is important to understand Metawidget is not a component library - it simply automates other component libraries. So if you have a rich data table component it is straightforward to plug in a WidgetBuilder for it (see DisplayTagWidgetBuilder).



Static layout based on model


Q. Good in theory, but large enterprise environments often have DBA's and different groups in charge of model code?

A. Metawidget's Inspector architecture is highly pluggable and designed to support a broad range of architectures and development styles. UI metadata can be sourced from XML files, POJOs, Web services, database schemas, rule engines or whatever method best suits the development team. It can even be sourced remotely across tiers, and across hetergenous technologies.

Q. Can you output static stuff at all?

A. There are no plans for static output at this time. Because Metawidget is runtime-based, inspecting objects, it is not clear how static output could be supported. I believe it becomes a mindset - I remember people used to ask whether Hibernate could output static SQL, but after you use a runtime ORM for a while it becomes a moot point. You can think of Metawidget as an OIM (Object Interface Mapper).



Source structure, standards, and build environment


Q. Licensing, copyright, dependencies?

A. The source is broadly divided into folders for the Metawidget source, folders for the examples and folders for the tests. There's an Ant build around the whole lot, with all build dependencies inside a lib folder.

Within the Metawidget source, packages are carefully structured to separate out technologies, such as org.metawidget.swing and org.metawidget.faces. It is intended developers can easily strip out those plug-ins they don't use (see the Swing Applet example).

Licensing is 99% LGPL. Copyrights belong to the author at the top of each file (mostly me, though I am grateful to those others who have contributed). At runtime, Metawidget has no mandatory JAR dependencies - it just uses whatever is available to it.