Thursday, November 26, 2009

Metawidget: King of the Hill


Nice article here (at least I assume it's nice, my German is even worse than Google Translate's):


My thanks to the author.

Wednesday, November 18, 2009

We're Hiring!

Here's the job ad we're posting today. A chance to work from home, and work for me! What a dream job :)


Senior Java EE 5 (J2EE) Developer: $90,000 - $100,000 AUD
  • Small, focused team

  • Modern, well-crafted software

  • Work in city or from home
A rare opportunity to join our small consultancy team. We have recently received substantial investment from a leading Australian financial institution and we must grow to meet demand.

You will work side-by-side with one of Australia's premier Java EE developers, and be intimately involved in all design decisions.

You will be a pragmatic programmer. Software development will be in your blood: a natural instinct. You must be passionate about Open Source and Java EE. You will demonstrate advanced analytical skills; an eye for elegance and craftmanship; a passion for refactoring, unit testing, and delivering secure and robust code.

Your skills will include many of the following:
  • JBoss

  • JSF/RichFaces

  • XSL (T and FO) and XPath

  • EJB 3/JMS

  • JPA/SQL

  • Metawidget

  • HtmlUnit

  • HTML/CSS
In addition, you will have excellent communication skills and be comfortable interacting with stakeholders at all levels.

Work from home will be offered providing that you can demonstrate an appropriate working environment. You must be a citizen or permanent resident of Australia.

To help us sort applicants, include your CV and a 1 page overview highlighting your suitability for the role. Links to examples of your work (eg. web sites you have built, blogs you have written, Open Source contributions etc) will be highly regarded.

Please send your application to jobs@kennardconsulting.com.

Wednesday, November 11, 2009

Safely manipulating the component tree with JSF 2

The information in this blog post has been superseded. Please see Safely manipulating the component tree with JSF 2, revisited

The Problem

A common problem encountered by writers of dynamic JSF 1.x components (like Metawidget) was "at what point in the lifecycle can I safely manipulate the component tree"?

For a page's initital GET request, there weren't many lifecycle methods you could hook into - you basically had encodeBegin. For subsequent POST-backs there were a slew of hooks, including decode, processValidators and processUpdates, but none were at exactly the right place in the lifecycle to do safe component tree manipulation. What would be 'exactly the right place'? Namely:
  1. the component tree should be fully realized (ie. all parents and children should be set)

  2. the component tree should not have been serialized yet
Because there was no 'official' place, writers of dynamic JSF 1.x components had to resort to all kinds of tricks. As Ken Paulson wrote "...people use constructors, bindings, action methods... people create their own renderer which dynamically adds children each request". To which Jacob Hookum opined "what's actually needed is post component tree creation hooks, providing the ability to then modify the component tree".


The Saviour

Enter JSF 2. From the spec "System Events are introduced in version 2 of the specification and represent specific points in time for a JSF application". They are like the old PhaseEvents, but much more fine-grained. For the purposes of this blog, the SystemEvent we are interested in is PostAddToViewEvent.

To use it, first subscribe to the event in your UIComponent's constructor...

public class UITestComponent
   extends UIComponentBase
   implements SystemEventListener {

   public UITestComponent() {
      FacesContext ctx = FacesContext.getCurrentInstance();
      ctx.getViewRoot().subscribeToViewEvent(PostAddToViewEvent.class, this);
   }

...then, when it gets fired, you can safely manipulate the component tree ...

public void processEvent( SystemEvent event ) throws AbortProcessingException {

   FacesContext ctx = FacesContext.getCurrentInstance();
   UIComponent dynamicallyGenerated = ctx.getApplication().createComponent( "javax.faces.HtmlInputText" );
   getChildren().add( dynamicallyGenerated );
}


The Gotchas

While working through this solution, there were a number of gotchas I encountered. Huge thanks to Ryan Lubke for holding my hand through them:

First, you should use subscribeToViewEvent, not subscribeToEvent. The latter will mean the event subscription itself get serialized into the component tree, so you'll keep doubling up subscribers every time the page refreshes.

Second, you must hook into UIViewRoot's PostAddToViewEvent, not UITestComponent's. This is because, at the time UITestComponent's PostAddToViewEvent is fired, its children will not be initialized yet.

Third, you cannot use the @ListenerFor annotation to hook into SystemEvents from a UIComponent. This is because UIComponent implements ComponentSystemEventListener, and @ListenerFor is designed to ignore the SystemEventListener interface for any class that implements ComponentSystemEventListener.


The Ugly

There is, unfortunately, still a problem for certain types of dynamic component.

If your component, in its processEvent method, dynamically creates not just simple HtmlInputText components but nested components that are themselves dynamic, we have a problem. This is because the 'official' way to safely manipulate the component tree is through SystemEvents, but there is no official way to safely manipulate the SystemEvent list.

In the current release of the JSF Reference Implementation (2.0.1), attempting to dynamically create a component that in turn tries to subscribe to a SystemEvent will get you a ConcurrentModificationException. In future releases, there will not be an exception but the newly added SystemEvent will simply not fire, so your newly added dynamic component will never get an opportunity to populate itself.

This new issue is being tracked by the JSF RI team. Until it is resolved, JSF 2 can safely create dynamic components (a big step forward), but it cannot safely create dynamic components that themselves create dynamic components.

Suggestions welcome!

Friday, October 30, 2009

XSL-FO number-columns-spanned="remainder"

Every so often when developing some XSL-FO I get the dreaded...

column-number or number of cells in the row overflows the number of fo:table-column specified for the table

...these tend to be a nightmare to track down, and very fiddly to fix, because often you need to add a number-columns-spanned attribute to one of the fo:table-cell elements, and in a dynamic world you have to figure out exactly how many cells to span. Agh!

It'd be much easier if XSL-FO let you just say number-columns-spanned="remainder". So today I wrote a little XSLT that you can put after your XSL-FO and before you try to serialize it (with something like Apache FOP).

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
            xmlns:fo="http://www.w3.org/1999/XSL/Format">

   <!-- number-columns-spanned: remainder -->
   
   <xsl:template match="fo:table-cell[@number-columns-spanned = 'remainder']" mode="#all">
   
      <xsl:copy>
         <xsl:attribute name="number-columns-spanned">
            <xsl:variable name="number-columns-in-table" as="xs:integer">
               <xsl:value-of select="count(ancestor::fo:table[1]/fo:table-column)"/>
            </xsl:variable>
            <xsl:variable name="number-columns-in-row" as="xs:integer">
               <xsl:value-of select="count(preceding-sibling::fo:table-cell[not(@number-columns-spanned)]) + count(following-sibling::fo:table-cell[not(@number-columns-spanned)])"/>
            </xsl:variable>
            <xsl:variable name="number-spanned-columns-in-row" as="xs:integer">
               <xsl:value-of select="sum(preceding-sibling::fo:table-cell[@number-columns-spanned ne 'remainder']/@number-columns-spanned) + sum(following-sibling::fo:table-cell[@number-columns-spanned ne 'remainder']/@number-columns-spanned)"/>
            </xsl:variable>
            <xsl:value-of select="$number-columns-in-table - $number-columns-in-row - $number-spanned-columns-in-row"/>
         </xsl:attribute>
         <xsl:apply-templates select="@*[not(local-name() = 'number-columns-spanned')]|node()"/>
      </xsl:copy>
      
   </xsl:template>


   <!-- identity transform -->
   
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

I should've done it years ago. Note unfortunately it won't work if you've got other rows that are using number-rows-spanned. Improvements welcome!

Thursday, October 15, 2009

User Interface Generator: Metawidget v0.85

Version 0.85 of Metawidget, the user interface generator, is now available! This release has something for everyone:

For first time users, we have updated and improved the User Guide. For intermediate users, we have greatly expanded the architecture documentation, with lots more diagrams and detailed explanations. And for advanced users, we have substantially refactored the internals, including introducing new pluggable WidgetProcessors to handle more demanding requirements. Please note there are unfortunately some breaking changes, as covered in the Migration Guide.

In addition we have improved our support for RichFaces (now includes SuggestionBox, TabPanel and RichPanel), ExtGWT (now includes Slider), Swing (now includes configurable labels), and have added XML schemas for every component and lots more unit tests.

Special thanks to Girolamo Violante and Illya Yalovyy for their help with this release!

As always, the best place to start is the Reference Documentation:

http://metawidget.org/doc/reference/en/pdf/metawidget.pdf

Your continued feedback is invaluable to us. Please download it and let us know what you think.

Friday, October 2, 2009

Metawidget 0.8 to 0.85 Migration Guide

The next release of Metawidget (v0.85, due in late October) will represent a significant refactoring of the Metawidget internals, aimed at increasing API clarity and consistency, code reuse, type safety and extensibility - all in preparation for our 1.0 release. As such, there will be a number of breaking changes.

We apologise for this disruption and provide this Migration Guide to help in moving from v0.8 to v0.85. All of the existing documentation and examples have already been migrated, as a reference point.

WidgetProcessors

The big new change is the concept of a 'widget processor'. These are lightweight, pluggable classes who can 'process' a widget just after its building (by the WidgetBuilder) and before it is laid out (by the Layout).


The interface is simply:

W processWidget( W widget, String elementName, Map<String, String> attributes, M metawidget )

This is great because:

  • It allows you to plug-in arbitrary processing of a widget without touching the Metawidget class itself. For example you could write a widget processor to add a tooltip to every component:

    JComponent processWidget( JComponent widget, String elementName, Map attributes, SwingMetawidget metawidget ) {
       widget.setToolTipText( attributes.get( NAME ));
       return widget;
    }

  • It provides more ways to identify and process a widget than getComponent( String... names ), for situations where you don't know the component's name in advance

  • It allows you to attach Event Handlers as inner classes that have connections to their parent class:

    final Object someObject = ...;

    metawidget.addWidgetProcessor( new BaseWidgetProcessor() {
    JComponent processWidget( JComponent widget, String elementName, Map<String, String> attributes, SwingMetawidget metawidget ) {
       ...decide whether to attach event handler...

       widget.add( new AbstractAction() {
          public void actionPerformed( ActionEvent event ) {
             someObject.doSomething();
          }
       }
    }
    }

  • Standardizing this concept allows us to refactor a lot of previously ad-hoc functionality. For example all binding and validation functionality are now implemented as widget processors:


    They can be chained together either programmatically or in metawidget.xml:

    <widgetProcessors>
       <list>
          <processor:requiredAttributeProcessor />
          <processor:immediateAttributeProcessor />
          <processor:standardBindingProcessor />
          <processor:readableIdProcessor />
          <processor:labelProcessor />
          <processor:standardValidatorProcessor />
          <processor:standardConverterProcessor />
       </list>
    </widgetProcessors>

Refactored save(), rebind(), validate()

As mentioned, binding and validation have now been refactored into WidgetProcessors. This has the advantage of moving methods such as save() and validate() out of the Metawidget (where they weren't always applicable) and into the responsible WidgetProcessor (where they will always be applicable, by definition).

This unfortunately means a slightly more cumbersome API. Instead of...

metawidget.save()

...you now have to do...

metawidget.getWidgetProcessor( BeansBindingProcessor.class ).save( metawidget )
...however we think the tradeoff is worth it.

metawidget.xml now supports (and mostly uses) <array>

ConfigReader now natively supports an <array> element. This allows it to natively call vararg methods, removing the need for some of the overloaded methods in the xxxConfig classes.

Most current usages of <list> should be replaced with <array>. Lists (and Sets) are still supported for your custom use-cases.

Refactored setCreateHiddenFields

JSF hidden field creation has also been refactored into a WidgetProcessor. For example:

<widgetProcessors>
   <list>
      <hiddenFieldProcessor />
   </list>
</widgetProcessors>

Layouts must now be immutable

Layouts are now a standardized part of the Metawidget pipeline. They must implement the new org.metawidget.layout.iface.Layout interface, and must be threadsafe and immutable just like Inspectors, WidgetBuilders and WidgetProcessors. Custom Layouts that are currently thread-unsafe or mutable need to be refactored in a couple of ways:

  • Configuration settings, that do not change over the lifetime of the Layout and would previously have been retrieved via metawidget.getParameter (and possibly saved into member variables), should now be configured by an external xxxConfig class. For example:

    public GridBagLayout() {
       this( new GridBagLayoutConfig() );
    }

    public GridBagLayout( GridBagLayoutConfig config ) {
       mNumberOfColumns = config.getNumberOfColumns();
       mLabelAlignment = config.getLabelAlignment();
       mSectionStyle = config.getSectionStyle();
       mLabelSuffix = config.getLabelSuffix();
       mRequiredAlignment = config.getRequiredAlignment();
       mRequiredText = config.getRequiredText();
    }

    ...and configured either programmatically or in metawidget.xml:

    <layout>
       <htmlTableLayout xmlns="java:org.metawidget.jsp.tagext.html.layout" config="HtmlTableLayoutConfig">
          <tableStyle>
             <string>aTableStyle</string>
          </tableStyle>
       </htmlTableLayout>
    </layout>

  • Internal state that changes during layout and was stored in member variables should now be stored in the parent Metawidget. For example:

    State state = (State) metawidget.getClientProperty( GridBagLayout.class );
    state.currentRow++;

No more metawidget.setParameter or m:param

The previously (type unsafe) metawidget.setParameter methods and m:param tags have now been removed, in favour of typesafe configuration objects on the WidgetProcessors and Layouts. So instead of...

metawidget.setPropertyBindingClass( BeansBinding.class )
metawidget.setParameter( "updateStrategy", UpdateStrategy.READ )

...you now do...

metawidget.addWidgetProcessor( new BeansBindingProcessor(
   new BeansBindingProcessorConfig()
      .setUpdateStrategy( UpdateStrategy.READ )));

...or equivalent in metawidget.xml.

ConfigReader Moved

ConfigReader has now been moved out of org.metawidget.inspector and into the new org.metawidget.config. This reflects it outgrowing its roots as a purely Inspector-focussed mechanism, into a general purpose way to configure Metawidgets.

XSDs

Existing XSDs have now been moved under http://metawidget.org/xsd. In addition, all the XSDs for the Inspectors, WidgetBuilders etc have been generated.

PropertyStyles and ActionStyles are now objects

ConfigReader is now smart enough to reuse PropertyStyle and ActionStyles instances between Inspectors. This means they are now specified on the Inspector as an object, not their class. This opens the door to people writing their own, configrable property styles if they need to.

Ant Build

The formerly monolithic build.xml has been split into several smaller ones. The original (/build.xml) now only builds Metawidget itself. There is a separate /examples/build.xml (builds examples), /test/build.xml (runs unit tests), /src/doc/build.xml (builds documentation) and /src/web/build.xml (builds Web site).

Similarly, the lib folder has now been split into /lib, /examples/lib and /test/lib.

Java Puzzler: enforcing whether a class overrides equals/hashCode


The Problem

Let's say I'm writing a Java class that requires users of my class override equals and hashCode on their objects. I'd be in good company: lots of classes do this, not least the java.util.Collection classes like List and Set.

This important requirement is generally only recorded in the JavaDoc, with a stern warning that Bad Things Will Happen if you forget. But the requirement is not enforced at runtime, much less compile time.

The Question

What if I wanted to enforce it? What if I wanted to write a class like HashMap that made sure anything you put in it overrode equals and hashCode? What if I'm prepared to sacrifice a little performance and/or code complexity to do this? What are my choices? Can I do it at runtime? Better yet, can I do it at compile-time?

The Answer?

I don't know a great answer. I don't know of any libraries that do. I'd love some feedback on helping eliminate this important category of subtle bugs.

To get the ball rolling, this is what I'm thinking of doing in Metawidget:

Class classToTest = objectToCache.getClass();
Object dummy1 = classToTest.newInstance();
Object dummy2 = classToTest.newInstance();

if ( !dummy1.equals( dummy2 ))
throw new Exception( classToTest + " does not override .equals(), so cannot be reliably cached" );

if ( dummy1.hashCode() != dummy2.hashCode() )
throw new Exception( classToTest + " does not override .hashCode(), so cannot be reliably cached" );

This approach takes advantage of the fact that, given your class has internal state, two brand new instances should always have equivalent state, but the default Object.equals (which uses ==) will return false. It's not perfect. It'll work if you write a POJO and forget to override equals. But it won't work if your superclass overrides equals but your subclass, which adds some more internal state, forgets to. But it's a start.

Note that, annoyingly, this doesn't seem to work:

class.getDeclaredMethod( "hashCode" )

Public methods like hashCode and equals are always considered 'declared methods', even if the class doesn't actually declare them. Similarly:

class.getDeclaredMethod( "hashCode" ).getDeclaringClass()

Always returns the subclass name, even if the subclass doesn't override hashCode.

Suggestions welcome!

Update

Thanks to everyone for the really helpful comments. The first thing to note is that...

class.getDeclaredMethod( "hashCode" ).getDeclaringClass()

...does actually work. I don't know why it didn't seem to when I tried it originally. Evidentally I am an idiot!

Anyway, here's what's currently going into Metawidget, based on everyone's feedback:

Class<?> configClass = configToStoreUnder.getClass();

// Hard error

// equals

Class<?> equalsDeclaringClass = configClass.getMethod( "equals", Object.class ).getDeclaringClass();

if ( Object.class.equals( equalsDeclaringClass ) )
throw new Exception( configClass + " does not override .equals(), so cannot cache reliably" );

// hashCode

Class<?> hashCodeDeclaringClass = configClass.getMethod( "hashCode" ).getDeclaringClass();

if ( Object.class.equals( hashCodeDeclaringClass ) )
throw new Exception( configClass + " does not override .hashCode(), so cannot cache reliably" );

if ( !equalsDeclaringClass.equals( hashCodeDeclaringClass ) )
throw new Exception( equalsDeclaringClass + " implements .equals(), but .hashCode() is implemented by " + hashCodeDeclaringClass + ", so cannot cache reliably" );

if ( !configClass.equals( equalsDeclaringClass ) )
{
// Soft warning
//
// Note: only show this if the configClass appears to have its own 'state'.
// Base this assumption on whether it declares any methods. We don't want to
// use .getDeclaredFields because that requires a security manager
// check of checkMemberAccess(Member.DECLARED), whereas we may only have
// checkMemberAccess(Member.PUBLIC) permission

for ( Method declaredMethod : configClass.getMethods() )
{
if ( configClass.equals( declaredMethod.getDeclaringClass() ) )
{
LOG.warn( configClass + " does not override .equals() (only its super" + equalsDeclaringClass + " does), so may not be cached reliably" );
break;
}
}

// Note: not necessary to do !configClass.equals( hashCodeDeclaringClass ),
// as will already have thrown an Exception from
// !equalsDeclaringClass.equals( hashCodeDeclaringClass ) if that's the case
}

Improvements welcome!