Some months ago there were discussion about how to use immutable value
objects in wicket. See:
http://thread.gmane.org/gmane.comp.java.wicket.user/12887/focus=12887

The conclusion was that wicket does not support well such a case
currently (http://article.gmane.org/gmane.comp.java.wicket.user/12911).
However, I think there may be pretty easy way to solve the issue.
Provide a FormComponent which can use associated markup file, just like
a Panel:

public abstract class CompoundFormComponent extends FormComponent 
{
    private boolean wasOpenCloseTag = false;
    
    public CompoundFormComponent(String id) 
    {
        super(id);
    }
    
    public CompoundFormComponent(String id, IModel model) 
    {
        super(id, model);
    }
    
    @Override
    public abstract void updateModel();
    
    @Override
    protected void onComponentTag(final ComponentTag tag)
    {
        if (tag.isOpenClose())
        {
            this.wasOpenCloseTag = true;
            
            // Convert <span wicket:id="myPanel" /> into 
            // <span wicket:id="myPanel">...</span>  
            tag.setType(XmlTag.OPEN);
        }
        super.onComponentTag(tag);
    }

    @Override
    protected void onComponentTagBody(final MarkupStream markupStream,
final ComponentTag openTag)
    {
        // Render the associated markup
        renderAssociatedMarkup("panel",
                "Markup for a panel component has to contain part
'<wicket:panel>'");

        if (this.wasOpenCloseTag == false)
        {
            // Skip any raw markup in the body
            markupStream.skipRawMarkup();
        }
    }
}

Note, the methods onComponentTag and onComponentTagBody are copy pasted
from Panel. The method updateModel() is made abstract, this is the place
where the immutable value object is created from convertedInputs of
FormComponents. Now, the IntegerRangeField (see the original thread) can
be written simply as:

IntegerRangeField.java:

public class IntegerRangeField extends CompoundFormComponent {
    private final TextField minimum;
    private final TextField maximum;

    public IntegerRangeField(Form parent, String id,
IModel/*<IntegerRange>*/model) {
        super(id, model);
        minimum = new RequiredTextField("minimum", new
Model(defaultMinimumValue()), Integer.class);
        maximum = new RequiredTextField("maximum", new
Model(defaultMaximumValue()), Integer.class);
        add(minimum);
        add(maximum);
        parent.add(new Validator(this));
    }
    
    @Override
    public void updateModel() {
        setModelObject(new IntegerRange(
                (Integer) minimum.getConvertedInput(), 
                (Integer) maximum.getConvertedInput()));
    }

    private Integer defaultMinimumValue() {
        if (rangeValue() == null) {
            return null;
        }
        return rangeValue().getMinimum();
    }

    private Integer defaultMaximumValue() {
        if (rangeValue() == null) {
            return null;
        }
        return rangeValue().getMaximum();
    }

    private IntegerRange rangeValue() {
        return (IntegerRange) getModelObject();
    }

    public static class Validator extends AbstractFormValidator {
        ...
    }
}

IntegerRangeField.html:

<?xml version="1.0" encoding="utf-8"?>
<wicket:panel>
<table cellpadding="0" cellspacing="0" border="0">
  <tr>
    <td>
      <input wicket:id="minimum" type="text" class="text numeric"
size="8" />
    </td>
    <td>&nbsp;-&nbsp;</td>
    <td>
      <input wicket:id="maximum" type="text" class="text numeric"
size="8" />
    </td>
  </tr>
</table>  
</wicket:panel>

I tried this with other immutables too, like DateRanges etc. and the
implementation was always straight forward. The original implementations
were much more complex and required deep knowledge of wicket's form
processing. It would be great to see something like this in core since
the abstract CompoundFormComponent contains copy pasted code from Panel.

Joni



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user

Reply via email to