Until now I've had a Metawidget interface with a MetawidgetImpl class. This acted as a go-between between instantiating platform-specific WidgetBuilders, and running and collating results from multiple Inspectors.
In turn, the platform-specific WidgetBuilders (SwingWidgetBuilder, FacesWidgetBuilder, etc) implemented a WidgetBuilder interface and extended a generic WidgetBuilderImpl class which took care of some of the generic 'plumbing' of iterating over inspection results.
Then we had another class that extended each target framework and made use of the WidgetBuilder. So you have:
- FacesMetawidgetComponent extends javax.faces.UIComponent (platform-specific base class)
- FacesWidgetBuilder extends WidgetBuilder (generic base class for iterating inspection results)
- MetawidgetImpl (collates inspection results)
- JavaBeanInspector implements Inspector
In addition, I collapsed the separation between Metawidget and the Inspectors into simply a MetaInspector that both implements Inspector and collates multiple results. This is really neat because it means we can efficiently support apps that only need a single Inspector (they don't use MetaInspector) and formalize a common XSD for inspection results - both from the 'bottom-level' Inspectors and the 'top-level' MetaInspector.
It means there's no longer a separate Metawidget class per se, but I think I can live with that too.
As a final bonus it allows for pluggable implementations of, say, remoting (RemoteInspector) and alternative merging algorithms.
Phew! A lot of refactoring for one day...