<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xebia Blog &#187; Mischa Dasberg</title>
	<atom:link href="http://blog.xebia.com/author/mdasberg/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.xebia.com</link>
	<description>Software development done right!</description>
	<lastBuildDate>Wed, 01 Feb 2012 00:30:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Google Guice and Multibinding</title>
		<link>http://blog.xebia.com/2009/12/21/google-guice-and-multibinding/</link>
		<comments>http://blog.xebia.com/2009/12/21/google-guice-and-multibinding/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 12:58:46 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/blog.xebia.com/www/wp-content/plugins/autometa/autometa.php</b> on line <b>303</b><br />
		<category><![CDATA[Java]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/?p=3875</guid>
		<description><![CDATA[Last week I started migrating an application that used Spring for DI to Google Guice when I stumbled on multibinding. Since Google Guice 2.0 we can use Multibinding which allows us to bind multiple objects to a collection. But the one thing I missed in the current release is the ability to bind objects with [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I started migrating an application that used Spring for DI to Google Guice when I stumbled on multibinding.</p>
<p>Since Google Guice 2.0 we can use Multibinding which allows us to bind multiple objects to a collection.<br />
But the one thing I missed in the current release is the ability to bind objects with a specific annotation. So I thought, why not build it myself <img src='http://blog.xebia.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-3875"></span><br />
So lets use the Multibinder example written in the Javadoc of Multibinder.</p>
<pre lang="java">public class SnacksModule extends AbstractModule {
    protected void configure() {
     Multibinder<ISnack> multibinder = Multibinder.newSetBinder(binder(), ISnack.class);
      multibinder.addBinding().toInstance(new Twix());
      multibinder.addBinding().toProvider(SnickersProvider.class);
      multibinder.addBinding().to(Skittles.class);
    }
  }</pre>
<p>With this binding, a Set&lt;ISnack&gt; can now be injected:</p>
<pre lang="java">  class SnackMachine {
    @Inject
    public SnackMachine(Set<ISnack> snacks) { ... }
  }</pre>
<p>This is nice if you have a couple of Snacks, but if you have many and you want your<br />
module clean and simple, you probably want something like this</p>
<pre lang="java"> multibind(ISnack.class).toAnnotatedClasses(Snack.class);</pre>
<p>Where a Snack looks like this:</p>
<pre lang="java">
@Snack
public class Snickers implements ISnack { ... }
</pre>
<p>To make this possible, I created the following Module:</p>
<pre lang="java">public abstract class AbstractMultibindModule extends AbstractModule {

    public  AdvancedMultibinder multibind(Class clazz) {
        return new AdvancedMultibinder(clazz);
    }

    public class AdvancedMultibinder {
        private Multibinder multibinder;
        private Class clazz;

        private AdvancedMultibinder(Class clazz) {
            this.clazz = clazz;
            multibinder = Multibinder.newSetBinder(binder(), clazz);
        }

        public Multibinder toAnnotatedClasses(Class bindingAnnotation) {
            return toAnnotatedClasses(bindingAnnotation, clazz.getPackage().getName());
        }

        public Multibinder toAnnotatedClasses(Class bindingAnnotation, String basePackageName) {
            for (Class clazz : AnnotationUtil.getAnnotatedClasses(bindingAnnotation, basePackageName)) {
                multibinder.addBinding().to(clazz);
            }
            return multibinder;
        }

        public LinkedBindingBuilder addBinding() {
            return multibinder.addBinding();
        }
    }
}</pre>
<p>As you can see the multibind method returns an AdvancedMultibinder. We cannot extend Multibinder because it has a private Constructor, so instead I use the multibinder internally and call methods on it to add bindings.</p>
<p>The AdvancedMultibinder has a method toAnnotatedClasses, which takes the annotation class as a parameter and adds a binding for each annotated class.</p>
<p>Now we can do the following.</p>
<pre lang="java">
     AdvancedMultibinder multibinder = multibind(ISnack.class);
     multibinder.toAnnotatedClasses(Snack.class);

     // Add a non annotated class to the bind.
     multibinder.addBinding().to(Skittles.class);

     bind(Machine.class).to(SnackMachine.class);</pre>
<p>I have attached the example project <a title="Multi binding" href="http://blog.xebia.com/wp-content/uploads/2009/12/guice-auto-multibinding.zip" target="_blank">here</a> so you can look into the code yourself.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2009/12/21/google-guice-and-multibinding/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2009%2F12%2F21%2Fgoogle-guice-and-multibinding%2F&amp;title=Google%20Guice%20and%20Multibinding" id="wpa2a_2"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2009/12/21/google-guice-and-multibinding/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Testing Wicket AjaxBehavior</title>
		<link>http://blog.xebia.com/2009/08/25/testing-wicket-ajaxbehavior/</link>
		<comments>http://blog.xebia.com/2009/08/25/testing-wicket-ajaxbehavior/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 19:50:54 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Wicket]]></category>

	<!-- AutoMeta Start -->
	<category></category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/?p=2983</guid>
		<description><![CDATA[Last week I ran into a problem while testing AjaxBehavior in Wicket. Consider the following scenario: we have a FormComponent which has an AjaxBehavior added to it. We want to test that behavior. Depending on the selected value of for instance a RadioChoice, the Ajaxbehavior should show one component and hide another. You would think [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I ran into a problem while testing AjaxBehavior in Wicket.</p>
<p>Consider the following scenario: we have a FormComponent which has an AjaxBehavior added to it. We want to test that behavior. Depending on the selected value of for instance a RadioChoice, the Ajaxbehavior should show one component and hide another.</p>
<p>You would think that this would be out of the box behavior when using WicketTester, but unfortunately this is not the case. Triggering an Ajaxbehavior is easy using WicketTester, but setting the selected value isn&#8217;t. <span id="more-2983"></span></p>
<p>So we have the following code:</p>
<pre lang="java">
public class TestPage extends WebPage {

    private Label l1;
    private Label l2;
    private WebMarkupContainer container;

    public TestPage() {
        container = new WebMarkupContainer("container");
        container.setOutputMarkupPlaceholderTag(true);

        l1 = new Label("true", "I selected true");
        l1.setVisible(false);
        l1.setOutputMarkupPlaceholderTag(true);
        l2 = new Label("false", "I selected false");
        l2.setVisible(false);
        l2.setOutputMarkupPlaceholderTag(true);

        container.add(new SingleLineRadioChoice<Boolean>("choice", new Model<Boolean>(),
       Arrays.asList(Boolean.TRUE, Boolean.FALSE)) {
            private static final long serialVersionUID = 1L;
            @Override
            public void onUpdateBehavior(AjaxRequestTarget target) {
                if(getModelObject()) {
                    l1.setVisible(true);
                    l2.setVisible(false);
                } else {
                    l1.setVisible(false);
                    l2.setVisible(true);
                }
                target.addComponent(container);
            }
        }, l1, l2);
        add(container);
    }

    public class SingleLineRadioChoice<T> extends RadioChoice<T> {
        private static final long serialVersionUID = -6650798211067977383L;

        public SingleLineRadioChoice(String id,  IModel<T> model, List<T> choices) {
            super(id, model, choices);
            setSuffix("");
            add(new AjaxFormChoiceComponentUpdatingBehavior() {
                private static final long serialVersionUID = 1L;
                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    updateModel();
                    onUpdateBehavior(target);
                }
            });
        }

        /**  @param target The {@link AjaxRequestTarget}. */
        public void onUpdateBehavior(AjaxRequestTarget target) { }

    }
}
</pre>
<p>The way you should normally expect the test to work is:</p>
<pre lang="java">
 public void testShouldShowL2() {
        tester.assertInvisible("container:false");
        tester.setParameterForNextRequest("container:choice", "true");
        tester.executeBehavior((AbstractAjaxBehavior)
        tester.getComponentFromLastRenderedPage("container:choice").getBehaviors().get(0));
        tester.assertVisible("container:false");
    }
</pre>
<p>Unfortunately this doesn&#8217;t work because the WicketTester method executeBehavior calls<br />
tester.getServletRequest().setRequestToRedirectString(url.toString()) which sets the<br />
selected value to null.</p>
<p>To be able to test this behavior I created a method om my BaseTest class which looks like this:</p>
<pre lang="java">
   /**
     * Wicket tester.executeBehavior calls
     * tester.getServletRequest().setRequestToRedirectString(url.toString()) which sets the
     * selected value to null. To keep the value call tester.getServletRequest()
     * .setParameter(id, value) after tester.getServletRequest().setRequestToRedirectString
     *(url.toString())
     * @param id The wicket:id.
     * @param value The value that should be selected The value should be the selected index
     * from the list starting with 0.
     */
    public void executeBehavior(String id, String value) {
        AbstractAjaxBehavior behavior = (AbstractAjaxBehavior)
        tester.getComponentFromLastRenderedPage(id).getBehaviors().get(0);
        CharSequence url = behavior.getCallbackUrl(false);
        WebRequestCycle cycle = tester.setupRequestAndResponse(true);
        tester.getServletRequest().setRequestToRedirectString(url.toString());
        tester.getServletRequest().setParameter(id, value);
        tester.processRequestCycle(cycle);
    }
</pre>
<p>Now you can test the behavior like this.</p>
<pre lang="java">
  public void testShouldShowL2() {
        tester.assertInvisible("container:false");
        executeBehavior("container:choice", "1");
        tester.assertVisible("container:false");
    }
</pre>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2009/08/25/testing-wicket-ajaxbehavior/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2009%2F08%2F25%2Ftesting-wicket-ajaxbehavior%2F&amp;title=Testing%20Wicket%20AjaxBehavior" id="wpa2a_4"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2009/08/25/testing-wicket-ajaxbehavior/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testing Wicket with Fitnesse</title>
		<link>http://blog.xebia.com/2008/07/06/testing-wicket-with-fitnesse/</link>
		<comments>http://blog.xebia.com/2008/07/06/testing-wicket-with-fitnesse/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 18:44:25 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/blog.xebia.com/www/wp-content/plugins/autometa/autometa.php</b> on line <b>303</b><br />
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Wicket]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/?p=593</guid>
		<description><![CDATA[On our latest project, My colleague Tjeerd Kaastra and I, have been using Wicket. Since our GUI was so complex, and we had to write 100s of unit tests (a lot of corner cases), we sat down with our testers to find out how we should approach this. Because Our testers use Fitnesse to test [...]]]></description>
			<content:encoded><![CDATA[<p>On our latest project, My colleague Tjeerd Kaastra and I, have been using Wicket.<br />
Since our GUI was so complex, and we had to write 100s of unit tests (a lot of corner cases), we sat down with our testers to find out how we should approach this. Because Our testers use <span style="color:#643B71;font-weight: bold;font-size:110%;">Fitnesse</span> to test both functional acceptance as well as regression tests, they test a lot of the code as well. So we thought, why not integrate the two and that is what we did.</p>
<p>This blog describes how to test <span style="color:#643B71;font-weight: bold;font-size:110%;">Wicket</span> applications using <span style="color:#643B71;font-weight: bold;font-size:110%;">Fitnesse</span>. It is about stretching the limits of the Wicket test components to do so. We will try to explain this by using a small example project we have created to illustrate things. This example project has been inspired on the new user wizard example by Eelco Hillenius. We adapted this example so that it uses Spring, because most apps use a backend system. </p>
<p><span id="more-593"></span><br />
For those who don&#8217;t know what Fitnesse is:  FitNesse is a web server, a wiki, and a software testing tool. FitNesse allows users to enter specially formatted input (its format is accessible to non-programmers). This input is interpreted and tests are created automatically. So Fitnesse offers great options for automated testing beyond your unit tests. Wicket has got some utilities to unit test your application GUI outside a container.  These components are org.apache.wicket.util.tester.WicketTester and specifically for Form components there is org.apache.wicket.util.tester.FormTester. Would it not be great if we could use these unit test components for functional testing in Fitnesse? </p>
<p>Forms can be tested using the FormTester. But unfortunately, the FormTester is meant to test one form and as usual in a unit test, you write a seperate testcase per scenario. From a functional point of view, you might want to test a form submit, then go back to the page, correct some validation issues and re-submit the form.<br />
In real life, we used an abstract fixture class to provide all the generic methods and an extended fixture that gives us all the implementation details (like the correct application context, model class, start page, etc). The abstract fixture has for instance methods to check if components exist, set and select methods and lots more. See the example project.<br />
Furthermore, throughout the code you will see several boolean return values that seem unused. This is a fitnesse best-practice. Whenever a boolean is returned, the Fitnesse test will color the result cell green or red so you can verify that the method was executed.</p>
<p><strong>Testing the wizard</strong><br />
So for those who do not know the Wizard component, a wizard component is a dialog component that takes it&#8217;s users through a number of predefined steps. It has common functionality like a next, previous, finish and cancel button, and it uses a transition rules to let clients navigate through it&#8217;s steps.</p>
<p>Here&#8217;s a typical fitnesse table that you might want to use to test your flow:<br />
<img src="http://blog.xebia.com/wp-content/uploads/2008/07/example.jpg" alt="" title="example"  class="alignnone size-medium wp-image-640" /></p>
<p>Look&#8217;s easy enough, right? Well, there are quite some steps to take to achieve this easy testing scenario, and of course a couple of problems.</p>
<p><strong>Problem 1</strong>: using field values instead of index numbers<br />
Normally, using WicketTester you must define indexes for all fields that you want to test. When writing unit tests, this is not a problem but since we want to cater for functional testing, we will have to use reflection to achieve this.</p>
<p>We will not be going in to the ReflectionUtils, but the setFieldValueThroughSetMethod sets a value for a specific field through the corresponding Set method.<br />
Since we tend to use ListView components for repeating form elements, we also added a special method to be able to add a value to a component at a certain position in the list that the ListView uses.</p>
<p><strong>Problem 2</strong>: submitting multiple times and keeping you feedback<br />
The actual submit has several problems to solve:<br />
FormTester only allows one RequestCycle, meaning you can only submit a form once after which you must setup your testcase again. The formtester also does not update the model since it only tests one step.<br />
Since the submit only tests the local step, we have to call .onSubmit() on the Next-button to proceed to the next step.<br />
Feedback messages get lost if you submit a form using both FormTester and WicketTester. When you set a field value, store this value in a Map that will be used as a cache.</p>
<p>On submit, first retrieve the WebSession and remove all feedback messages.<br />
Then set any field values that you have cached on the form again.<br />
We then submit the FormTester to validate the form behavior and when all goes well (meaning there are no error messages caused by validating the form entries) we move to the next step.</p>
<p><strong>Problem 3</strong>: ListViews do not get rendered automatically<br />
Because you cannot update values on unrendered components, we will have to render our ListView components manually. Therefore, when moving to another step, we should render the components, see RenderComponents() in the Abstract Fixture.</p>
<p><strong>Problem 4</strong>: Map values to Object attributes.<br />
Because rendered values are Strings, for Example in our example application we have a User object which has a List of Role&#8217;s, we only display the roleName of the Role object.<br />
We need to be able to map an input string to an Object attribute.<br />
So if in fitnesse we say</p>
<p><img src="http://blog.xebia.com/wp-content/uploads/2008/07/selectwithvalue.jpg" alt="" title="selectwithvalue" class="alignnone wp-image-641" /></p>
<p>One of the nice things about a component-based framework is that your GUI components are backed by real Java objects. However, this makes it harder to test if a field is filled as expected. When setting up a fixture, we need to create a map of Object types and their corresponding GI fields.<br />
Add this to your initialize method:<br />
        addTypeAndFieldName(&#8220;Role&#8221;, &#8220;roleName&#8221;);<br />
        addCustomComponent(&#8220;org.apache.wicket.markup.html.basic.Label&#8221;);<br />
        addCustomComponent(&#8220;org.apache.wicket.markup.html.list.ListView&#8221;);</p>
<p>So lets illustrate a couple of tests. </p>
<p><strong>Test 1:</strong><br />
- Check if the expected components exist on the NewUserWizardPage.</p>
<p>In your browser the page look like this:<br />
<img src="http://blog.xebia.com/wp-content/uploads/2008/07/usernamestep.jpg" alt="" title="test1" width="300" height="126" class="alignnone size-medium wp-image-633" /></p>
<p>The fitnesse test looks like this:<br />
<img src="http://blog.xebia.com/wp-content/uploads/2008/07/componentscheck1.jpg" alt="" title="test1" class="alignnone size-medium wp-image-635" /></p>
<p>As you can see it is easy and readable. As you can see, our test is comform point 3. The testers do not need to fill in the Fully Qualified Name for RequiredTextField. To be able to do this, we keep an internal map of components fully qualified names. If you have Components that does not reside in the package <strong>org.apache.wicket.markup.html.form.</strong>, you have to add them by adding a line like addCustomComponent(&#8220;org.apache.wicket.markup.html.basic.Label&#8221;); to the initialize method in the fixture.) </p>
<p><strong>Test 2:</strong><br />
- Press the &#8220;Next&#8221; button and check if there are any errors and if we are on the correct Step in the wizard.</p>
<p>In your browser the page look like this:<br />
<img src="http://blog.xebia.com/wp-content/uploads/2008/07/usernamestepsubmit.jpg" alt="" title="test2" width="300" height="160" class="alignnone size-medium wp-image-637" /></p>
<p>The fitnesse test looks like this:<br />
<img src="http://blog.xebia.com/wp-content/uploads/2008/07/submit.jpg" alt="" title="test2" class="alignnone size-medium wp-image-636" /></p>
<p><strong>Test 3:</strong><br />
- Fill in username and press the &#8220;Next&#8221; button and check if there are any errors and if we are on the correct Step in the wizard, then fill in email address and press the &#8220;Next&#8221; button and check if there are any errors and if we are on the correct Step in the wizard. </p>
<p>The fitnesse test looks like this:<br />
<img src="http://blog.xebia.com/wp-content/uploads/2008/07/test31.jpg" alt="" title="test3" class="alignnone size-medium wp-image-639" /></p>
<p>These are just a few examples of how to test you wicket application using fitnesse.<br />
As you can see, it make it very easy to test and it is readable!!</p>
<p>By combining the power of Fitnesse and Wicket , we are enabling non-techies to write automated tests. This way, your UI is tested completely in each iteration within a few hours, this gives us a major quality improvement and it really speeds up the testing (imagine how much time it would take to do a regression test by hand!). Our project proved the combination to be very valuable to both developers, testers and our customer.</p>
<p>The sources of the example project can be found <a href='http://blog.xebia.com/wp-content/uploads/2008/07/wicketfitnesse.zip'>here</a>. Read the installation.txt file in the directory src/main/documents to get you started with the example app. </p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2008/07/06/testing-wicket-with-fitnesse/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2008%2F07%2F06%2Ftesting-wicket-with-fitnesse%2F&amp;title=Testing%20Wicket%20with%20Fitnesse" id="wpa2a_6"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2008/07/06/testing-wicket-with-fitnesse/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Wicket &#8211; Updating ListViews using an AjaxLink</title>
		<link>http://blog.xebia.com/2008/06/04/wicket-updating-listviews-using-an-ajaxlink/</link>
		<comments>http://blog.xebia.com/2008/06/04/wicket-updating-listviews-using-an-ajaxlink/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 08:20:56 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Wicket]]></category>

	<!-- AutoMeta Start -->
	<category></category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/?p=581</guid>
		<description><![CDATA[Consider the following senario: we want to display some data in a table like manner, and we want it to update when we click on a link or button. We do not want to do a complete page refresh, we want it in an ajax way. Also we would like the modify the css for [...]]]></description>
			<content:encoded><![CDATA[<p>Consider the following senario: we want to display some data in a table like manner, and we want it to update when we click on a link or button. We do not want to do a complete page refresh, we want it in an ajax way. Also we would like the modify the css for each cell.</p>
<p>In wicket you can use a ListView iterate over a List of Objects and display them in a table like manner.<br />
This blog describes how you can update ListView data and modify the css for each cell.<br />
<span id="more-581"></span><br />
So how do we start?</p>
<p>Well first we need to create a ListView. Lets call it <em><strong>view</strong></em>.<br />
But before we do that we need a List of objects we want to display. So lets create it.<br />
I use a List of TestObject&#8217;s.</p>
<p>As you can see below, this isn&#8217;t very hard.</p>
<pre lang="java">
private ListView view;
private List<TestObject> objects;

objects = Arrays.asList(new TestObject[] {
    new TestObject("one", true),
    new TestObject("two", false),
    new TestObject("three", true)});

view = new ListView("view", objects) {
    @Override
    protected void populateItem(ListItem item) {
        Label label = new Label("label", new PropertyModel(item.getModel(), "name"));
        label.setOutputMarkupId(true);
        item.add(label);
    }
};
</pre>
<p>Next we will create an IndicatingAjaxFallbackLink which is basically a AjaxLink that shows an indicator.</p>
<pre lang="java">
private IndicatingAjaxFallbackLink link;

link = new IndicatingAjaxFallbackLink("link") {
    @Override
    public void onClick(AjaxRequestTarget target) {
        objects = Arrays.asList(new TestObject[] {
            new TestObject("four", false),
            new TestObject("five", true),
            new TestObject("six", false)});
        view.setList(objects);
        target.addChildren(view, Label.class);
    }
};
</pre>
<p>Thats all. Now see that we add a new List of objects to the ListView. To make sure the ListView is updated we add
<pre lang="java">target.addChildren(view, Label.class);</pre>
<p> instead of
<pre lang="java">target.addComponent(view);</pre>
<p>. As a ListView is a repeater, we cannot updated it, but we can update components in a ListView.</p>
<p>So now we can update a ListView, but how do we change the css for each field?</p>
<p>We add an AttributeModifier. In the populateItem method show above we just add the following</p>
<pre lang="java">
label.add(new AttributeModifier("class", true, new PropertyModel(item.getModel(), "odd") {
    @Override
    public Object getObject() {
        return ((Boolean) super.getObject()) ? "odd" : "even";
    }
}));
</pre>
<p>The getObject method is overridden, because the method getOdd() on the TestObject returns a boolean. So instead of returning true or false, it now returns &#8220;odd&#8221; or &#8220;even&#8221; which are css class styles.</p>
<p>That&#8217;s it.</p>
<p>I have attached the example project  <a href='http://blog.xebia.com/wp-content/uploads/2008/06/wicket-example.zip'>here</a> so you can look into the code yourself.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2008/06/04/wicket-updating-listviews-using-an-ajaxlink/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2008%2F06%2F04%2Fwicket-updating-listviews-using-an-ajaxlink%2F&amp;title=Wicket%20%26%238211%3B%20Updating%20ListViews%20using%20an%20AjaxLink" id="wpa2a_8"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2008/06/04/wicket-updating-listviews-using-an-ajaxlink/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>JavaOne 2008 Day Four: That&#8217;s a wrap!</title>
		<link>http://blog.xebia.com/2008/05/10/javaone-2008-day-four-thats-a-wrap/</link>
		<comments>http://blog.xebia.com/2008/05/10/javaone-2008-day-four-thats-a-wrap/#comments</comments>
		<pubDate>Sat, 10 May 2008 17:28:44 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[JavaOne]]></category>
		<category><![CDATA[Semantic Web]]></category>

	<!-- AutoMeta Start -->
	<category></category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/?p=561</guid>
		<description><![CDATA[Today was the last day of the JavaOne Conference. We came to the point when a lot of OutOfMemoryErrors where thrown. We just managed to squeeze in the last sessions. Today&#8217;s keynote was all about toys. The guys from the Netbeans team showed some new features such as a JavaScript editor (which contains code completion), [...]]]></description>
			<content:encoded><![CDATA[<p>Today was the last day of the JavaOne Conference. We came to the point when a lot of OutOfMemoryErrors where thrown. We just managed to squeeze in the last sessions.</p>
<p>Today&#8217;s keynote was all about toys. The guys from the Netbeans team showed some new features such as a JavaScript editor (which contains code completion), Sentilla showed there small sensor thingies, which you can program to gather information, such as acceleration, temperature etc.., LiveScribe showed there very cool pen and lots more.</p>
<p>Today&#8217;s topic included:</p>
<ul>
<li>User Experience</li>
<li>SOA</li>
<li>Semantic Web</li>
</ul>
<p><span id="more-561"></span></p>
<p><strong>Mischa and Erik Jan  on The Layperson’s Guide to Building a Better User Experience</strong></p>
<p>Burk Hufnagel showed in his presentation how to <italic>leverage the skills you already have and build experiences that delight your users.</italic></p>
<p>The term “User Experience” describes how people feel about using something. This is very important, because if the experience isn&#8217;t satisfying,</p>
<ul>
<li>The ability to get things done is slow.</li>
<li>The software will be replaced by software that does have a satisfying experience.</li>
</ul>
<p>The Layperson&#8217;s guide is a guide for non-experts, on how to develop the best &#8220;User Experience&#8221; for the target group.</p>
<p>So what affects the user’s experience?</p>
<ul>
<li>Interaction Design</li>
<li>How the users thinks it works.</li>
<li>How the system is actually built.</li>
<li>How the system presents itself to the user</li>
</ul>
<p>Doing Test Driven Design has a couple of benefits like</p>
<ul>
<li>Writing tests first makes it easier to you create the right interfaces and behaviors later.</li>
<li>Writing tests first can reduce the chances of the implementation model leaking into the representation model.</li>
</ul>
<p>So how do you start? Well identifying the Key users is a good start.<br />
They are te ones that must be satisfied for the product to succeed in the market.<br />
Next you need to develop Persona&#8217;s, figure out there behavior, motivation and goals. It may take some time to get to the<br />
bottom of this, but it is better then to guess what they want. Try to limit the amount of persona&#8217;s, because you need to create<br />
an interface for all of them, to be able to get the best User Experience for all Key Users.</p>
<p>Developing like this may take a little more time on startup, but will gain a lot in the end.</p>
<p><strong>Jeroen on the Semantic Web</strong><br />
Today I had another talk on the Semantic Web, this time a real Technical Session by one of the same guys who talked in yesterday&#8217;s discussion panel, Dean Allemang from TopQuadruant. His talk was similarly titled as his book: Semantic Web for the Working Ontologist.</p>
<p>One of the best ways to describe the semantic web is probably using the following sentence: From data on the web to a Web of Data. Our current Web mostly consists of data that us humans can interpret as meaningful, but it has no meaning whatsoever to machines. In the Semantic Web, it is all about adding another dimension to data so that both humans and computers can reason about the data.</p>
<p>One of the standards for the Semantic Web is the Resource Description Framework (RDF). RDF is a way of storing data as triples (subject, predicate, object) distributed across a network, using URI&#8217;s as identifiers  for the data. For instance if I wanted to model the plays Hamlet and Romeo and Juliet written by Shakespeare in RDF I could write down the following:</p>
<pre>
(1, my:writer, Shakespeare)
(1, my:title, Hamlet)
(2, my:writer, Shakespeare)
(2, my:title, Romeo and Juliet)
</pre>
<p>However as you can see, my:title could be very different from your:title. Where my:title is the title of the play, your:title could be your degree, like &#8220;MSc.&#8221;. This means that the first requirement for the Semantic Web is that we need to agree to disagree. Using namespacing we can assign different meanings to the same terms.</p>
<p>The Semantic Web is all about data, and not about how you represent the data. Yo can chose your own representation and map that to someone else&#8217;s representation. For example, if I wanted to say that my:writer is the same as a Dubblin Core author, I could write down the following RDF triple:</p>
<pre>
(my:writer, owl:equivalentProperty, dc:author)
</pre>
<p>Now anyone knows that if I say writer, I am actually talking about an author. What is nice is that RDF is used for both the data, as well as the schema. Usig these constructions we can build an ontology. An ontology is best described as: A reusable component of a distributed semantic model. A well known example of an ontology is the Dublin Core standard.</p>
<p>This primer into the Semantic Web was pretty good and clear. I hope they&#8217;ll give some more talks on this subject.</p>
<p><strong>Marco on his day</strong><br />
<em>Keynote: extreme innovation</em><br />
This one was about some of the really cool things you can do with Java. The absolute highlight was the Pulse smartpen, a Java-enabled pen that can not only record what you write &#038; what you hear at the same time, but also order a cup of coffee. In Mandarin. Also noteworthy was a car that can drive &#038; park by itself, which will become hugely popular amongst Asian people &#038; women, I hope.</p>
<p><em>Designing GUI&#8217;s 101: From User Needs To Usable GUI&#8217;s</em><br />
Thank heaven this one only lasted for about 30 minutes, as absolutely nothing new was said (&#8220;so we first need to ask the users what they want, then create a prototype, and then ask the same users again what they think of it? Brilliant!&#8221;).</p>
<p><em>Using SOA, EAI, and BPM to reengineer Legacy Applications to Java 2 Platform, Enterprise J2EE Platform</em><br />
A real-life story about how to drag a legacy system kicking &#038; screaming into the 21st century. I really dug this one, with a very energetic speaker talking about how they wanted to save 30 years of business logic stored in the system by putting JNI on top of it, then later taking another step into the future with SOA. One lesson learned: apparently it&#8217;s easier to teach Java developers assembly code than vice versa. Which should insult me in some way as I started out doing machine language, but I&#8217;m just too tired to care at this point.</p>
<p><em>Open Source Development Tools fir the Java Platform, Enterprise Edition (Java Platform), Web 2.0 and SOA</em><br />
The final session I attended and it sure was hot, temperature wise that is. The demo gods still seemed to be angry, resulting in the room telling the presenter what to do, instead of the other way around (rule #61: if there is a stack trace, study it to see what is wrong – it will save time). After a change of subject (JBoss ESB instead of Seam) things got pretty interesting again, too bad it wasn&#8217;t possible anymore to get hold of the free development cd.</p>
<p><em>Epilogue</em><br />
It was really clear that this was the last day, as both the number of visitors and the energy level of those still present was down. After attending so many sessions (and writing about them to boot) I myself am &#8216;stuffed&#8217;, but all things considered it was a fantastic experience, and I certainly learned a lot. I&#8217;m glad I decided to concentrate on one track (SOA), even though it means I missed out on some other great presentations. Then again, my esteemed colleagues saw those, and I&#8217;m pretty sure they will blog about it as well somewhere else.</p>
<p>What do you mean, they share this space with me? I&#8217;m a star damn it, I deserve my own space! Now go get me some monkeys!</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2008/05/10/javaone-2008-day-four-thats-a-wrap/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2008%2F05%2F10%2Fjavaone-2008-day-four-thats-a-wrap%2F&amp;title=JavaOne%202008%20Day%20Four%3A%20That%26%238217%3Bs%20a%20wrap%21" id="wpa2a_10"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2008/05/10/javaone-2008-day-four-thats-a-wrap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wicket and List Choice Transfers</title>
		<link>http://blog.xebia.com/2008/03/25/wicket-and-list-choice-transfers/</link>
		<comments>http://blog.xebia.com/2008/03/25/wicket-and-list-choice-transfers/#comments</comments>
		<pubDate>Tue, 25 Mar 2008 20:12:50 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ajax]]></category>

	<!-- AutoMeta Start -->
	<category>wicket</category>
	<category>working</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2008/03/25/wicket-and-list-choice-transfers/</guid>
		<description><![CDATA[Consider the following scenario: we want to have two select boxes and we want to add options from one to the other and back. Currently, this is not easily possible in Wicket, even though there are a lot of extensions available. This blog describes an easy way to create a component which does just that! [...]]]></description>
			<content:encoded><![CDATA[<p>Consider the following scenario: we want to have two select boxes and we want to add options from one to the other and back.<br />
Currently, this is not easily possible in Wicket, even though there are a lot of extensions available.<br />
This blog describes an easy way to create a component which does just that!</p>
<tr>
<td>&nbsp;</td>
<td><img src="http://blog.xebia.com/wp-content/uploads/2008/03/select-transfer.gif" alt="select transfer" /></td>
<td>&nbsp;</td>
<td><img src="http://blog.xebia.com/wp-content/uploads/2008/03/select-transfer-2.gif" alt="select transfer" /></td>
</tr>
<p><span id="more-468"></span><br />
</p>
<p>For creating a Select box there are multiple options available. You can use a  ListChoice for selecting a single option or a ListMultipleChoice for selecting multiple options.</p>
<p>So how do we start? </p>
<p>Well, first we need to create two ListMultipleChoice object. Lets give them the following names: <em><strong>originals</strong></em> and <em><strong>destinations</strong></em></p>
<p>As you can see below, this isn&#8217;t very hard.</p>
<pre lang="java">

  // The Selected options in the list choices.
  private List<String> selectedOriginals;
  private List<String> selectedDestinations;

ListMultipleChoice originals = new ListMultipleChoice("originals",
  new PropertyModel(this, "selectedOriginals"), new LoadableDetachableModel() {
      @Override
      protected Object load() {
        return Arrays.asList(new String[] {"one", "two", "three", "four", "five", "six"});
      }
    });

ListMultipleChoice destinations = new ListMultipleChoice("destinations",
   new PropertyModel(this, "selectedDestinations"), new LoadableDetachableModel() {
      @Override
      protected Object load() {
        return new ArrayList<String>();
      }
    });
</pre>
<p>and the matching HTML part:</p>
<pre lang="xml">
<select wicket:id="originals" size="7" style="width:200px;"></select>
<select wicket:id="destinations" size="7" style="width:200px;"></select>
</pre>
<p>Next we need two buttons, one for adding and one for removing options from a select box.</p>
<pre lang="java">
AjaxButton add = new AjaxButton("add") {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form) {
            update(target,selectedOriginals, originals, destinations);
      }
    };

AjaxButton remove = new AjaxButton("remove") {
       @Override
      protected void onSubmit(AjaxRequestTarget target, Form form) {
           update(target, selectedDestinations, destinations, originals);
      }
    };

  /**
   * Updates the select boxes.
   * @param target The {@link AjaxRequestTarget}.
   */
  private void update(AjaxRequestTarget target, List<String> selections, ListMultipleChoice from, ListMultipleChoice to) {
    for (String destination : selections) {
      List<String> choices = getChoices(from);
      if (!to.getChoices().contains(destination)) {
        to.getChoices().add(destination);
        choices.remove(destination);
        from.setChoices(choices);
      }
    }
    target.addComponent(to);
    target.addComponent(from);
  }
</pre>
<p>and the matching HTML part:</p>
<pre lang="xml">
<input wicket:id="add" type="button" value="&rarr;" />
<input wicket:id="remove" type="button" value="&larr;" />
</pre>
<p>As you can see I use an AjaxButton, which is basically what you want for this example. We do not want to do a full page reload.</p>
<p>That&#8217;s it. </p>
<p>Next thing we want to do is create a component that does all of this, so we can reuse it. After analysing, I found out that we only need a method which retrieves all options. I have called it getOriginalChoices();<br />
If you look into the attached example project, you can see that it is now very easy to use it.</p>
<p>To use the Component you need to do the following:</p>
<pre lang="java">
    ListMultipleChoiceTransfer listMultipleChoiceTransfer = new ListMultipleChoiceTransfer("test"){
      @Override
      public List getOriginalChoices() {
        return Arrays.asList(new String[] {"one", "two", "three", "four", "five", "six"});
      }
    };
</pre>
<p>and the matching html</p>
<pre lang="xml">
<span wicket:id="test">ListMultipleChoiceTransfer will be placed here</span>
</pre>
<p>I have attached the example project <a href="http://blog.xebia.com/wp-content/uploads/2008/03/MultiSelectTransfer.zip">here</a> so you can look into the code yourself.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2008/03/25/wicket-and-list-choice-transfers/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2008%2F03%2F25%2Fwicket-and-list-choice-transfers%2F&amp;title=Wicket%20and%20List%20Choice%20Transfers" id="wpa2a_12"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2008/03/25/wicket-and-list-choice-transfers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How to make Displaytag ajax enabled using DWR?</title>
		<link>http://blog.xebia.com/2007/12/10/how-to-make-displaytag-ajax-enabled-using-dwr/</link>
		<comments>http://blog.xebia.com/2007/12/10/how-to-make-displaytag-ajax-enabled-using-dwr/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 21:28:08 +0000</pubDate>
		<dc:creator>Mischa Dasberg</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ajax]]></category>

	<!-- AutoMeta Start -->
	<category>displaytag</category>
	<category>ajax</category>
	<category>display</category>
	<category>episode</category>
	<category>paging</category>
	<category>airdate</category>
	<category>senario</category>
	<category>enabled</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.xebia.com/2007/12/10/how-to-make-displaytag-ajax-enabled-using-dwr/</guid>
		<description><![CDATA[Displaytag is an open source suite of custom tags with which you can easily display a collection of Objects as a table including direct support for paging and sorting. Normally selecting a new page, or sorting the tables leads to a complete page-refresh. It is more user-friendly to refresh only the data in the table [...]]]></description>
			<content:encoded><![CDATA[<p>Displaytag is an open source suite of custom tags with which you can easily display a collection of Objects as a table including direct support for paging and sorting. Normally selecting a new page, or sorting the tables leads to a complete page-refresh. It is more user-friendly to refresh only the data in the table using Ajax technology, however Displaytag doesn&#8217;t offer this out-of-the-box. But we can of course try to add support for this using one of the many Ajax frameworks that are currently available. </p>
<p>A non ajax enabled Displaytag would do a request to a controller for every action such as a sorting or selecting a next page. This would result in a complete page refresh (step 1-8 ). When we Ajax enable the Displaytag we skip the page refresh and only refresh a specific piece of the page using an exposed service which provides the updated HTML fragment (step 1a-8a).<br />
<span id="more-336"></span><br />
<img src="http://blog.xebia.com/wp-content/uploads/2007/12/flow.gif" alt="flow" /></p>
<p>In the example I am going to use the following technologies: </p>
<ul>
<li><a href="http://www.springframework.org/">Spring</a></li>
<li><a href="http://www.hibernate.org/">Hibernate</a></li>
<li><a href="http://getahead.org/dwr">Dwr</a></li>
<li><a href="http://displaytag.sourceforge.net/11/">Displaytag</a></li>
</ul>
<p>The senario is as follows: We want to display episodes in a table. We want to do this in an Ajax way by using DWR. But where do we start?</p>
<p>Well, first of all we create a domain object called Episode.</p>
<pre lang="java">
public class Episode {
   long id;
   String show;
   String name;
   String episode;
   String airDate;
....
}
</pre>
<p>Next we create a repository.</p>
<pre lang="java">
public class EpisodeRepository extends HibernateDaoSupport {

    public List<Episode> getAllEpisodes(int firstResult, int maxResults, String orderBy,
    boolean ascending) {
        Criteria criteria = getSession().createCriteria(Episode.class)
            .setFirstResult(firstResult)
	    .setMaxResults(maxResults)
	    .addOrder(ascending ? Order.asc(orderBy) : Order.desc(orderBy));
	    return criteria.list();
	}

    public int getNumberOfEpisodes() {
        Criteria criteria = getSession().createCriteria(Episode.class);
	criteria.setProjection(Projections.count("id"));
	return (Integer)criteria.uniqueResult();
    }
}
</pre>
<p>And a Jsp containing the Displaytag for presenting the collection of Episodes.<br />
<code>&lt;display:table id="ep" name="<i><b>eps</b></i>" sort="external" requestURI="<i><b>replaceURI</b></i>" pagesize="30" partialList="true" size="${<i><b>nrOfEps</b></i>}"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;display:setProperty name="basic.empty.showtable" value="true" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;display:column title="Show" property="show" sortable="true" sortName="show" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;display:column title="Name" property="name" sortable="true" sortName="name" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;display:column class="Episode" property="episode" sortable="true" sortName="episode" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;display:column title="Airdate" property="airDate" sortable="true" sortName="airDate" /&gt;<br />
&lt;/display:table&gt;<br />
</code><br />
Note that I use <i><b>replaceURI</b></i> as requestURI. This is very important because we are going to replace this with a call to a javascript method. Displaytag creates links like &lt;a href=&#8221;repaceURI?d-2332-o=1&#8230;.&#8221;&gt; and this should be replaced by &lt;a href=&#8221;javascript:update(&#8216;d-2332-o=1&#8230;&#8217;)&gt; so that we the links will be Ajax enabled too. Unfortunatly this is not the only thing that we need to update. We need to update the range we are displaying, the page we are currently on and how the data is sorted.</p>
<p>So how do we do that?<br />
Well, we need to expose a service using DWR. DWR is an Ajax toolkit which make it possible to expose services which can then be called from JavaScript. I created an abstract generic class so that you can use it to enable any service you like. The abstract class contains the following method:</p>
<pre lang="java">
public abstract class AbstractExposedDisplayTagService<T> implements InitializingBean {

    public void afterPropertiesSet() throws Exception {
        ....
    }

    public String findAllObjects(String criteria) {
        WebContext wctx = WebContextFactory.get();
	HttpServletRequest request = wctx.getHttpServletRequest();

	// split results and set values;
	int maxResults = Integer.parseInt(getCriterionValue(criteria, "maxResults", DEFAULT_MAXIMUM_RESULTS));
	int page = Integer.parseInt(getCriterionValue(criteria, displayTagPage, "1"));
	boolean ascending = Integer.parseInt(getCriterionValue(criteria, displayTagSortOrder, "1")) == 1 ? true : false;
	String orderBy = getCriterionValue(criteria, displayTagOrderBy, "id");
	int firstResult = (page - 1) * maxResults;
	int numberOfObjects = getNumberOfObjects();

	// set the episodes on the request so dwr can reload the jsp part.
	request.setAttribute(getObjectsName(), getObjects(firstResult, maxResults, orderBy, ascending));
	request.setAttribute(getNumberOfObjectsName(), numberOfObjects);
	try {
	    String html = wctx.forwardToString(viewFragment);
	    html = DisplayTagReplacementUtil.updatePagingHtml(html, page, maxResults, numberOfObjects, displayTagPage);
	    html = DisplayTagReplacementUtil.updateSortOrderHtml(html, ascending, displayTagSortOrder);
	    html = DisplayTagReplacementUtil.updateHtmlLinks(html);
	    return html;
	} catch (ServletException e) {
	    return "";
	} catch (IOException e) {
	    return "";
	}
}
}
</pre>
<p>And here is the implementation. </p>
<pre lang="java">
public class EpisodeService extends AbstractExposedDisplayTagService<Episode> {
	private EpisodeRepository episodeRepository;

	@Override
	public int getNumberOfObjects() {
		return episodeRepository.getNumberOfEpisodes();
	}

	@Override
	public String getNumberOfObjectsName() {
		return "numberOfEpisodes";
	}

	@Override
	public List<Episode> getObjects(int firstResult, int maxResults, String orderBy, boolean ascending) {
		return episodeRepository.getAllEpisodes(firstResult, maxResults, orderBy, ascending);
	}

	@Override
	public String getObjectsName() {
		return "episodes";
	}

	public void setEpisodeRepository(EpisodeRepository episodeRepository) {
		this.episodeRepository = episodeRepository;
	}
}
</pre>
<p>Now you see that the <i><b>findAllObjects</b></i> method calls 3 static update methods on the DisplayTagReplacementUtil class.<br />
These are responsible for the actual Ajax enabling. They use regular expressions to update the links, sorting etc.. </p>
<p>Finally we need to add some JavaScript to be able to call the exposed service methods.<br />
The following piece of code should be in the head of the jsp , in which you include the jsp containing the displaytag shown above in.<br />
<code>&lt;script type='text/javascript' src='&lt;c:url value="/dwr/interface/EpisodeService.js"/&gt;'&gt;&lt;/script&gt;<br />
&lt;script type='text/javascript' src='&lt;c:url value="/dwr/engine.js"/&gt;'&gt;&lt;/script&gt;<br />
&lt;script type='text/javascript' src='&lt;c:url value="/dwr/util.js"/&gt;'&gt;&lt;/script&gt;<br />
&lt;link rel="stylesheet" type="text/css" href='&lt;c:url value="/css/displaytag.css"/&gt;' /&gt;<br />
</code><br />
and the javascript:<br />
<code>&lt;script type="text/javascript"&gt;<br />
	function update(criteria) {<br />
	  	EpisodeService.findAllObjects(criteria, function(data) {<br />
	    	dwr.util.setValue("displayTable", data, { escapeHtml:false });<br />
	  	});<br />
	}<br />
	update("");<br />
&lt;/script&gt;<br />
</code></p>
<p>It is now a simple matter of extending the abstract class and you have Ajax enabled your Displaytag .<br />
I have attached the example project <a href="http://blog.xebia.com/wp-content/uploads/2007/12/Displaytag+dwr.zip">here</a> so you can look into the code yourself.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="small" count="1" href="http://blog.xebia.com/2007/12/10/how-to-make-displaytag-ajax-enabled-using-dwr/"></g:plusone></div><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.xebia.com%2F2007%2F12%2F10%2Fhow-to-make-displaytag-ajax-enabled-using-dwr%2F&amp;title=How%20to%20make%20Displaytag%20ajax%20enabled%20using%20DWR%3F" id="wpa2a_14"><img src="http://blog.xebia.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xebia.com/2007/12/10/how-to-make-displaytag-ajax-enabled-using-dwr/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  blog.xebia.com/author/mdasberg/feed/ ) in 0.90534 seconds, on Feb 9th, 2012 at 4:08 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 9th, 2012 at 5:08 pm UTC -->
