Wicket in Action2020-11-13T09:19:21+00:00http://wicketinaction.com/Wicket in ActionWorking with background jobs2014-07-01T07:00:00+00:00http://wicketinaction.com/2014/07/working-with-background-jobs<h1 id="the-problem">The problem</h1>
<p>From time to time Wicket users ask questions related to how to deal with background jobs in Wicket. E.g. “How do I make Application or Session available
to a background thread?” Or, “How do I deal with showing some progress information, or allow the user to cancel a background process?”. We have build a small toy
project to illustrate a possible way to do those things. We hope this project could help people get started on rolling their own solutions.</p>
<p>The complete code of the application can be found at: <a target="_blank" href="https://github.com/reiern70/antilia-bits/tree/master/bgprocess">https://github.com/reiern70/antilia-bits/tree/master/bgprocess</a>. Feel free to just grab the code and use it in any way you please.</p>
<h1 id="the-solution">The solution</h1>
<p>We start by defining an interface that represents a Task. i.e. some lengthy computation to be done in a background non-WEB thread.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">ITask</span> <span class="kd">extends</span> <span class="nc">Serializable</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">doIt</span><span class="o">(</span><span class="nc">ExecutionBridge</span> <span class="n">bridge</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>the method doIt() receives a context/bridge class that can be used to communicate with the WEB layer.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExecutionBridge</span> <span class="kd">implements</span> <span class="nc">Serializable</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">taskName</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">volatile</span> <span class="kt">boolean</span> <span class="n">stop</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">volatile</span> <span class="kt">boolean</span> <span class="n">cancel</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">volatile</span> <span class="kt">int</span> <span class="n">progress</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">message</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">ExecutionBridge</span><span class="o">()</span> <span class="o">{</span>
<span class="o">}</span>
<span class="o">...</span> <span class="n">setter</span> <span class="n">and</span> <span class="n">gettters</span>
<span class="o">}</span></code></pre></figure>
<p>As an example we provide a dummy task, that looks like.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">DummyTask</span> <span class="kd">implements</span> <span class="nc">ITask</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">Logger</span> <span class="no">LOGGER</span> <span class="o">=</span> <span class="nc">LoggerFactory</span><span class="o">.</span><span class="na">getLogger</span><span class="o">(</span><span class="nc">DummyTask</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="nd">@javax</span><span class="o">.</span><span class="na">inject</span><span class="o">.</span><span class="na">Inject</span>
<span class="kd">private</span> <span class="nc">IAnswerService</span> <span class="n">answerService</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">DummyTask</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">Injector</span><span class="o">.</span><span class="na">get</span><span class="o">().</span><span class="na">inject</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">doIt</span><span class="o">(</span><span class="nc">ExecutionBridge</span> <span class="n">bridge</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// check thread locals are available</span>
<span class="no">LOGGER</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"App: {}"</span><span class="o">,</span> <span class="nc">Application</span><span class="o">.</span><span class="na">exists</span><span class="o">());</span>
<span class="no">LOGGER</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"Session: {}"</span><span class="o">,</span> <span class="nc">Session</span><span class="o">.</span><span class="na">exists</span><span class="o">());</span>
<span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span><span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o"><=</span> <span class="mi">100</span><span class="o">;</span> <span class="o">)</span> <span class="o">{</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setProgress</span><span class="o">(</span><span class="n">i</span><span class="o">);</span>
<span class="k">if</span><span class="o">(</span><span class="n">bridge</span><span class="o">.</span><span class="na">isCancel</span><span class="o">())</span> <span class="o">{</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setMessage</span><span class="o">(</span><span class="n">answerService</span><span class="o">.</span><span class="na">getMessage</span><span class="o">(</span><span class="nc">AnswerType</span><span class="o">.</span><span class="na">IS_CANCEL</span><span class="o">,</span> <span class="n">i</span><span class="o">));</span>
<span class="c1">// end the task!</span>
<span class="k">return</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">if</span><span class="o">(</span><span class="n">bridge</span><span class="o">.</span><span class="na">isStop</span><span class="o">())</span> <span class="o">{</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setMessage</span><span class="o">(</span><span class="n">answerService</span><span class="o">.</span><span class="na">getMessage</span><span class="o">(</span><span class="nc">AnswerType</span><span class="o">.</span><span class="na">IS_STOP</span><span class="o">,</span> <span class="n">i</span><span class="o">));</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setMessage</span><span class="o">(</span><span class="n">answerService</span><span class="o">.</span><span class="na">getMessage</span><span class="o">(</span><span class="nc">AnswerType</span><span class="o">.</span><span class="na">ALL_OK</span><span class="o">,</span> <span class="n">i</span><span class="o">));</span>
<span class="n">i</span><span class="o">++;</span>
<span class="o">}</span>
<span class="k">try</span> <span class="o">{</span>
<span class="nc">Thread</span><span class="o">.</span><span class="na">sleep</span><span class="o">(</span><span class="mi">1000L</span><span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">InterruptedException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setProgress</span><span class="o">(</span><span class="mi">100</span><span class="o">);</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setMessage</span><span class="o">(</span><span class="n">answerService</span><span class="o">.</span><span class="na">getMessage</span><span class="o">(</span><span class="nc">AnswerType</span><span class="o">.</span><span class="na">IS_ERROR</span><span class="o">,</span> <span class="n">i</span><span class="o">));</span>
<span class="k">return</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>This task does nothing but iterate from 1 to 100 and repeatedly call a service, IAnswerService, to get some text messages to pass to the WEB layer via the ExecutionBridge instance.
This class also uses information contained on bridge to determine if the task should be stopped or canceled. Mind that the task uses Wicket injection machinery to inject an implementation of IAnswerService, so, that mean we need to have Application as a thread local when Injector.get().inject(this); is called. This is achieved by providing a runnable that beside executing tasks, will
make sure Application and Session are attached, and properly detached, as thread locals.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">TasksRunnable</span> <span class="kd">implements</span> <span class="nc">Runnable</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">ITask</span> <span class="n">task</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">ExecutionBridge</span> <span class="n">bridge</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">Application</span> <span class="n">application</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">Session</span> <span class="n">session</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">TasksRunnable</span><span class="o">(</span><span class="nc">ITask</span> <span class="n">task</span><span class="o">,</span> <span class="nc">ExecutionBridge</span> <span class="n">bridge</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">task</span> <span class="o">=</span> <span class="n">task</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">bridge</span> <span class="o">=</span> <span class="n">bridge</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">application</span> <span class="o">=</span> <span class="nc">Application</span><span class="o">.</span><span class="na">get</span><span class="o">();</span>
<span class="k">this</span><span class="o">.</span><span class="na">session</span> <span class="o">=</span> <span class="nc">Session</span><span class="o">.</span><span class="na">exists</span><span class="o">()</span> <span class="o">?</span> <span class="nc">Session</span><span class="o">.</span><span class="na">get</span><span class="o">()</span> <span class="o">:</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">{</span>
<span class="nc">ThreadContext</span><span class="o">.</span><span class="na">setApplication</span><span class="o">(</span><span class="n">application</span><span class="o">);</span>
<span class="nc">ThreadContext</span><span class="o">.</span><span class="na">setSession</span><span class="o">(</span><span class="n">session</span><span class="o">);</span>
<span class="n">task</span><span class="o">.</span><span class="na">doIt</span><span class="o">(</span><span class="n">bridge</span><span class="o">);</span>
<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span>
<span class="nc">ThreadContext</span><span class="o">.</span><span class="na">detach</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>Additionally, we provide custom Session and Application classes containing the machinery to track user’s running tasks and to launch tasks, respectively. See</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">BgProcessApplication</span> <span class="kd">extends</span> <span class="nc">WebApplication</span> <span class="o">{</span>
<span class="nc">ExecutorService</span> <span class="n">executorService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ThreadPoolExecutor</span><span class="o">(</span><span class="mi">10</span><span class="o">,</span> <span class="mi">10</span><span class="o">,</span>
<span class="mi">0L</span><span class="o">,</span> <span class="nc">TimeUnit</span><span class="o">.</span><span class="na">MILLISECONDS</span><span class="o">,</span>
<span class="k">new</span> <span class="nc">LinkedBlockingQueue</span><span class="o"><</span><span class="nc">Runnable</span><span class="o">>());</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="nc">Class</span><span class="o"><?</span> <span class="kd">extends</span> <span class="nc">WebPage</span><span class="o">></span> <span class="nf">getHomePage</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nc">HomePage</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">init</span><span class="o">();</span>
<span class="n">com</span><span class="o">.</span><span class="na">google</span><span class="o">.</span><span class="na">inject</span><span class="o">.</span><span class="na">Injector</span> <span class="n">injector</span> <span class="o">=</span> <span class="nc">Guice</span><span class="o">.</span><span class="na">createInjector</span><span class="o">(</span><span class="n">newModule</span><span class="o">());</span>
<span class="n">getComponentInstantiationListeners</span><span class="o">().</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">GuiceComponentInjector</span><span class="o">(</span><span class="k">this</span><span class="o">,</span> <span class="n">injector</span><span class="o">));</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onDestroy</span><span class="o">()</span> <span class="o">{</span>
<span class="n">executorService</span><span class="o">.</span><span class="na">shutdown</span><span class="o">();</span>
<span class="k">try</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">executorService</span><span class="o">.</span><span class="na">awaitTermination</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="nc">TimeUnit</span><span class="o">.</span><span class="na">SECONDS</span><span class="o">))</span> <span class="o">{</span>
<span class="n">executorService</span><span class="o">.</span><span class="na">shutdownNow</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">InterruptedException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onDestroy</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="nc">Module</span> <span class="nf">newModule</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Module</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">configure</span><span class="o">(</span><span class="nc">Binder</span> <span class="n">binder</span><span class="o">)</span> <span class="o">{</span>
<span class="n">binder</span><span class="o">.</span><span class="na">bind</span><span class="o">(</span><span class="nc">IAnswerService</span><span class="o">.</span><span class="na">class</span><span class="o">).</span><span class="na">to</span><span class="o">(</span><span class="nc">AnswerService</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">};</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">BgProcessApplication</span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="nc">BgProcessApplication</span><span class="o">)</span><span class="n">get</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="nc">Session</span> <span class="nf">newSession</span><span class="o">(</span><span class="nc">Request</span> <span class="n">request</span><span class="o">,</span> <span class="nc">Response</span> <span class="n">response</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">BgProcessSession</span><span class="o">(</span><span class="n">request</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">launch</span><span class="o">(</span><span class="nc">ITask</span> <span class="n">task</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// we are on WEB thread so services should be normally injected.</span>
<span class="nc">ExecutionBridge</span> <span class="n">bridge</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ExecutionBridge</span><span class="o">();</span>
<span class="c1">// register bridge on session</span>
<span class="n">bridge</span><span class="o">.</span><span class="na">setTaskName</span><span class="o">(</span><span class="s">"Task-"</span> <span class="o">+</span> <span class="nc">BgProcessSession</span><span class="o">.</span><span class="na">getSession</span><span class="o">().</span><span class="na">countTasks</span><span class="o">()</span> <span class="o">+</span> <span class="mi">1</span><span class="o">);</span>
<span class="nc">BgProcessSession</span><span class="o">.</span><span class="na">getSession</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">bridge</span><span class="o">);</span>
<span class="c1">// run the task</span>
<span class="n">executorService</span><span class="o">.</span><span class="na">execute</span><span class="o">(</span> <span class="k">new</span> <span class="nc">TasksRunnable</span><span class="o">(</span><span class="n">task</span><span class="o">,</span> <span class="n">bridge</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span> </code></pre></figure>
<p>and</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">BgProcessSession</span> <span class="kd">extends</span> <span class="nc">WebSession</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">List</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">></span> <span class="n">bridges</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">>();</span>
<span class="kd">public</span> <span class="nf">BgProcessSession</span><span class="o">(</span><span class="nc">Request</span> <span class="n">request</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">request</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">synchronized</span> <span class="kt">void</span> <span class="nf">add</span><span class="o">(</span><span class="nc">ExecutionBridge</span> <span class="n">bridge</span><span class="o">)</span> <span class="o">{</span>
<span class="n">bind</span><span class="o">();</span>
<span class="n">bridges</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">bridge</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">synchronized</span> <span class="kt">void</span> <span class="nf">pruneFinishedTasks</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">ArrayList</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">></span> <span class="n">nonFinishedBridges</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">>();</span>
<span class="k">for</span><span class="o">(</span><span class="nc">ExecutionBridge</span> <span class="nl">bridge:</span> <span class="k">this</span><span class="o">.</span><span class="na">bridges</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(!</span><span class="n">bridge</span><span class="o">.</span><span class="na">isFinished</span><span class="o">())</span> <span class="o">{</span>
<span class="n">nonFinishedBridges</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">bridge</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">this</span><span class="o">.</span><span class="na">bridges</span> <span class="o">=</span> <span class="n">nonFinishedBridges</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">Iterator</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">></span> <span class="nf">getTasksPage</span><span class="o">(</span><span class="kt">int</span> <span class="n">start</span><span class="o">,</span> <span class="kt">int</span> <span class="n">size</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">min</span> <span class="o">=</span> <span class="nc">Math</span><span class="o">.</span><span class="na">min</span><span class="o">(</span><span class="n">size</span><span class="o">,</span> <span class="n">bridges</span><span class="o">.</span><span class="na">size</span><span class="o">());</span>
<span class="k">return</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">>(</span><span class="n">bridges</span><span class="o">.</span><span class="na">subList</span><span class="o">(</span><span class="n">start</span><span class="o">,</span> <span class="n">min</span><span class="o">)).</span><span class="na">iterator</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">long</span> <span class="nf">countTasks</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">bridges</span><span class="o">.</span><span class="na">size</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">BgProcessSession</span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="nc">BgProcessSession</span><span class="o">)</span><span class="n">get</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<h2 id="the-web-layer-to-handlemanage-tasks">The WEB layer to handle/manage tasks.</h2>
<p>The WEB layer is more or less standard Wicket. The more complex class is TasksListPanel which uses an AjaxFallbackDefaultDataTable in order to display running tasks. This panel, contains an
AjaxSelfUpdatingTimerBehavior that takes care of repainting the panel to show tasks progress. There are other user interactions, like creating new tasks and pruning “dead” tasks, but we will
not get into the details.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">TasksListPanel</span> <span class="kd">extends</span> <span class="nc">Panel</span> <span class="o">{</span>
<span class="cm">/**
* @param id
*/</span>
<span class="kd">public</span> <span class="nf">TasksListPanel</span><span class="o">(</span><span class="nc">String</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">id</span><span class="o">);</span>
<span class="n">setOutputMarkupId</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>
<span class="n">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">AjaxLink</span><span class="o"><</span><span class="nc">Void</span><span class="o">>(</span><span class="s">"prune"</span><span class="o">)</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onClick</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">BgProcessSession</span><span class="o">.</span><span class="na">getSession</span><span class="o">().</span><span class="na">pruneFinishedTasks</span><span class="o">();</span>
<span class="n">target</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">TasksListPanel</span><span class="o">.</span><span class="na">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="n">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">AjaxSelfUpdatingTimerBehavior</span><span class="o">(</span> <span class="nc">Duration</span><span class="o">.</span><span class="na">seconds</span><span class="o">(</span><span class="mi">5</span><span class="o">)</span> <span class="o">)</span> <span class="o">);</span>
<span class="nc">ArrayList</span><span class="o"><</span><span class="nc">IColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>></span> <span class="n">columns</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">IColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span><span class="nc">String</span><span class="o">>>();</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Actions"</span><span class="o">),</span> <span class="s">"-"</span><span class="o">)</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">populateItem</span><span class="o">(</span>
<span class="nc">Item</span><span class="o"><</span><span class="nc">ICellPopulator</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">>></span> <span class="n">item</span><span class="o">,</span>
<span class="nc">String</span> <span class="n">componentId</span><span class="o">,</span> <span class="nc">IModel</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">></span> <span class="n">rowModel</span><span class="o">)</span> <span class="o">{</span>
<span class="n">item</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">ActionsPanel</span><span class="o">(</span><span class="n">componentId</span><span class="o">,</span> <span class="n">rowModel</span><span class="o">)</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onAction</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">TasksListPanel</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AjaxSelfUpdatingTimerBehavior</span><span class="o">(</span> <span class="nc">Duration</span><span class="o">.</span><span class="na">seconds</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
<span class="n">target</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">TasksListPanel</span><span class="o">.</span><span class="na">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Name"</span><span class="o">),</span> <span class="s">"taskName"</span><span class="o">)</span> <span class="o">);</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Stoped"</span><span class="o">),</span> <span class="s">"stop"</span><span class="o">)</span> <span class="o">);</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Canceled"</span><span class="o">),</span> <span class="s">"cancel"</span><span class="o">)</span> <span class="o">);</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Message"</span><span class="o">),</span> <span class="s">"message"</span><span class="o">)</span> <span class="o">);</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Progress"</span><span class="o">),</span> <span class="s">"progress"</span><span class="o">)</span> <span class="o">);</span>
<span class="n">columns</span><span class="o">.</span><span class="na">add</span><span class="o">(</span> <span class="k">new</span> <span class="nc">PropertyColumn</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Finished"</span><span class="o">),</span> <span class="s">"finished"</span><span class="o">)</span> <span class="o">);</span>
<span class="nc">AjaxFallbackDefaultDataTable</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">></span> <span class="n">tasks</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AjaxFallbackDefaultDataTable</span><span class="o"><</span><span class="nc">ExecutionBridge</span><span class="o">,</span> <span class="nc">String</span><span class="o">>(</span><span class="s">"tasks"</span><span class="o">,</span> <span class="n">columns</span><span class="o">,</span> <span class="k">new</span> <span class="nc">TaskDataProvider</span><span class="o">(),</span> <span class="mi">10</span><span class="o">);</span>
<span class="n">add</span><span class="o">(</span><span class="n">tasks</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onEvent</span><span class="o">(</span><span class="nc">IEvent</span><span class="o"><?></span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getPayload</span><span class="o">()</span> <span class="k">instanceof</span> <span class="nc">TaskLaunchedEvent</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">TaskLaunchedEvent</span> <span class="n">event2</span> <span class="o">=</span> <span class="o">(</span><span class="nc">TaskLaunchedEvent</span><span class="o">)</span><span class="n">event</span><span class="o">.</span><span class="na">getPayload</span><span class="o">();</span>
<span class="nc">TasksListPanel</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AjaxSelfUpdatingTimerBehavior</span><span class="o">(</span> <span class="nc">Duration</span><span class="o">.</span><span class="na">seconds</span><span class="o">(</span><span class="mi">5</span><span class="o">)));</span>
<span class="n">event2</span><span class="o">.</span><span class="na">getTarget</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="nc">TasksListPanel</span><span class="o">.</span><span class="na">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<h1 id="final-words">Final words</h1>
<p>We hope this example helps you get started in rolling your own solution.</p>
<p>Last but not least, I would like to thanks Martin Grigorov for guiding me in writing this small article, making nice amendments to it and for he’s invaluable work maintaining Apache Wicket.</p>
Build and watch resources with Gulp.js2014-07-01T07:00:00+00:00http://wicketinaction.com/2014/07/build-resources-with-node.js<h1 id="history">History</h1>
<p>Lately I observe that the <a target="_blank" href="http://nodejs.org/">Node.js</a> ecosystem provides much more (and better!) tools
for building web applications. For example there are tools to generate CSS like <a target="_blank" href="http://lesscss.org">Less.js</a>,
<a target="_blank" href="http://sass-lang.com">SASS</a>, <a target="_blank" href="http://learnboost.github.io/stylus/">Stylus</a>, minimizers like
<a target="_blank" href="https://github.com/GoalSmashers/clean-css">Clean CSS</a>, <a target="_blank" href="http://lisperator.net/uglifyjs/">Uglify JS</a>,
linting tools like <a target="_blank" href="http://www.jshint.com/">JSHint</a> and <a target="_blank" href="http://www.jslint.com/">JSLint</a> and many more.
All these are available in the JVM world via <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino">Rhino</a>
but it is kind of slow… Maybe it will get better with <a target="_blank" href="http://en.wikipedia.org/wiki/Nashorn_(JavaScript_engine)">Nashorn</a>
with Java 8 but it will take some time. And someone, like <a target="_blank" href="https://github.com/alexo/wro4j">Wro4j</a>, will have to create
adapters for all these useful tools.</p>
<h1 id="the-solution">The solution</h1>
<p>In my opinion it is much better to utilize the above tools directly with Node.js with its build tools like
<a target="_blank" href="http://gulpjs.com/">Gulp</a>, <a target="_blank" href="http://gruntjs.com/">Grunt</a>, <a target="_blank" href="http://gearjs.org/">Gear</a>, etc.</p>
<p>To accomplish that the most easier way I’ve found is by using <a target="_blank" href="https://github.com/eirslett/frontend-maven-plugin">frontend-maven-plugin</a></p>
<ul>
<li>a Maven plugin that downloads Node.js for you and integrates with Gulp and Grunt.</li>
</ul>
<p><strong>Note</strong>: there is a Gradle plugin in the works by the same author!</p>
<h2 id="demo-application">Demo application</h2>
<p>At <a target="_blank" href="https://github.com/martin-g/blogs/tree/master/wicket-nodejs-build">my GitHub account</a> you may find a demo application that uses Less
to <a target="_blank" href="https://github.com/martin-g/blogs/blob/master/wicket-nodejs-build/gulpfile.js#L21">create</a> the CSS resources
and JSHint and UglifyJS to <a target="_blank" href="https://github.com/martin-g/blogs/blob/master/wicket-nodejs-build/gulpfile.js#L50">lint and minimize</a>
the JavaScript resources.
At <a target="_blank" href="https://github.com/martin-g/blogs/blob/master/wicket-nodejs-build/pom.xml#L116">pom.xml</a> we use <em>frontend-maven-plugin</em> to execute
the default Gulp task that cleans and builds the final CSS and JS resources. The usage is as simple as <em>mvn clean compile</em>. At Maven’s
<em>generate-sources</em> phase frontend-maven-plugin will execute the Gulp’s tasks.</p>
<p><strong>Note</strong>: it will download Node.js and all needed Gulp plugins the first time and save them at <em>./node/</em> and <em>./node_modules/</em> folders. Make sure to ignore them in your SCM tool!</p>
<p>The usage in Wicket components is as you probably do it now:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"> <span class="n">response</span><span class="o">.</span><span class="na">render</span><span class="o">(</span><span class="nc">CssHeaderItem</span><span class="o">.</span><span class="na">forReference</span><span class="o">(</span><span class="k">new</span> <span class="nc">CssResourceReference</span><span class="o">(</span><span class="nc">HomePage</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="s">"res/demo.css"</span><span class="o">)));</span></code></pre></figure>
<p>In <em>src/main/resources/com/mycompany/res</em> folder there is <em>demo.less</em> resource but Gulp’s <em>stylesInPackages</em> task generates <em>demo.css</em>
and puts it in the classpath, so everything Just Works™.</p>
<h1 id="bonus">Bonus</h1>
<p>Most of the Node.js build work flows provide a way to watch the resources for modifications and reload the browser automatically
for you to see the changes. In the demo application we define <a target="_blank" href="https://github.com/martin-g/blogs/blob/master/wicket-nodejs-build/gulpfile.js#L90">watch</a>
task that listens for changes in the Less and JavaScript resources and executes the earlier tasks automatically. Additionally
we make use of <a target="_blank" href="https://github.com/davidB/livereload-jvm">livereload-jvm</a> at the
<a target="_blank" href="https://github.com/martin-g/blogs/blob/master/wicket-nodejs-build/src/test/java/com/mycompany/Start.java#L79">server side</a>
that can notify browser <a target="_blank" href="http://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions-">plugins</a>
which will reload the page.
To try it:</p>
<ol>
<li>execute *gulp watch* on the command line, in the same folder where gulpfile.js is located</li>
<li>install the plugin for your preferred browser</li>
<li>start the application via Start.java (starts embedded Jetty server and LiveReload-JVM server)</li>
<li>open http://localhost:8080 in the browser</li>
<li>open demo.less in your IDE and modify the background color to any valid color. Save the change.</li>
<li>the browser will reload automatically !</li>
</ol>
<h1 id="final-words">Final words</h1>
<p>I have played with all this on Linux. I’m pretty sure it will work flawlessly on Mac too. People say that Node.js support for Windows has become
pretty good these days so it should work there too.</p>
<p>I hope you find all this useful!</p>
<p>Since recently Wicket itself uses the solution described above to execute its
<a target="_blank" href="https://github.com/apache/wicket/tree/master/testing/wicket-js-tests">JavaScript unit tests</a>.</p>
<p>In my daily job we switched from Node.js+less.js based build to <a href="https://github.com/SomMeri/less4j">Less4j</a> because it is much faster and we have a lot of Less resources!</p>
Groovy DSL for Apache Wicket2014-05-26T12:08:52+00:00http://wicketinaction.com/2014/05/groovy-dsl-for-wicket<p>Eugene Kamenev has released his take on <a href="https://github.com/eugene-kamenev/wicket-groovy-DSL">making Wicket groovy</a>:</p>
<blockquote>
<p>Apache Wicket is great, and Groovy is also great. This project tries
to combine the power of both. However, sometimes Apache Wicket code
become damn verbose. But with some little, yet powerful Groovy DSL
written, we can extend Wicket to simplify common tasks, and to delete
over 30-40% of verbose code.</p>
</blockquote>
<p>A short example of the usual Wicket and Java code:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="o">...</span>
<span class="nc">Form</span> <span class="n">form</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Form</span><span class="o">(</span><span class="s">"wicketForm"</span><span class="o">,</span> <span class="k">new</span> <span class="nc">CompoundPropertyModel</span><span class="o">(</span><span class="k">this</span><span class="o">))</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onSubmit</span><span class="o">(){</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="nc">MyPage</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">input1</span> <span class="o">+</span> <span class="nc">MyPage</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">input2</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isVisible</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// just for example :)</span>
<span class="o">!</span><span class="nc">MyPage</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">input1</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="nc">MyPage</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">input2</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="n">form</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">TextField</span><span class="o">(</span><span class="s">"input1"</span><span class="o">));</span>
<span class="n">form</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">TextField</span><span class="o">(</span><span class="s">"input2"</span><span class="o">));</span>
<span class="n">add</span><span class="o">(</span><span class="n">form</span><span class="o">);</span></code></pre></figure>
<p>These lines of code can be shortened by using Eugene’s Groovy DSL:</p>
<figure class="highlight"><pre><code class="language-groovy" data-lang="groovy"><span class="o">...</span>
<span class="n">use</span><span class="o">(</span><span class="n">WicketDSL</span><span class="o">,</span> <span class="n">WicketFormDSL</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">def</span> <span class="nf">form</span><span class="o">(</span><span class="s1">'wicketForm'</span><span class="o">,</span>
<span class="k">new</span> <span class="nf">CompoundPropertyModel</span><span class="o">(</span><span class="k">this</span><span class="o">),</span>
<span class="o">[</span>
<span class="nl">submit:</span> <span class="o">{</span> <span class="n">println</span> <span class="k">this</span><span class="o">.</span><span class="na">input1</span> <span class="o">+</span> <span class="k">this</span><span class="o">.</span><span class="na">input2</span> <span class="o">},</span>
<span class="nl">visible:</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">input1</span> <span class="o">!=</span> <span class="k">this</span><span class="o">.</span><span class="na">input2</span> <span class="o">}</span>
<span class="o">]</span>
<span class="o">)</span>
<span class="n">form</span><span class="o">.</span><span class="na">field</span><span class="o">(</span><span class="s1">'input1'</span><span class="o">)</span>
<span class="n">form</span><span class="o">.</span><span class="na">field</span><span class="o">(</span><span class="s1">'input2'</span><span class="o">)</span>
<span class="k">this</span> <span class="o"><<</span> <span class="n">form</span>
<span class="o">}</span></code></pre></figure>
<p>You can see some example code in his readme file, and the project comes
with some examples.</p>
<p><a href="https://github.com/eugene-kamenev/wicket-groovy-DSL">Go check it out</a>!</p>
Wicket in Action Makeover2014-03-30T20:40:00+00:00http://wicketinaction.com/2014/03/wicket-in-action-makeover<p>A couple of days ago the Wicket in Action website was unavailable
without any notice. I’d like to explain why that was necessary and what
I have done to prevent such outages in the future. This outage also
presented an opportunity to work on the design of the Wicket in Action
website.</p>
<h3 id="wicket-in-action-hosted-by-wordpress">Wicket in Action: hosted by Wordpress</h3>
<p>Wicket in Action was powered by a self-hosted <a href="http://wordpress.org">Wordpress</a>
installation since the beginning of this blog in 2008.</p>
<p>So why not use Wicket to create a blogging engine? I always figured
that it was more important to write content, not the backend software.
Hosting a Wordpress blog is almost gratis, where Java hosting brought
considerable costs with it. The choice for Wordpress was quite simple
at that time.</p>
<p>Wordpress has been a great blogging platform that got better with each
release. Most notably the automatic updates were a boon and the admin
UI was evolving nicely. With a press of a button I could upgrade my
blogs to a new major release of Wordpress. And in the latest releases
they even upgraded Wordpress for you automatically to patch releases.</p>
<h3 id="saying-goodbye-to-wordpress">Saying goodbye to Wordpress</h3>
<p>Unfortunately Wordpress has been the target of malicious software,
hackers and automated scripts. When you have to fully nuke and
reinstall because a new exploit has crippled your site it is time part
ways.</p>
<p>This caused quite a bit of a maintenance hassle, and a nagging feeling
that at any given moment the website could be used to distribute
malware or harvest information of blog visitors. A couple of months ago
the website suddenly was blocked by google for distributing malware,
causing visitors to see a big warning screen that the website could
harm their computers.</p>
<p>The final straw that pushed me to turn off Wordpress was that I noticed
in my access logs some weird pages that really had nothing to do with
Wicket:</p>
<ul>
<li>/2014/03/crack-sam-broadcaster-pro/</li>
<li>/2014/03/crack-wondershare-pdf-editor-or-serial-number/</li>
</ul>
<p>These pages did not turn up in the Wordpress administration UI so it
was difficult to spot them.</p>
<p>I immediately shutdown this website and my <a href="http://martijndashorst.com">own personal blog</a>. I
have put a notice in place but somehow my hosting provider shows a ‘not
registered’ page instead.</p>
<p>Goodbye Wordpress, I will not miss you.</p>
<h3 id="say-hello-to-jekyll">Say hello to jekyll</h3>
<p>The first thing I wanted to achieve was being free of active executing
code on my hosting server. This led me to turning this website into
serving only static markup.</p>
<h4 id="faster-more-secure-better-scalability">Faster, more secure, better scalability</h4>
<p>A static web site is safer than running Wordpress. There’s nothing to
execute on the server! All the pages are pre-rendered and ready to be
sent to browsers without any code executing. There are no accounts to
break: all editing is done offline.</p>
<p>A static website is also much faster to serve by web servers. The web
server only has to copy a file from disk to a network socket. There is
no code execution inbetween: all pages are pre-rendered and nothing
needs to be updated dynamically. This makes it easy to cache each page:
in a file cache or in the HTTP server.</p>
<p>Having only static markup files makes it rather easy for a HTTP server
to serve thousands of requests. Here’s a list Wordpress has to perform
to serve a blog post:</p>
<ul>
<li>start a PHP process</li>
<li>establish a connection to the database</li>
<li>query the database to retrieve the post</li>
<li>query the datebase to retrieve the author</li>
<li>query the database to retrieve the comments</li>
<li>query the database to retrieve active plugins</li>
<li>render the markup whilst executing any number of plugins and themes</li>
<li>close the connection to the database</li>
</ul>
<p>I am sure I have missed quite a few steps in this list. While only a
single step, there’s no saying what a given plugin and theme in
Wordpress can do.</p>
<p>In the new, static content situation the HTTP server has the following
tasks to perform:</p>
<ul>
<li>read file from disk</li>
<li>send file to network</li>
</ul>
<p>This is more concise and a lot easier to execute for a HTTP server.</p>
<p>One of the telltale indicators that a website is running a CMS
(Wordpress) is when a highly trafficed site (for example Reddit,
HackerNews, Slashdot, Daringfireball or Twitter) features the site on
the front page, the server will crumble under the amount of incoming
requests. Typically the first thing to give up is the database: with a
couple of hundred concurrent requests it is bound to consume too much
memory and the server will typically give up.</p>
<p>Wicket in action has not received that much traffic but you never know
who will link to your blog post. Give a positive review of JEE 7 or
Java 8 and suddenly you have thousands of Java developers looking at
your post.</p>
<p>While not strictly necessary from a performance standpoint, moving to a
static website makes sense.</p>
<h4 id="jekyll-as-the-powering-engine">Jekyll as the powering engine</h4>
<p>There were a couple of factors to choose <a href="http://jekyllrb.com">Jekyll</a> as the platform
for Wicket in Action and my <a href="http://martijndashorst.com">other website</a>:</p>
<ol>
<li>well known technology</li>
<li>servable from github.com</li>
<li>automatic migration from Wordpress</li>
</ol>
<p>The <a href="http://wicket.apache.org">Apache Wicket</a> project uses Jekyll to generate <a href="https://svn.apache.org/repos/asf/wicket/common/site/trunk/">the
website</a>. As such the Wicket committers have ample experience with
Jekyll. The tooling is well understood and there’s ample documentation
available.</p>
<p>Secondly github.com can serve Jekyll generated websites directly. You
create a project and push your Jekyll content to github. A few moments
later Github publishes the content. Github uses a <abbr title="Content Delivery Network">CDN</abbr> for the static websites. This gives our
blog a global presence and speedy delivery.</p>
<p>I did not want to loose 6 years of content, so being able to import the
Wordpress database and have all content available was a big plus.</p>
<p>I was able to replicate the URL schema of the Wordpress installation,
so all links pointing to articles will still work (no broken web)!</p>
<h4 id="a-new-design">A new design</h4>
<p>At first the Wicket in Action website had a nice design that followed
the book closely, but was tailored for a blog:</p>
<p><img alt="Screenshot of original Design of Wicket in Action" src="/img/2014-03-30-wia-orig-design.png" width="512" /></p>
<p>After a couple of Wordpress upgrades my custom theme did not work
anymore. So I had to either reimplement my custom theme, or just pick a
default theme. I chose the latter and Wicket in Action has used a
<a href="https://web.archive.org/web/20130704083056/http://wicketinaction.com/">plain design</a> for some time. I was never happy with that.</p>
<p>The migration to Jekyll also brought a really hidious default design,
so I had to do some design work.</p>
<p>The goals I set myself were:</p>
<ul>
<li>stay close to the Wicket in Action book (use the smoking person, use
the book color)</li>
<li>few menu items visible</li>
<li>clear, easy to read content</li>
<li>enough room for content and code examples</li>
</ul>
<p>I wanted a content area that was wider than the original design to
accomodate code better. I went into Keynote (my ‘design’ application)
for the initial sketch and after letting it sit for a day started to
implement it in the Jekyll site.</p>
<p>The result is what you see before you. It is not too snazzy, nor too
fashionable.</p>
<p>A couple of things I have yet to address or implement:</p>
<ul>
<li>author names instead of accounts</li>
<li>metadata clean up</li>
<li>code blocks design: better font and font-size</li>
<li>typography (font sizes of headings)</li>
<li>responsive UI (legibility on small devices)</li>
<li>search functionality</li>
<li>tags and categories (though who uses those anyway?)</li>
<li>reimplement comments</li>
<li>migrate all content from HTML to markdown</li>
</ul>
<p>This new setup gives Wicket in Action (and my other blog) a good solid
foundation for the coming years. I hope you like the new design and
that new content keeps on flowing!</p>
Header contributions positioning2014-03-14T13:47:14+00:00http://wicketinaction.com/2014/03/header-contributions-positioning<p>Wicket 6.0.0 came with some nice <a href="http://wicketinaction.com/2012/07/wicket-6-resource-management/" title="Wicket 6 resource management" target="_blank">improvements</a>
in the header contribution management.</p>
<p>With these improvements it is possible to put a specific header
contribution at the top of all others by using <em title="org.apache.wicket.markup.head.PriorityHeaderItem">PriorityHeaderItem</em>,
or to group several header contributions in a specific spot
in the page body by using <em title="org.apache.wicket.markup.head.filter.FilteredHeaderItem">FilteredHeaderItem</em>,
but still it was quite hard to something simple like
making sure that <meta charset=”utf-8”/> is always the very first
item in the page <head>.</p>
<p><strong><wicket:header-items/></strong></p>
<p>With <a href="https://issues.apache.org/jira/browse/WICKET-5531" target="_blank">WICKET-5531</a> (since Wicket 6.15.0) we added one more
facility that should make header contributions management even more
flexible.</p>
<p>By using markup like the one below in YourPage.html</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><head></span>
<span class="nt"><meta</span> <span class="na">chartset=</span><span class="s">"UTF-8"</span><span class="nt">/></span>
<span class="nt"><wicket:header-items/></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"my-monkey-patch-of-wicket-ajax.js"</span><span class="nt">></script></span>
<span class="nt"></head></span></code></pre></figure>
<p>all header contributions done by using <em title="org.apache.wicket.markup.head.IHeaderResponse">IHeaderResponse</em>
in your Java code or the special <a href="https://cwiki.apache.org/confluence/display/WICKET/Wicket's+XHTML+ tags#Wicket'sXHTMLtags-Elementwicket:head" target="_blank">wicket:head</a> tag will be put between the
<meta> and <script> elements, i.e. in the place of
<wicket:header-items/>.</p>
<p>This way you can make sure that some header item is always before or
after the header items managed by Wicket.</p>
<p><wicket:header-items/> can be used only in the page’s
<head> element and there could be at most one instance of it.</p>
Wicket at ApacheCon 2014: Croquet2014-03-09T13:06:09+00:00http://wicketinaction.com/2014/03/wicket-at-apachecon-2014-croquet<p>Due to an unfortunate scheduling conflict I'm unable to attend ApacheCon 2014 in North America, but<br />
it appears that ApacheCon isn't bereft of a Wicket attendance: William Speirs is <a href="http://apacheconnorthamerica2014.sched.org/event/d47e5ddfe3c13a62a37d61c69931f452#.UxxXn9zGm2w">presenting his<br />
Wicket, Jetty, Hibernate and Guice framework called "Croquet"</a>.</p>
<blockquote><p>Croquet is a framework that combines Apache Wicket, Jetty, Hibernate, and Google’s Guice into a high-performance ops-friends web framework. Croquet is to Wicket as DropWizard is to Jersey.</p>
<p>When creating a website with Wicket, Jetty is often used for serving HTTP, Hibernate for interacting with databases, and Google’s Guice for dependency injection. Getting all of these components to run together properly is non-trivial and often repeated by each project. Croquet solves this problem by doing all of the hard work involved in tying these projects together, making it easier for developers to get a Wicket site up and running.</p>
<p>A brief introduction to each component, how the various pieces are tied together, and a walk through of creating a new Wicket site in Croquet will be covered in this presentation. Finally, the code for Croquet will be open sourced at the end of the presentation.</p></blockquote>
<p>I'd love to be there...</p>
The State of Wicket 20142014-01-31T12:09:58+00:00http://wicketinaction.com/2014/01/the-state-of-wicket-2014<p>In this short presentation I delivered at the <a href="http://www.meetup.com/DEVdev-powered-by-Topicus/">first DEVdev meetup</a> I talk about the ThoughtWorks Technology Radar January 2014 <a href="http://www.thoughtworks.com/radar/#/languages-and-frameworks/683">assessment of JSF</a>, 10 years of Wicket history, the state of our community, the current releases and vision and roadmap for Wicket 6, 7 and 8.</p>
<p>The views, opinions and examples are all mine. What is presented here is not necessarily the opinion of the Wicket community, or the way we will do things in Wicket 7 or 8.</p>
<p><iframe src="http://www.slideshare.net/slideshow/embed_code/30661439" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen=""></iframe></p>
<div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/dashorst/de-vdev-meetup-1" title="The State of Wicket" target="_blank">The State of Wicket</a> </strong> from <strong><a href="http://www.slideshare.net/dashorst" target="_blank">Martijn Dashorst</a></strong></div>
<p>Enjoy this presentation!</p>
Capture JavaScript errors and log them at the server2014-01-30T12:08:52+00:00http://wicketinaction.com/2014/01/capture-javascript-errors-and-log-them-at-the-server<p><a href="http://www.thoughtworks.com/radar/#/techniques/545" title="ThoughtWorks technology radar">ThoughtWorks technology radar</a> recommends capturing client-side
JavaScript errors and logging them at the server. This way you can see
whether your application experience problems on different browsers.</p>
<h2 id="a-solution-for-apache-wicket">A solution for Apache Wicket</h2>
<p>Michael Haitz has implemented a <a href="https://github.com/l0rdn1kk0n/wicket-clientside-logging" title="Wicket client side logging">small
library</a>
that integrates with Wicket’s JavaScript APIs and captures and sends
all client-side logs to the server.</p>
<p>Check its documentation to see how to setup and use it!</p>
Surgical Ajax updates with Ractive.js2013-08-13T12:43:59+00:00http://wicketinaction.com/2013/08/surgical-ajax-updates-with-ractive-js<h3 id="replace-all-with-outerhtml">Replace all with outerHTML</h3>
<p>At the moment (Apache Wicket version 6.10.0) when a Component has to be
updated in Ajax response Wicket will replace the whole HTML element
with all its attributes and sub-elements included, i.e. the
<em>outerHTML</em> of the element is replaced.</p>
<p>Wicket has always tried to do this in the most efficient way for the
different browsers. Since version 6.0.0 Wicket uses jQuery to do this,
so jQuery cares about the browser inconsistencies.</p>
<p>With or without using jQuery for DOM manipulations if the change in the
DOM is as minimal as a new value for some attribute of the HTML element
then Wicket will replace the whole element (including its sub-elements)
to be able to update the attribute. Depending on the size of the markup
this may be a noticeable or not.</p>
<h3 id="replace-only-what-has-changed-with-ractivejs">Replace only what has changed with Ractive.js</h3>
<p>In this article I want to introduce you <a href="http://www.ractivejs.org/">Ractive.js</a> - a JavaScript library
that among other things is able to make surgical updates in the DOM
tree.</p>
<p>Ractive.js uses templating based on <a href="http://mustache.github.io/">Mustache</a>. For example your markup
template can look like:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><p</span> <span class="na">id=</span><span class="s">"myTmpl"</span> <span class="na">style=</span><span class="s">"color: "</span><span class="nt">></span>Hello ! You have
<span class="nt"><strong></span> new messages<span class="nt"></strong></span>.
<span class="nt"></p></span></code></pre></figure>
<p>To populate the data in the mustaches you need to initialize a Ractive instance with something like this:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">ractive</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Ractive</span><span class="p">({</span>
<span class="na">el</span><span class="p">:</span> <span class="dl">"</span><span class="s2">#target</span><span class="dl">"</span><span class="p">,</span>
<span class="na">template</span><span class="p">:</span> <span class="dl">"</span><span class="s2">myTmpl</span><span class="dl">"</span><span class="p">,</span>
<span class="na">data</span><span class="p">:</span> <span class="p">{</span>
<span class="na">user</span><span class="p">:</span> <span class="p">{</span>
<span class="na">color</span><span class="p">:</span> <span class="dl">"</span><span class="s2">green</span><span class="dl">"</span><span class="p">,</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Dave</span><span class="dl">'</span><span class="p">,</span>
<span class="na">messages</span><span class="p">:</span> <span class="p">{</span> <span class="na">total</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span> <span class="na">unread</span><span class="p">:</span> <span class="mi">4</span> <span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span></code></pre></figure>
<p>This will read the template from the element with id “myTmpl” and put
the final result in an element with id “target”.</p>
<p>Later if you need to update some variable (mustache) you should do:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">ractive</span><span class="p">.</span><span class="kd">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">user.messages.unread</span><span class="dl">'</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span></code></pre></figure>
<p>This will update just the text node inside the <em>strong</em> HTML
element responsible to visualize the number of the unread messages.</p>
<p>Even if we do something like:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">ractive</span><span class="p">.</span><span class="kd">set</span><span class="p">(</span><span class="dl">'</span><span class="s1">user</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">color</span><span class="p">:</span> <span class="dl">"</span><span class="s2">green</span><span class="dl">"</span><span class="p">,</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Dave</span><span class="dl">"</span><span class="p">,</span>
<span class="na">messages</span><span class="p">:</span> <span class="p">{</span>
<span class="na">total</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span>
<span class="na">unread</span><span class="p">:</span> <span class="mi">2</span>
<span class="p">}</span>
<span class="p">});</span></code></pre></figure>
<p>Note that only the <em>unread</em> has a new value, Ractive.js will figure
that out and will do the right thing - will update the same text node
only, as above, not the complete template.</p>
<h3 id="the-integration">The integration</h3>
<p>At <a href="https://github.com/martin-g/wicket-ractive/">Wicket-Ractive</a>
you may find an integration between Wicket and Ractive that takes
advantage of Ractive’s DOM update possibilities.</p>
<p>By adding <code class="language-plaintext highlighter-rouge">RactiveBehavior</code> to a component/panel Wicket will use
its model object to create an instance of Ractive and populate its
mustaches with initial values from the object’s properties. Later when
updating this component you may use
<code class="language-plaintext highlighter-rouge">Ractive#ractive(AjaxRequestTarget, Component)</code> helper to tell
Ractive to do its magics and update only the bean properties which have
new values.</p>
<p><code class="language-plaintext highlighter-rouge">Ractive#ractive(AjaxRequestTarget, Component)</code> helper can be used when
you know that the changes in the model object are small enough. In case
there are bigger changes and replacing the <em>outerHTML</em> may be
more efficient you can still use
<code class="language-plaintext highlighter-rouge">AjaxRequestTarget#add(Component)</code> as you do now.</p>
<p>There is a demo application in the <code class="language-plaintext highlighter-rouge">src/test/java</code> folder of this
project. Try it.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Ractive.js is used intensively at <a href="http://theguardian.com/">The
Guardian</a> but it is still a new project that has to prove itself
among other good JavaScript libraries.</p>
<p>The usage of the mustaches in the markup template is against Wicket’s
philosophy of developing with <em>plain Java and plain HTML</em>, so
this approach may be a step in the wrong direction for some of the
Wicket’s users.</p>
Server and client side validation2013-04-24T16:04:33+00:00http://wicketinaction.com/2013/04/server-and-client-side-validation<p>Maybe not so well known feature in Wicket is that the form component <em title="org.apache.wicket.validation.IValidator">validator</em>s are actually <em title="org.apache.wicket.behavior.Behavior">Behavior</em>s, or if they are not then a special <em title="org.apache.wicket.validation.ValidatorAdapter">adapter</em> is used, so at the end they are stored as a behavior in the component.</p>
<p>Being a behavior gives the validator the chance to be notified when the respective form component is being rendered. And this makes it possible to make a validator that can validate at the server side and to contribute whatever is needed for some client side (JavaScript) library to make the same validation before the request is even made to the server.</p>
<p>At <a href="https://github.com/martin-g/blogs/tree/master/wicket-parsley-validation">this repo</a> you may find an integration with <a href="http://parsleyjs.org/">Parsley.js</a>.</p>
<p>The implementation is in <a href="https://github.com/martin-g/blogs/blob/master/wicket-parsley-validation/src/main/java/com/mycompany/parsley/ParsleyValidationBehavior.java">ParsleyValidationBehavior</a>.<br />
This is the base class that does most generic configuration, i.e. set the expected by Parsley <em>data-xyz</em> attributes in the form component markup. Additionally it uses a delegate <em title="org.apache.wicket.validation.IValidator">IValidator</em> that does the server side validation.</p>
<p>The usage is as any other validator in Wicket:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">TextField</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">fullName</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TextField</span><span class="o"><</span><span class="nc">String</span><span class="o">>(</span><span class="s">"fullname"</span><span class="o">,</span> <span class="n">someModel</span><span class="o">);</span>
<span class="n">fullName</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">ParsleyValidationBehavior</span><span class="o"><</span><span class="nc">String</span><span class="o">>(</span><span class="nc">EmailValidator</span><span class="o">.</span><span class="na">getInstance</span><span class="o">()).</span><span class="na">type</span><span class="o">(</span><span class="s">"email"</span><span class="o">).</span><span class="na">require</span><span class="o">(</span><span class="kc">true</span><span class="o">));</span></code></pre></figure>
<p>The code above is a bit mouthfull so we can create a specialization class:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ParsleyEmailValidator</span> <span class="kd">extends</span> <span class="nc">ParsleyValidationBehavior</span><span class="o"><</span><span class="nc">String</span><span class="o">></span>
<span class="o">{</span>
<span class="kd">public</span> <span class="nf">ParsleyEmailValidator</span><span class="o">()</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="nc">EmailAddressValidator</span><span class="o">.</span><span class="na">getInstance</span><span class="o">());</span>
<span class="n">require</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>
<span class="n">type</span><span class="o">(</span><span class="s">"email"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>and use it like:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">TextField</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">fullName</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TextField</span><span class="o"><</span><span class="nc">String</span><span class="o">>(</span><span class="s">"fullname"</span><span class="o">,</span> <span class="n">someModel</span><span class="o">);</span>
<span class="n">fullName</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">ParsleyEmailValidator</span><span class="o">());</span></code></pre></figure>
<p>The project just demostrates how to approach the problem. It does not provide full integration with Parsley.js.<br />
If there is interest the project can be moved to <a href="https://github.com/wicketstuff/core">WicketStuff</a> and extended more with <strong>your</strong> help!</p>
<p><strong>Update</strong>: <a href="https://twitter.com/Cedric_Gatay">Cedric Gatay</a> extended the demo application with Bean Validation (JSR 303) support: <a href="https://github.com/code-troopers/wicket-jsr303-parsley">Wicket + JSR_303 + Parsley</a>. Good work, Cedric!</p>
Replace components with animation2013-02-21T16:00:49+00:00http://wicketinaction.com/2013/02/replace-components-with-animation<p>In this article I'm going to show you how to replace a component in Ajax response using animation effects like sliding, fading, etc.</p>
<h1>The problem</h1>
<p>To update a <em title="org.apache.wicket.Component">Component</em> in Ajax request Wicket just replaces its old HTML DOM element with a new one created by the HTML in the response.<br />
To update it with an animation you need to do:</p>
<ol>
<li>hide the old HTML element</li>
<li>replace the component, but do not show it</li>
<li>show the new HTML element</li>
</ol>
<p>Attempt 1 (not working):</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">onClick</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">)</span> <span class="o">{</span>
<span class="n">target</span><span class="o">.</span><span class="na">prependJavaScript</span><span class="o">(</span><span class="s">"jQuery('#"</span><span class="o">+</span><span class="n">component</span><span class="o">.</span><span class="na">getMarkupId</span><span class="o">()+</span><span class="s">"').slideUp(1000);"</span><span class="o">);</span>
<span class="n">target</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">component</span><span class="o">);</span>
<span class="n">target</span><span class="o">.</span><span class="na">appendJavaScript</span><span class="o">(</span><span class="s">"jQuery('#"</span><span class="o">+</span><span class="n">component</span><span class="o">.</span><span class="na">getMarkupId</span><span class="o">()+</span><span class="s">"').slideDown(1000);"</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>The first problem is that animations in JavaScript are implemented with <em>window.setTimeout</em> or with <em>requestAnimationFrame</em> and this makes them asynchronous-ish. That is Wicket will execute the prepend script to hide the element but wont wait for 1000ms before replacing it, so you wont see the <em>slideUp</em> effect.</p>
<p>The second problem is that <em>target.add(component);</em> will show the new HTML element right away and thus <em>slideDown</em> has nothing to do.</p>
<h1>The solution</h1>
<p>wicket-ajax-jquery.js supports special syntax for the prepended/appended JavaScripts: <em>functionName|some-real-js-code</em>. Such JavaScript is transformed to: <em>function(functionName) {some-real-js-code}</em> where <em>functionName</em> is a function which should be executed in your JavaScript code to allow the next operation to be executed.</p>
<p>Attempt 2 (working):</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">onClick</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">)</span> <span class="o">{</span>
<span class="n">component</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">DisplayNoneBehavior</span><span class="o">());</span>
<span class="n">target</span><span class="o">.</span><span class="na">prependJavaScript</span><span class="o">(</span><span class="s">"notify|jQuery('#"</span> <span class="o">+</span> <span class="n">component</span><span class="o">.</span><span class="na">getMarkupId</span><span class="o">()</span> <span class="o">+</span> <span class="s">"').slideUp(1000, notify);"</span><span class="o">);</span>
<span class="n">target</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">component</span><span class="o">);</span>
<span class="n">target</span><span class="o">.</span><span class="na">appendJavaScript</span><span class="o">(</span><span class="s">"jQuery('#"</span><span class="o">+</span><span class="n">component</span><span class="o">.</span><span class="na">getMarkupId</span><span class="o">()+</span><span class="s">"').slideDown(1000);"</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">DisplayNoneBehavior</span> <span class="kd">extends</span> <span class="nc">AttributeAppender</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nf">DisplayNoneBehavior</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="s">"style"</span><span class="o">,</span> <span class="nc">Model</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"display: none"</span><span class="o">));</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isTemporary</span><span class="o">(</span><span class="nc">Component</span> <span class="n">component</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>Problem 1) is solved by using <em>notify</em> as a callback function which should be executed when the sliding up is finished.<br />
Problem 2) is solved by using <em>DisplayNoneBehavior</em> that add 'display: none' to the markup of this component just for this rendering (see Behavior#isTemporary(Component)).</p>
<p>This code can be extracted in a helper class and reused. Simple implementation of such helper class can be found in the <a href="https://github.com/martin-g/blogs/tree/master/wicket6-replace-with-effect">demo application</a>.</p>
<p>This functionality is broken in Wicket 6.4.0, 6.5.0 and 6.6.0. It is fixed with <a href="https://issues.apache.org/jira/browse/WICKET-5039">WICKET-5039</a>.</p>
WicketStuff download stats for Nov 20122012-12-09T19:25:16+00:00http://wicketinaction.com/2012/12/wicketstuff-download-stats-for-nov-2012<p>Some download statistics for Wicket Stuff projects for November 2012:</p>
<ol>
<li>inmethod-grid (2468)</li>
<li>googlecharts (666)</li>
<li>tinymce (660)</li>
<li>wicketstuff-annotation (648)</li>
<li>inmethod-grid-examples (589)</li>
<li>input-events (572)</li>
<li>objectautocomplete (537)</li>
<li>gmap2-examples (505)</li>
<li>input-events-examples (480)</li>
<li>googlecharts-examples (475)</li>
</ol>
<p>As you can see, the examples projects are rather popular-taking 4 top 10 slots.</p>
JavaScript based functional testing2012-11-26T15:38:08+00:00http://wicketinaction.com/2012/11/javascript-based-functional-testing<h2>The problem</h2>
<p>Every software developer very well knows that producing new code leads to producing new bugs (problems in the software).<br />
The good software developers know that writing tests for their code doesn"t solve completely the problem but at least prevents regressions. Unfortunately developers often do not have time to write the tests, or are too lazy to do it, or just don"t like the way they do it and try to postpone it.</p>
<p>In this article I"ll describe a prototype of a mini framework that can be used to create functional tests for web applications that run blazing fast, are easy to debug and more imporatantly are very close to the real way a web application is being used.</p>
<p><strong>Note</strong>: this article is not Wicket specific. The described solution can be used for any kind of web application.</p>
<h2>The solution</h2>
<p>A well known library for writing functional tests for web applications is <a href="https://code.google.com/p/selenium/">WebDriver/Selenium2</a>.<br />
My problem with it is that it is:</p>
<ul>
<li>slow - starting the browser instance takes time, issuing commands to it takes time, HtmlUnitDriver with JavaScript enabled is <strong>very</strong> slow...</li>
<li>unreliable - every Driver implementation behaves differently. For me only FirefoxDriver works well</li>
<li>well, let"s not say more bad words for WebDriver. Some of its developers may have the same opinion for Apache Wicket :-)</li>
</ul>
<p>In this article I"m going to describe how to use <a href="http://qunitjs.com/">QUnit</a> to run functional tests for <a href="http://www.wicket-library.com/wicket-examples-6.0.x/">Wicket Examples</a>.</p>
<p>Apache Wicket project already uses QUnit for its <a href="https://github.com/apache/wicket/tree/master/wicket-core/src/test/js">unit tests</a> since version 6.0.0 and so far they seems to serve us very well. </p>
<p>The main idea is that the tests run the application in an iframe, i.e. each test tells the iframe what is its initial source url, then the test can enter data in input fields, click links and buttons and finally assert the result of the previous actions. </p>
<h3>CORS</h3>
<p>The first problem is <a href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross origin requests</a> - the tests need to be in the same domain as the application to be able to manipulate it.<br />
There are (at least) two possible solutions:</p>
<ul>
<li>run the application with the proper Access-Control-Allow-Origin header value</li>
<li>create a new application that merges the tests in the original application</li>
</ul>
<p>The first approach is too obtrusive. It makes the application aware of its clients (the tests).<br />
I prefer the second solution - by using <a href="http://maven.apache.org/plugins/maven-war-plugin/overlays.html">Maven War Overlays</a> we can create a Maven project that contains the tests and injects the original application in itself. This way the tests are available in my-tests folder in the web context for example.</p>
<h3>QUnit Setup</h3>
<p>To create QUnit tests you need to start with their HTML template. For our functional tests we need to put our additional iframe in its body. It is good to make the iframe big enough to be able to see what happens when you debug a test. In non-debug mode everything happens so fast that you cannot see anything ;-)</p>
<p>Here is the HTML template:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html">
<span class="cp"><!DOCTYPE html></span>
<span class="nt"><html></span>
<span class="nt"><head></span>
<span class="nt"><title></span>Wicket Examples Functional tests<span class="nt"></title></span>
<span class="nt"><meta</span> <span class="na">http-equiv=</span><span class="s">"content-type"</span> <span class="na">content=</span><span class="s">"text/html; charset=UTF-8"</span><span class="nt">></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"lib/qunit-1.10.0.css"</span> <span class="na">type=</span><span class="s">"text/css"</span> <span class="na">media=</span><span class="s">"screen"</span> <span class="nt">/></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"lib/jquery.min.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">></span>
<span class="nx">$q</span> <span class="o">=</span> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">(</span><span class="kc">true</span><span class="p">),</span>
<span class="nx">$</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">jQuery</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nt"></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"lib/qunit-1.10.0.js"</span><span class="nt">></script></span>
<span class="c"><!-- common helpers --></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"Helpers.js"</span><span class="nt">></script></span>
<span class="c"><!-- the modules under test --></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"tests/helloworld.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"tests/echo.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"tests/forminput.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"tests/ajax/form.js"</span><span class="nt">></script></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><h1</span> <span class="na">id=</span><span class="s">"qunit-header"</span><span class="nt">></span>Wicket Examples JS tests<span class="nt"></h1></span>
<span class="nt"><h2</span> <span class="na">id=</span><span class="s">"qunit-banner"</span><span class="nt">></h2></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"qunit-testrunner-toolbar"</span><span class="nt">></div></span>
<span class="nt"><h2</span> <span class="na">id=</span><span class="s">"qunit-userAgent"</span><span class="nt">></h2></span>
<span class="c"><!-- Show the iframe to see how the tests run --></span>
<span class="nt"><iframe</span> <span class="na">id=</span><span class="s">"applicationFrame"</span> <span class="na">width=</span><span class="s">"100%"</span> <span class="na">height=</span><span class="s">"500px"</span> <span class="na">src=</span><span class="s">"../"</span><span class="nt">></iframe></span>
<span class="nt"><ol</span> <span class="na">id=</span><span class="s">"qunit-tests"</span><span class="nt">></ol></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"qunit-fixture"</span><span class="nt">></span>
<span class="nt"></div></span>
<span class="nt"></body></span>
<span class="nt"></html></span></code></pre></figure>
<p>The interesting things here are: </p>
<ul>
<li>we preserve current page"s (the tests" page) jQuery in $q variable and unset the original jQuery and $ variables just to avoid name clashes later in our tests.</li>
<li>we add Helpers.js which is a set of helper functions which are used by all our tests</li>
<li>we add <script> for all actual tests</li>
<li>and finally we add the iframe that will run the application</li>
</ul>
<p>And here is how the tests themselves look like:</p>
<p>helloworld.js:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">$q</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">use strict</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">module</span><span class="p">(</span><span class="dl">"</span><span class="s2">Hello World</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">asyncTest</span><span class="p">(</span><span class="dl">"</span><span class="s2">hello world</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
<span class="nx">onPageLoad</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$message</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">#message</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">equal</span><span class="p">(</span><span class="nx">$message</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="dl">"</span><span class="s2">The greeting is there</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">equal</span><span class="p">(</span><span class="nx">$message</span><span class="p">.</span><span class="nx">text</span><span class="p">(),</span> <span class="dl">"</span><span class="s2">Hello World!</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">The greeting is correct</span><span class="dl">"</span><span class="p">)</span>
<span class="nx">start</span><span class="p">();</span>
<span class="p">});</span>
<span class="nx">getIframe</span><span class="p">().</span><span class="nx">attr</span><span class="p">(</span><span class="dl">"</span><span class="s2">src</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">/helloworld</span><span class="dl">"</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">});</span></code></pre></figure>
<p>The idea is that we use QUnit <a href="http://api.qunitjs.com/asyncTest/">asyncronous tests</a> because often our tests will need to go over several pages in the application and we should not allow QUnit to go to the next test before the current test is finished.</p>
<p>So what does this test do ?<br />
It registers a callback for the <em>load</em> event for the iframe and tells the iframe to go to the page we need to test. When the callback fires we make our assertions and then notify QUnit that we are ready with <a href="http://api.qunitjs.com/start/">QUnit#start()</a>. We can register several nested onPageLoad callbacks if the test needs to go over several pages.</p>
<p>The Ajax tests work similarly just they listen for Wicket"s Global . See <em>ajax/form.js</em> from the demo application for example.</p>
<h2>Demo</h2>
<p>A demo application that integrates wicket-examples.war can be found at <a href="https://github.com/martin-g/blogs/tree/master/functional-qunit">my GitHub account</a>.<br />
To run it:</p>
<ul>
<li>git clone git@github.com:martin-g/blogs.git</li>
<li>mvn install</li>
<li>cd functional-qunit</li>
<li>mvn jetty:run</li>
<li>in a browser open <a href="http://localhost:8080/js-test/all.html">http://localhost:8080/js-test/all.html</a>
</ul>
<p>The tests can be integrated in Continious Integration setup easily by using PhantomJS and/or Grunt.js (also based on PhantomJS).<br />
To run the tests with Grunt.js check the header content of grunt.js in the project.</p>
<h2>Credits</h2>
<p>The original idea is borrowed from <a href="http://michelgotta.posterous.com/user-interfaces-and-unittesting-with-qunit-an">User interfaces and unit testing with QUnit</a></p>
</li></ul>
Uploading files to Wicket IResource2012-11-14T10:40:35+00:00http://wicketinaction.com/2012/11/uploading-files-to-wicket-iresource<p>Several times people have asked in the mailing lists how to integrate JavaScript widgets for file uploading like <a href="http://www.plupload.com/">Plupload</a>, <a href="http://www.uploadify.com/">Uploadify</a>, <a href="http://fineuploader.com/index.html">Fine Uploader</a> or <a href="http://blueimp.github.com/jQuery-File-Upload/">jQuery-File-Upload</a> with Apache Wicket.</p>
<h2>The problem</h2>
<p>Wicket provides <em title="org.apache.wicket.markup.html.form.upload.FileUploadField">FileUploadField</em> which can be used as part of a form submission. It supports HTML5 <em>multiple</em> attribute and works great but these JavaScript widgets are smarter than that!</p>
<p>The widgets provide functionalities to select the files to upload with HTML5's Drag & Drop, or if HTML5 is not supported by the browser then fallback to Flash or IFrame solution.</p>
<p>So the widgets don't really need a form to be able to do their work. All they need is a destination URL to send the bytes to.</p>
<h2>The solution</h2>
<p>Users of Apache Wicket know very well its <em title="org.apache.wicket.markup.html.WebPage">WebPage</em> component. It is used as a main container of other smaller components that construct the content that is delivered to the client when a given url is requested.<br />
Since file uploading doesn't really need to construct a page and its optional response often is just a piece of data explaining that the upload is successful or not we are going to use Wicket's <em title="org.apache.wicket.request.resource.IResource">IResource</em> as an endpoint. IResource could be mounted at a predefined mount path just like pages by using a <em title="org.apache.wicket.request.resource.ResourceReference">ResourceReference</em>: </p>
<p>MyApplication.java:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">init</span><span class="o">();</span>
<span class="n">mountResource</span><span class="o">(</span><span class="s">"fileUpload"</span><span class="o">,</span> <span class="k">new</span> <span class="nc">FileUploadResourceReference</span><span class="o">(</span><span class="no">BASE_FOLDER</span><span class="o">));</span>
<span class="n">mountResource</span><span class="o">(</span><span class="s">"fileManager"</span><span class="o">,</span> <span class="k">new</span> <span class="nc">FileManageResourceReference</span><span class="o">(</span><span class="no">BASE_FOLDER</span><span class="o">));</span>
<span class="o">}</span></code></pre></figure>
<p>Here we mounted two resources - one as destination for the file uploads and another for managing the uploaded files (it can serve and delete them).</p>
<p>Check <a href="http://wicketinaction.com/2011/07/wicket-1-5-mounting-resources/">Wicket 1.5 - Mounting resources</a> for more information.</p>
<h3>Reading the uploaded files</h3>
<p>The main problem to solve is how to read the uploaded files from the request parameters.<br />
Actually the solution is quite simple, just few lines of code:</p>
<p>AbstractFileUploadResource.java</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">protected</span> <span class="nc">ResourceResponse</span> <span class="nf">newResourceResponse</span><span class="o">(</span><span class="nc">Attributes</span> <span class="n">attributes</span><span class="o">)</span>
<span class="o">{</span>
<span class="nc">ServletWebRequest</span> <span class="n">webRequest</span> <span class="o">=</span> <span class="o">(</span><span class="nc">ServletWebRequest</span><span class="o">)</span> <span class="n">attributes</span><span class="o">.</span><span class="na">getRequest</span><span class="o">();</span>
<span class="nc">MultipartServletWebRequest</span> <span class="n">multiPartRequest</span> <span class="o">=</span> <span class="n">webRequest</span><span class="o">.</span><span class="na">newMultipartWebRequest</span><span class="o">(</span><span class="n">getMaxSize</span><span class="o">(),</span> <span class="s">"ignored"</span><span class="o">);</span>
<span class="c1">// Note: since Wicket 6.18.0 you will need to call "multiPartRequest.parseFileParts();" additionally here</span>
<span class="nc">Map</span><span class="o"><</span><span class="nc">String</span><span class="o">,</span> <span class="nc">List</span><span class="o"><</span><span class="nc">FileItem</span><span class="o">>></span> <span class="n">files</span> <span class="o">=</span> <span class="n">multiPartRequest</span><span class="o">.</span><span class="na">getFiles</span><span class="o">();</span>
<span class="o">...</span>
<span class="o">}</span></code></pre></figure>
<p>We just asked Wicket to create a WebRequest that knows how to read the multipart request parameters. The final result is a map with keys the name of the request parameter and values the respective <em title="org.apache.wicket.util.upload.FileItem">FileItem</em>s which can be used to get the uploaded file's name, size, input stream, etc.</p>
<p>And basically that's it!<br />
From here on our code is responsible to store somewhere these files and return a response to the client is the format it expects - JSON, HTML, ...</p>
<h2>Demo</h2>
<p>At <a href="https://github.com/martin-g/blogs/tree/master/file-upload">my GitHub account</a> you may find a demo application that integrates <a href="http://blueimp.github.com/jQuery-File-Upload/">jQuery-File-Upload</a>. I've chosen this widget because it looks very nice and I wanted to contribute it to <a href="https://github.com/l0rdn1kk0n/wicket-bootstrap">Wicket Bootstrap</a> project. It appeared that the docs and APIs of this widget are not the best one could wish for. To be able to duplicate the functionalities from its demo page I had to read and debug its internals (specifically jquery.fileupload-ui.js).</p>
<p>There are still some functionalities which do not work completely:</p>
<ul>
<li> the cancel button</li>
<li> the gallery preview of the uploaded files</li>
<li> the UI is broken in IE (I blame my CSS skills for that!)</li>
<li> ... </li>
</ul>
<p>But all these are not directly related to the topic of this post - how to upload files to Wicket IResource and how to read them at the server side.<br />
If you need this component for your application and you fix this issues I'll gladly accept your Pull Requests.</p>
Wicket-CDI for Wicket 6.0 and More2012-09-11T17:01:37+00:00http://wicketinaction.com/2012/09/wicket-cdi-for-wicket-6-and-more<p>If you are using wicket-cdi in your projects, or are thinking about using Wicket and CDI together, read this short <a href="https://www.42lines.net/2012/09/11/status-of-wicket-cdi-module/">blog post</a> about the current status of the wicket-cdi module and its future.</p>
Wicket 6 resource management2012-07-06T13:37:18+00:00http://wicketinaction.com/2012/07/wicket-6-resource-management<p>Several improvements in the header contribution functionality have been made in Wicket 6 to make it more flexible.</p>
<h2>Header items</h2>
<p>The major API break is that now IHeaderResponse can render only instances of <em title="org.apache.wicket.markup.head.HeaderItem">HeaderItem</em>. In previous versions IHeaderResponse had many #renderXyz() methods for each and every combination of CSS or JavaScript attributes, like media, IE condition, charset, url, id, etc. The new version of <em title="org.apache.wicket.markup.head.IHeaderResponse">IHeaderResponse</em> has just one <em>#render(HeaderItem)</em> and the developer should use the most specific implementation of HeaderItem.</p>
<p>For example:</p>
<p>AnyComponent/AnyBehavior.java:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">renderHead</span><span class="o">(</span><span class="nc">IHeaderResponse</span> <span class="n">response</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">renderHead</span><span class="o">(</span><span class="n">response</span><span class="o">);</span>
<span class="n">response</span><span class="o">.</span><span class="na">render</span><span class="o">(</span><span class="k">new</span> <span class="nc">CssContentHeaderItem</span><span class="o">(</span><span class="n">someCss</span><span class="o">,</span> <span class="n">someId</span><span class="o">,</span> <span class="n">optionalCondition</span><span class="o">));</span>
<span class="n">response</span><span class="o">.</span><span class="na">render</span><span class="o">(</span><span class="nc">CssHeaderItem</span><span class="o">.</span><span class="na">forReference</span><span class="o">(</span><span class="k">new</span> <span class="nc">SomeCssResourceReference</span><span class="o">()));</span>
<span class="n">response</span><span class="o">.</span><span class="na">render</span><span class="o">(</span><span class="nc">JavaScriptHeaderItem</span><span class="o">.</span><span class="na">forScript</span><span class="o">(</span><span class="n">someScript</span><span class="o">,</span> <span class="n">someId</span><span class="o">));</span>
<span class="o">}</span></code></pre></figure>
<p><em title="org.apache.wicket.markup.head.JavaScriptHeaderItem">JavaScriptHeaderItem</em> and <em title="org.apache.wicket.markup.head.CssHeaderItem">CssHeaderItem</em> provide factory methods for all default implementations of JavaScript and CSS related header items.</p>
<h2>Dependency management</h2>
<p>Resource references take advantage of the new HeaderItem's and use them to specify on what other resources they depend. The most trivial example is when a JavaScriptResourceReference used to contribute a jQuery plugin needs to declare that it depends on jQuery. This way the component/behavior needs to contribute only the resources it really depends on and Wicket cares to deliver the dependencies first and then the dependants.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyResourceReference</span> <span class="kd">extends</span> <span class="nc">JavaScriptResourceReference</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nf">ResourceReferenceA</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="nc">ResourceReferenceA</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="s">"my.js"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">Iterable</span><span class="o"><?</span> <span class="kd">extends</span> <span class="nc">HeaderItem</span><span class="o">></span> <span class="nf">getDependencies</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">List</span><span class="o"><</span><span class="nc">HeaderItem</span><span class="o">></span> <span class="n">dependencies</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">HeaderItem</span><span class="o">>();</span>
<span class="nc">Url</span> <span class="n">dojoGoogleCdn</span> <span class="o">=</span> <span class="nc">Url</span><span class="o">.</span><span class="na">parse</span><span class="o">(</span><span class="s">"https://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js"</span><span class="o">);</span>
<span class="nc">ExternalUrlResourceReference</span> <span class="n">externalUrlResourceReference</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ExternalUrlResourceReference</span><span class="o">(</span><span class="n">dojoGoogleCdn</span><span class="o">);</span>
<span class="n">dependencies</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">JavaScriptHeaderItem</span><span class="o">.</span><span class="na">forReference</span><span class="o">(</span><span class="n">externalUrlResourceReference</span><span class="o">));</span>
<span class="n">dependencies</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">CssHeaderItem</span><span class="o">.</span><span class="na">forReference</span><span class="o">(</span><span class="k">new</span> <span class="nc">CssResourceReference</span><span class="o">(</span><span class="nc">ResourceReferenceA</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="s">"a.css"</span><span class="o">)));</span>
<span class="k">return</span> <span class="n">dependencies</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>With the example above Wicket will render first the <script> to load Dojo and the <link> to load <em>a.css</em> before rendering the <script> for <em>my.js</em>.</p>
<h2>Resource bundles</h2>
<p>Another new feature in Wicket 6 is that several resources can be combined together in one before delivering it to the browser.</p>
<p>One way to do this is to use WebApplication's ResourceBundles:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">init</span><span class="o">();</span>
<span class="n">getResourceBundles</span><span class="o">()</span>
<span class="o">.</span><span class="na">addJavaScriptBundle</span><span class="o">(</span><span class="nc">ResourceManagementApplication</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="s">"bundle.js"</span><span class="o">,</span>
<span class="k">new</span> <span class="nf">ResourceReferenceA</span><span class="o">(),</span>
<span class="k">new</span> <span class="nf">ResourceReferenceB</span><span class="o">(),</span>
<span class="k">new</span> <span class="nf">ResourceReferenceC</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>Another way is by extending <em title="org.apache.wicket.resource.bundles.ConcatResourceBundleReference">ConcatResourceBundleReference</em> and using it as any other ResourceReference.</p>
<p>The bundle (with all resources) will be contributed if at least one of its resources is contributed by a component or behavior.</p>
<h2>Resource replacement</h2>
<p>Sometimes a third-party library or even Wicket itself adds dependencies you<br />
would rather replace by something else. For example, your application might<br />
depend on a more recent version of a JavaScript library or you want to use a<br />
CDN rather than a packaged resource. For this, Wicket 6 supports replacement<br />
resources. A replacement resource is a resource that will replace any<br />
occurence of some other resource throughout the application. It does not<br />
matter if the replaced resource is added in third party code, in your code or<br />
even as a depedency of another resource.</p>
<p>The following code replaces any occurence of DojoResourceReference by the<br />
version hosted on the Google APIs CDN:</p>
<p>MyApplication.java:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">init</span><span class="o">();</span>
<span class="n">addResourceReplacement</span><span class="o">(</span>
<span class="nc">DojoResourceReference</span><span class="o">.</span><span class="na">get</span><span class="o">(),</span>
<span class="k">new</span> <span class="nf">UrlResourceReference</span><span class="o">(</span><span class="nc">Url</span><span class="o">.</span><span class="na">parse</span><span class="o">(</span><span class="s">"https://ajax.googleapis.com/ajax/libs/dojo/1.7.3/dojo/dojo.js"</span><span class="o">))</span>
<span class="o">);</span></code></pre></figure>
<h2>Positioning of contributions</h2>
<h3>Filtered items</h3>
<p>A not well know feature in Wicket is that the application can provide custom <em title="org.apache.wicket.markup.html.IHeaderResponseDecorator">IHeaderResponseDecorator</em> and filter the header contributions. A common use case is when the application needs to render all JavaScripts in the footer of the page and leave CSSs in the header.<br />
This is made a bit simpler now by introducing <em title="org.apache.wicket.markup.head.filter.FilteredHeaderItem">FilteredHeaderItem</em>.</p>
<p>To make a use of it the developer have to add a special component in his page:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HeaderResponseContainer</span><span class="o">(</span><span class="s">"someId"</span><span class="o">,</span> <span class="n">filterName</span><span class="o">));</span></code></pre></figure>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><wicket:container</span> <span class="na">wicket:id=</span><span class="s">"someId"</span><span class="nt">/></span></code></pre></figure>
<p>And later contribute FilteredHeaderItems in any component or behavior:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">renderHead</span><span class="o">(</span><span class="nc">IHeaderResponse</span> <span class="n">response</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">renderHead</span><span class="o">(</span><span class="n">response</span><span class="o">);</span>
<span class="n">response</span><span class="o">.</span><span class="na">render</span><span class="o">(</span><span class="k">new</span> <span class="nc">FilteredHeaderItem</span><span class="o">(</span><span class="n">wrappedItem</span><span class="o">,</span> <span class="n">filterName</span><span class="o">));</span>
<span class="o">}</span></code></pre></figure>
<h3>Priority items</h3>
<p>Since Wicket 1.5 components do their header contribution before the page they are contained in. The reason is that the application may use a third party component library and the page should be able to override any contribution made by the components. A better design is if the components may be configured what to contribute but sometimes this is not possible. The same is valid for component inheritence - the specialization (the child component) contributes after the base component.<br />
Thanks to the HeaderItems with Wicket 6 it is possible to give some header contributions bigger priority than the others when there is such need. By default Wicket provides <em title="org.apache.wicket.markup.head.PriorityHeaderItem">PriorityHeaderItem</em> which is an item that is contributed before any other non-priority item. If the application needs finer control then it may register a custom comparator with <em title="org.apache.wicket.settings.IResourceSettings">IResourceSettings#setHeaderItemComparator(Comparator)</em></p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">response</span><span class="o">.</span><span class="na">render</span><span class="o">(</span><span class="k">new</span> <span class="nc">PriorityHeaderItem</span><span class="o">(</span><span class="n">wrappedItem</span><span class="o">));</span></code></pre></figure>
<h2>Demo application</h2>
<p>A demo application showing all these features in action can be found at Martin Grigorov's GitHub <a href="https://github.com/martin-g/blogs/tree/master/wicket6-resource-management">repository</a>. Run it locally and check the produced markup for the pages. There are comments inside the code describing the demonstrated features.</p>
<p>Additionally the <a href="http://www.wicket-library.com/wicket-examples-6.0.x/resourceaggregation/">Resource aggregation</a> example has been updated to use the new features. </p>
Wicket 6 Native WebSockets2012-07-05T14:48:16+00:00http://wicketinaction.com/2012/07/wicket-6-native-websockets<h2>Asynchronous communication with Web Sockets</h2>
<p>Wicket 6.0 introduces two new modules, both of them related to Server Push technology, Wicket-Atmosphere and Wicket Native WebSockets. In this article we will see how to make your application more dynamic by employing Wicket Native WebSockets.</p>
<h2>Web Sockets</h2>
<p>Web Sockets are new technology, part of HTML5 stack, for asynchronous communication between the web server and the browser. The client initiates a WebSocket connection by using the JavaScript APIs and from there on both the client and the server may send data to the other party fully asynchronously.</p>
<h2>Wicket Native WebSocket</h2>
<h3>Server side APIs</h3>
<p>Wicket Native WebSocket module provides an integration that makes it as easy to use WebSockets as you already use Ajax in your Wicket applications. Basically all you need to do is to add a WebSocketBehavior to a page/component and override the callback methods you may be interested in - onConnect, onClose and/or onMessage.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">WebSocketBehavior</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onMessage</span><span class="o">(</span><span class="nc">WebSocketRequestHandler</span> <span class="n">handler</span><span class="o">,</span> <span class="nc">TextMessage</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">msg</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="na">getText</span><span class="o">();</span>
<span class="c1">// use the message sent by the client</span>
<span class="n">handler</span><span class="o">.</span><span class="na">push</span><span class="o">(</span><span class="s">"A message pushed by the server"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">});</span></code></pre></figure>
<p>Most probably an application will need to push messages from the server to the client asynchronously, i.e. without the client to ask for such messages. This may be achived by storing the needed information to lookup the WebSocket connection when WebSocketBehavior#onConnect(ConnectedMessage) is called:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onConnect</span><span class="o">(</span><span class="nc">ConnectedMessage</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="n">applicationName</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="na">getApplication</span><span class="o">().</span><span class="na">getName</span><span class="o">();</span>
<span class="n">sessionId</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="na">getSessionId</span><span class="o">();</span>
<span class="n">pageId</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="na">getPageId</span><span class="o">();</span>
<span class="c1">// store applicationName, sessionId, pageId somehow so they are available later</span>
<span class="o">}</span></code></pre></figure>
<p>Later when you need to push a message asynchronously you may lookup the connection with:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"> <span class="nc">IWebSocketConnectionRegistry</span> <span class="n">registry</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SimpleWebSocketConnectionRegistry</span><span class="o">();</span>
<span class="nc">Application</span> <span class="n">application</span> <span class="o">=</span> <span class="nc">Application</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">applicationName</span><span class="o">);</span>
<span class="nc">IWebSocketConnection</span> <span class="n">wsConnection</span> <span class="o">=</span> <span class="n">registry</span><span class="o">.</span><span class="na">getConnection</span><span class="o">(</span><span class="n">application</span><span class="o">,</span> <span class="n">sessionId</span><span class="o">,</span> <span class="n">pageId</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">wsConnection</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="n">wsConnection</span><span class="o">.</span><span class="na">isOpen</span><span class="o">())</span> <span class="o">{</span>
<span class="n">wsConnection</span><span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="s">"Asynchronous message"</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<h3>Client side API</h3>
<p>By default when WebSocketBehavior is used Wicket will open a default WebSocket connection for you, so you can just use:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Wicket</span><span class="p">.</span><span class="nx">WebSocket</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="dl">"</span><span class="s2">A message sent by the client</span><span class="dl">"</span><span class="p">);</span></code></pre></figure>
<p>to send a message from the client to the server.</p>
<p>To listen for messages pushed by the server you have to subscribe for a topic with name '/websocket/message':</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">Wicket</span><span class="p">.</span><span class="nx">Event</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="dl">"</span><span class="s2">/websocket/message</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">jqEvent</span><span class="p">,</span> <span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do something with the message.</span>
<span class="c1">// it may be a text or a binary message depending on what you pushed from the server side</span>
<span class="p">});</span></code></pre></figure>
<h2>Re-rendering components</h2>
<p>If you have noticed earlier #onMessage() receives a parameter of type <em title="org.apache.wicket.ajax.WebSocketRequestHandler">WebSocketRequestHandler</em>. This request handler implements AjaxRequestTarget so it is possible to add components (via #add(Component...)), to prepend/append JavaScript (via #prependJavaScript() and #appendJavaScript()) as you already do with Ajax behaviors.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onMessage</span><span class="o">(</span><span class="nc">WebSocketRequestHandler</span> <span class="n">handler</span><span class="o">,</span> <span class="nc">TextMessage</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="n">handler</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">someComponent</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<h2>Demo application</h2>
<p>At Martin Grigorov's GitHub <a href="https://github.com/martin-g/blogs/tree/master/wicket6-native-websockets">repository</a> you may find an application that demonstrates some of the new possibilities available with WebSockets. The application schedules an asynchronous task at the server side that pushes data back to the client and visualizes it in Google Line chart.</p>
<h2>Documentation</h2>
<p>More complete documentation may be found at the <a href="https://cwiki.apache.org/WICKET/wicket-native-websockets.html">Wiki</a>. Feel free to contribute to make it better. Just create an account and edit it!</p>
Wicket 6 JavaScript improvements2012-07-05T08:56:25+00:00http://wicketinaction.com/2012/07/wicket-6-javascript-improvements<p>A major rework of the internals of the core Wicket JavaScript libraries has been done for Wicket 6. The good news is the client APIs are mostly the same and the application developers will not need to change their applications.</p>
<h2>Event registration</h2>
<p>Until version 1.5.x attaching an Ajax event behavior to a component would lead to addition of an inline attribute to the markup of this component. For example the produced markup for an AjaxLink is similar to:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><a</span> <span class="na">id=</span><span class="s">"linkId"</span> <span class="na">onclick=</span><span class="s">"wicketAjaxGet('some/url')"</span><span class="nt">></span>Link<span class="nt"></a></span></code></pre></figure>
<p>In Wicket 6 JavaScript event registration is being used instead. For example the above becomes:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><head></span>
...
<span class="nt"><script></span>
<span class="nx">Wicket</span><span class="p">.</span><span class="nx">Event</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nb">window</span><span class="p">,</span> <span class="dl">'</span><span class="s1">domready</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">Wicket</span><span class="p">.</span><span class="nx">Ajax</span><span class="p">.</span><span class="kd">get</span><span class="p">({</span><span class="dl">'</span><span class="s1">u</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">some/url</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">c</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">linkId</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">e</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">}));</span>
<span class="c1">// ... more event registrations and onDomReady scripts</span>
<span class="p">});</span>
<span class="nt"></script></span>
<span class="nt"></head></span>
...
<span class="nt"><a</span> <span class="na">id=</span><span class="s">"linkId"</span><span class="nt">></span>Link<span class="nt"></a></span></code></pre></figure>
<p>The benefit is that the event registrations for all elements are done in one place - the page header and your markup elements are not cluttered with extra attributes. Also the generated code for the event registration is much shorter than the one produced in the earlier versions.</p>
<h2>jQuery as backing library</h1>
<p>The previous implementations of wicket-ajax.js and wicket-event.js were home baked solutions which worked well but also suffered from the differences in the browsers. Often users complained that some functionality doesn't work on particular version of particular browser. That's why the Wicket team chose to use JQuery to deal with browser inconsistencies and leave us to do our business logic.</p>
<p>All Java components and behaviors still use the Wicket.** APIs so if an application already uses another big JavaScript library and adding jQuery is not an option then the developer of this application will be able to provide implementation of wicket-event.js and wicket-ajax.js based on her favorite JavaScript library.<br />
To do it the developer should use the new <em title="org.apache.wicket.settings.IJavaScriptLibrarySettings">IJavaScriptLibrarySettings</em>:</p>
<p>MyApplication#init():</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">init</span><span class="o">();</span>
<span class="nc">IJavaScriptLibrarySettings</span> <span class="n">jsSettings</span> <span class="o">=</span> <span class="n">getJavaScriptLibrarySettings</span><span class="o">();</span>
<span class="n">jsSettings</span><span class="o">.</span><span class="na">setBackingLibraryReference</span><span class="o">(</span><span class="k">new</span> <span class="nc">DojoResourceReference</span><span class="o">());</span>
<span class="n">jsSettings</span><span class="o">.</span><span class="na">setWicketEventReference</span><span class="o">(</span><span class="k">new</span> <span class="nc">DojoWicketEventResourceReference</span><span class="o">());</span>
<span class="n">jsSettings</span><span class="o">.</span><span class="na">setWicketAjaxReference</span><span class="o">(</span><span class="k">new</span> <span class="nc">DojoWicketAjaxResourceReference</span><span class="o">());</span>
<span class="o">}</span></code></pre></figure>
<h2>Ajax request attributes</h2>
<p>The main change in the Java code is the introduction of <em title="org.apache.wicket.ajax.attributes.AjaxRequestAttributes">AjaxRequestAttributes</em> in Ajax behaviors API.<br />
AjaxRequestAttributes can be used to configure how exactly the Ajax call should be executed and how its response should be processed. To do this use:</p>
<p>AnyAjaxComponent/AnyAjaxBehavior.java:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"> <span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">updateAjaxAttributes</span><span class="o">(</span><span class="nc">AjaxRequestAttributes</span> <span class="n">attributes</span><span class="o">)</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">updateAjaxAttributes</span><span class="o">(</span><span class="n">attributes</span><span class="o">);</span>
<span class="n">attributes</span><span class="o">.</span><span class="na">setSomeAttribute</span><span class="o">();</span>
<span class="o">}</span></code></pre></figure>
<p>This way the developer can specify whether the Ajax call should use GET or POST method, whether to submit a form, on what JavaScript events to listen to, etc. For a full list of the available attributes see the new <a href="https://cwiki.apache.org/WICKET/wicket-ajax.html#WicketAjax-AjaxRequestAttributes">Wiki</a> page. Most of the attributes have default values and they may be omitted in the generated JavaScript code.</p>
<h2>Ajax call listeners</h2>
<p>Because of the usage of event registration there is no need of <em title="org.apache.wicket.ajax.IAjaxCallDecorator">IAjaxCallDecorator</em> because there is no script to decorate anymore. The same functionality can be achieved with the new <em title="org.apache.wicket.ajax.attributes.IAjaxCallListener">IAjaxCallListener</em>. It provides the means to register JavaScript listeners which are being called during the Ajax call execution. A listener may provide a <em>precondition</em> which may cancel completely the Ajax call when evaluated to false, a <em>before handler</em> - executed right after the successful pass of the preconditions, an <em>after handler</em> - executed right after the make of the Ajax call, a <em>success handler</em> - executed on successful return of the Ajax call, a <em>failure handler</em> - executed when the Ajax call fails for some reason, and a <em>complete handler</em> which is executed after the success/failure handlers no matter what.</p>
<p>To register an AjaxCallListener do something like:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"> <span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">updateAjaxAttributes</span><span class="o">(</span><span class="nc">AjaxRequestAttributes</span> <span class="n">attributes</span><span class="o">)</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">updateAjaxAttributes</span><span class="o">(</span><span class="nc">AjaxRequestAttributes</span> <span class="n">attributes</span><span class="o">);</span>
<span class="nc">IAjaxCallListener</span> <span class="n">listener</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">IAjaxCallListener</span><span class="o">()</span>
<span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="nc">CharSequence</span> <span class="nf">getBeforeHandler</span><span class="o">(</span><span class="nc">Component</span> <span class="n">c</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">handler</span><span class="o">;</span> <span class="o">}</span>
<span class="o">.....</span>
<span class="o">};</span>
<span class="n">attributes</span><span class="o">.</span><span class="na">getAjaxCallListeners</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">listener</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>In the example above the returned <em>handler</em> could be any instance of CharSequence. If it is an instance of <em title="org.apache.wicket.ajax.json.JsonFunction">JsonFunction</em> then it will be written as is, otherwise Wicket will assume that the text is just the body of a JavaScript function and will wrap it in <em title="org.apache.wicket.ajax.json.JsonFunction">JsonFunction</em> for you. The benefit of using <em title="org.apache.wicket.ajax.json.JsonFunction">JsonFunction</em> is that it generates JSON with <em>function</em> as a value. This is non-valid JSON but this way there is no need to use <em>eval()</em> in the browser and the execution of the handlers is faster.</p>
<h2>Global Ajax call listeners</h2>
<p>IAjaxCallListener's can be used to listen for the lifecycle of an Ajax call for a specific component. If the user application needs to listen for all Ajax calls then it may subscribe to the following topics:</p>
<ul>
<li>/ajax/call/before</li>
<li>/ajax/call/after</li>
<li>/ajax/call/success</li>
<li>/ajax/call/failure</li>
<li>/ajax/call/complete</li>
</ul>
<p>Those replaces the old Wicket.Ajax.(registerPreCallHandler|registerPostCallHandler|registerFailureHandler) methods and uses publish/subscribe mechanism.</p>
<p>Example (JavaScript):</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"> <span class="nx">Wicket</span><span class="p">.</span><span class="nx">Event</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="dl">'</span><span class="s1">/ajax/call/failure</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">jqEvent</span><span class="p">,</span> <span class="nx">attributes</span><span class="p">,</span> <span class="nx">jqXHR</span><span class="p">,</span> <span class="nx">errorThrown</span><span class="p">,</span> <span class="nx">textStatus</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// do something when an Ajax call fails</span>
<span class="p">});</span></code></pre></figure>
<p>All global listeners receive the same arguments as the respective IAjaxCallListener handler plus jQuery.Event that is passed by the PubSub system.</p>
<h2>Demo application</h2>
<p>At Martin Grigorov's GitHub <a href="https://github.com/martin-g/blogs/tree/master/wicket6-ajax-demo">repository</a> you may find a simple demo application that shows some of the new features.<br />
The application provides a custom AjaxButton (<em title="com.wicketinaction.HandlebarsButton">HandlebarsButton</em>) that uses:</p>
<ul>
<li>org.apache.wicket.ajax.attributes.AjaxRequestAttributes#setWicketAjaxResponse(false) - tells Wicket.Ajax to not try to process the returned Ajax response. The response is custom JSON which will be processed by a custom success handler</li>
<li>org.apache.wicket.ajax.attributes.AjaxRequestAttributes#setDataType("json") - a hint to Wicket.Ajax that the response is JSON and it will try to parse it for us, so your success handler can use it as JavaScript object directly</li>
<li>usage of JsonFunction as success handler - this way the application needs to provide the complete code of a JavaScript function that will handle the success case</li>
<li>usage of plain Strings with the function bodies for the precondition, before and complete handlers - Wicket will wrap them in JsonFunction for you</li>
<li>shows how to suppress the execution of AjaxRequestHandler - there is no need of it since we return custom JSON response</li>
</ul>
<p>The application itself just updates a POJO (an article) at the server side and serializes it to JSON which is used at the client side to be rendered with the help of <a href="http://handlebarsjs.com/">Handlebars</a> JavaScript library.</p>
<h2>More</h2>
<p>More complete documentation may be found at the <a href="https://cwiki.apache.org/WICKET/wicket-ajax.html">Wiki</a>. Feel free to contribute to make it better. Just create an account and edit it!</p>
</h2>
What's new in Wicket 62012-07-02T13:10:20+00:00http://wicketinaction.com/2012/07/whats-new-in-wicket-6<h1>What's new in Wicket 6</h1>
<p>Wicket 6.0 is around the corner and it is time to describe what's new and what's has changed since Wicket 1.5. This article will mention briefly the major things. More details about the bigger changes will be provided in separate articles.</p>
<h2>Why 6.0 ?</h2>
<p>The Wicket team decided to use semantic versioning (<a href="http://semver.org/">http://semver.org</a>) from now on. That means that having version like x.y.z we will fix bugs in 'z', introduce new features which do not break APIs in 'y' and break APIs in 'x' versions.<br />
This new version has APIs breaks here and there (more on this below) so it must be a change in 'x' part of the version.<br />
Wicket 2.0 has been used already few years ago, somewhere between Wicket 1.2 and 1.3 for a major change which didn't work well and has been discontinued. Next option was Wicket 3.0 but since Wicket 6.0 now requires JDK 6 we decided to jump to 6.0.0. That doesn't mean that Wicket 7 will require JDK 7.</p>
<h2>Major changes in Wicket 6.0</h2>
<h3>JavaScript uses jQuery</h3>
<p>One of the bigger changes is in the Ajax support. Since version 6.0 Wicket will use jQuery internally for its JavaScript needs. Initially we started with an implementation based on YUI but the communitity asked us to re-think this decision and use jQuery instead because most of Wicket's users use jQuery at the moment. So we switched to jQuery as backing library but made it such way that it is easy to replace the current implementation with another one based on another JavaScript library if this is needed by some of the users.</p>
<p>Another change in the this area is that now Wicket uses JavaScript event registration (e.g. jQuery(element).on('click', function() { ... }) instead of using inline attributes in the HTML (e.g. <a onclick="...">).</a></p>
<h3>Resource management</h3>
<p><em title="org.apache.wicket.request.resource.ResourceReference">ResourceReference</em> class now can declare its dependencies so you just need to contribute a ResourceReference for your jQuery plugin for example, and the ResourceReference itself will tell Wicket that jQuery has to be delivered as well.</p>
<p>Additionally <em title="org.apache.wicket.request.resource.PackageResourceReference">PackageResourceReference</em> and its specializations can deliver minified version of their resource if such is available. For example by using<br />
'new JavaScriptResourceReference(MyComponent.class, "my.js")' Wicket will deliver my.js in development mode but will deliver my.min.js in production mode if it is available in the same folder.</p>
<h3>New Tree component</h3>
<p>The previous <em title="org.apache.wicket.extensions.markup.html.tree.Tree">Tree</em> component implementation used AWT/SWING APIs and it was not possible to use it in more restricted environments like Google AppEngine. That's why it has been deprecated and will be removed in a some next major release of Wicket.<br />
<em title="org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree">AbstractTree</em> and its specializations <em title="org.apache.wicket.extensions.markup.html.repeater.tree.NestedTree">NestedTree</em> and <em title="org.apache.wicket.extensions.markup.html.repeater.tree.TableTree">TableTree</em> are the replacements.</p>
<h2>New modules</h2>
<p>A few new modules have been added to the Wicket portfolio. For now they are with experimental status but depending on the adoption they will either join the other modules or will be removed.</p>
<h3>Integration with Atmosphere</h3>
<p>The first new module is Wicket Atmosphere (Maven id: org.apache.wicket:wicket-atmosphere:jar). It is an integration with <a href="https://github.com/Atmosphere/atmosphere/">Atmosphere</a> project and provides server push functionality. Depending on the configuration it may use WebSocket, long polling, streaming, JSONP, Server Side events mechanisms.</p>
<h3>Wicket Native WebSocket</h3>
<p>The second new module is again related to server push functionality but uses native integration with the underlying web container if such is supported. At the moment only Jetty 7+ and Tomcat 7+ are supported.</p>
<h2>What didn't make it</h2>
<h3>Component queueing</h3>
<p>The task of component queueing was to remove the requirement to keep in sync the component trees in the markup and in Java. Due to various technical problems this task has been postponed and may be implemented in a later version of Wicket.</p>
<h3>CDI integration</h3>
<p>The Contexts and Dependency injection (CDI) integration implemented in <a href="https://github.com/42Lines/wicket-cdi">wicket-cdi</a> cannot be merged to Apache Wicket for now because it uses some libraries which are not available yet in Maven central repository. Until this problem is resolved users still can use it as described at the project site.</p>
<h2>What else</h2>
<p>Some more information about the major changes can be found at the <a href="https://cwiki.apache.org/WICKET/wicket-60-roadmap.html">Roadmap</a> page and about other minor changes at the <a href="https://cwiki.apache.org/WICKET/migration-to-wicket-60.html">Migration page</a></p>
<p>The Wicket team!</p>
Wicket 6.0.0-beta2 released2012-05-31T09:20:53+00:00http://wicketinaction.com/2012/05/wicket-6-0-0-beta2-released<p>The Wicket team is proud to announce the second beta release of the Wicket 6.x series. This release brings over many improvements over the 1.5.x series.</p>
<h3 id="new_and_noteworthy">New and Noteworthy</h3>
<h4 id="wicket_atmosphere">Wicket Atmosphere</h4>
<p>The Beta 2 contains a new experimental module Wicket Atmosphere, which brings serverside push to Wicket and provides a great way to render serverside markup and send it to the browsers of your users. Check out the atmosphere example in our Examples project to see it in action.</p>
<p>In your application’s init method you need to register the push event bus:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="k">new</span> <span class="nc">EventBus</span><span class="o">(</span><span class="k">this</span><span class="o">);</span></code></pre></figure>
<p>Somewhere where you want to push your changes to the client, you need to publish your event to the push<code>EventBus</code>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">EventBus</span><span class="o">.</span><span class="na">get</span><span class="o">().</span><span class="na">post</span><span class="o">(</span><span class="n">input</span><span class="o">.</span><span class="na">getModelObject</span><span class="o">());</span></code></pre></figure>
<p>And finally you need to subscribe your page (or component) to the <code>EventBus</code>’s events with <code>@Subscribe</code>, taking in the typed parameter you post to the EventBus (in this case a <code>String</code>):</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Subscribe</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">receiveMessage</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">,</span> <span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="n">label</span><span class="o">.</span><span class="na">setDefaultModelObject</span><span class="o">(</span><span class="n">message</span><span class="o">);</span>
<span class="n">target</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">label</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>To be able to use Wicket Atmosphere you need to include the following dependency:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.apache.wicket<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>wicket-atmosphere<span class="nt"></artifactId></span>
<span class="nt"><version></span>0.1<span class="nt"></version></span>
<span class="nt"></dependency></span></code></pre></figure>
<p>Please note that this is still experimental.</p>
<h3 id="this_release">This release</h3>
<p>Check the <a href="https://cwiki.apache.org/WICKET/wicket-60-roadmap.html">roadmap</a> with a list of the major goals. And the <a href="https://cwiki.apache.org/WICKET/migration-to-wicket-60.html">migration guide</a> with all major and some minor changes between 1.5.x and 6.x series.</p>
<p>The Jira changelog of all closed ticket at <a href="https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12310561&version=12320343">Jira</a></p>
<p>To use it in Maven:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.apache.wicket<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>wicket-core<span class="nt"></artifactId></span>
<span class="nt"><version></span>6.0.0-beta2<span class="nt"></version></span>
<span class="nt"></dependency></span></code></pre></figure>
<p>If you don’t use a dependencies management build tool then you can download the <a href="http://www.apache.org/dyn/closer.cgi/wicket/6.0.0-beta2">full distribution</a> (including source).</p>
<p>There are no more planned API breaks but if you find something that can be made better now it the time to discuss it! We will try to avoid making any API changes in the Release Candidates that will follow this beta release.</p>
<p>Any feedback about the new features, their implementation and their documentation is very welcome!</p>
<p>The Wicket team!</p>