Added: wicket/common/site/trunk/_site/guide/guide/advanced.html
URL: 
http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/advanced.html?rev=1562075&view=auto
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/advanced.html (added)
+++ wicket/common/site/trunk/_site/guide/guide/advanced.html Tue Jan 28 
14:13:34 2014
@@ -0,0 +1,367 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+                      
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en">
+<head>
+    <title>17 Wicket advanced topics 6.x</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <link rel="stylesheet" href="../css/main.css" type="text/css" 
media="screen, print" title="Style" charset="utf-8"/>
+    <link rel="stylesheet" href="../css/pdf.css" type="text/css" media="print" 
title="PDF" charset="utf-8"/>
+    <script type="text/javascript">
+function addJsClass() {
+    var classes = document.body.className.split(" ");
+    classes.push("js");
+    document.body.className = classes.join(" ");
+}
+    </script>
+</head>
+
+<body class="body" onload="addJsClass();">
+<div id="navigation">
+    <ul>
+        <li>
+            <div id="nav-summary" onmouseover="toggleNavSummary(false)" 
onmouseout="toggleNavSummary(true)">
+                <a href="../guide/index.html" class="button">Table of 
contents</a>
+
+                <div id="nav-summary-childs" style="display:none;">
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/introduction.html"><strong>1</strong><span>Introduction</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/howToSource.html"><strong>2</strong><span>How to use the example 
code</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/whyLearn.html"><strong>3</strong><span>Why should I learn 
Wicket?</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/helloWorld.html"><strong>4</strong><span>Wicket says 
&ldquo;Hello world!&rdquo;</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/layout.html"><strong>5</strong><span>Wicket as page layout 
manager</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/keepControl.html"><strong>6</strong><span>Keeping control over 
HTML</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/componentLifecycle.html"><strong>7</strong><span>Components 
lifecycle</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/versioningCaching.html"><strong>8</strong><span>Page versioning 
and caching</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/requestProcessing.html"><strong>9</strong><span>Under the hood 
of the request processing</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/urls.html"><strong>10</strong><span>Wicket Links and URL 
generation</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/modelsforms.html"><strong>11</strong><span>Wicket models and 
forms</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/forms2.html"><strong>12</strong><span>Wicket forms in 
detail</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/repeaters.html"><strong>13</strong><span>Displaying multiple 
items with repeaters</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/i18n.html"><strong>14</strong><span>Internationalization with 
Wicket</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/resources.html"><strong>15</strong><span>Resource management 
with Wicket</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/jsintegration.html"><strong>16</strong><span>An example of 
integration with JavaScript</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/advanced.html"><strong>17</strong><span>Wicket advanced 
topics</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/ajax.html"><strong>18</strong><span>Working with AJAX</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/jee.html"><strong>19</strong><span>Integration with enterprise 
containers</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/security.html"><strong>20</strong><span>Security with 
Wicket</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/testing.html"><strong>21</strong><span>Test Driven Development 
with Wicket</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/testingspring.html"><strong>22</strong><span>Test Driven 
Development with Wicket and Spring</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/bestpractices.html"><strong>23</strong><span>Wicket Best 
Practices</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/maven.html"><strong>24</strong><span>Working with Maven 
(Appendix)</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/wicketstuff.html"><strong>25</strong><span>Project WicketStuff 
(Appendix)</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/redirects.html"><strong>26</strong><span>Lost In Redirection 
With Apache Wicket (Appendix)</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0"><a 
href="../guide/contributing.html"><strong>27</strong><span>Contributing to this 
guide (Appendix)</span></a>
+                    </div>
+                    
+                </div>
+            </div>
+        </li>
+        <li class="separator selected">
+            <a id="ref-button" onclick="localToggle(); return false;" 
href="#">Quick Reference</a>
+        </li>
+    </ul>
+</div>
+<div id="header">
+    <div class="images clearfix">
+        
+        <span id="logo"><a href="/" target="_blank"><img height="80px" 
src="http://wicket.apache.org/guide/img/apache-wicket.png"/></a></span>
+        
+        
+        <span id="sponsor"><a href="http://www.apache.org/"; 
target="_blank"><img height="60px" 
src="http://wicket.apache.org/guide/img/asf_logo.gif"/></a></span>
+        
+    </div>
+    <p>Free Online Guide for Apache Wicket framework</p>
+</div>
+
+
+<table id="colset" border="0" cellpadding="0" cellspacing="0">
+    <tr>
+        <td id="col1">
+            <div id="main" class="corner-all">
+
+                
+                    <div class="toc-item prev-left"><a 
href="../guide/jsintegration.html">&lt;&lt; <strong>16</strong><span>An example 
of integration with JavaScript</span></a></div>
+                
+
+                <span id='toggle-col1' class="toggle">(<a href="#" 
onclick="localToggle(); return false;">Quick Reference</a>)</span>
+
+                
+                    <div class="toc-item next-right"><a 
href="../guide/ajax.html"><strong>18</strong><span>Working with AJAX</span> 
>></a></div>
+                
+
+
+                <div class="project">
+                    <h1>17 Wicket advanced topics - Reference 
Documentation</h1>
+
+                    <p><strong>Authors:</strong> Andrea Del Bene, Carsten 
Hufe, Christian Kroemer, Daniel Bartl, Paul Borș</p>
+
+                    <p><strong>Version:</strong> 6.x</p>
+
+                    
+                </div>
+
+                
+                <div id="table-of-content">
+                    <h2>Table of Contents</h2>
+                    
+                    <div class="toc-item" style="margin-left:0px"><a 
href="#advanced_1"><strong>17.1</strong><span>Enriching components with 
behaviors</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0px"><a 
href="#advanced_2"><strong>17.2</strong><span>Generating callback URLs with 
IRequestListener</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0px"><a 
href="#advanced_3"><strong>17.3</strong><span>Initializers</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0px"><a 
href="#advanced_4"><strong>17.4</strong><span>Using JMX with Wicket</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0px"><a 
href="#advanced_5"><strong>17.5</strong><span>Generating HTML markup from 
code</span></a>
+                    </div>
+                    
+                    <div class="toc-item" style="margin-left:0px"><a 
href="#advanced_6"><strong>17.6</strong><span>Summary</span></a>
+                    </div>
+                    
+                </div>
+                
+
+                
+
+<h1 id="advanced">17 Wicket advanced topics</h1>
+In this chapter we will learn some advanced topics which have not been covered 
yet in the previous chapters but which are nonetheless essential to make the 
most of Wicket and to build sophisticated web applications.
+
+
+<h2 id="advanced_1">17.1 Enriching components with behaviors</h2>
+<p class="paragraph"/>With class 
<code>org.apache.wicket.behavior.Behavior</code> Wicket provides a very 
flexible mechanism to share common features across different components and to 
enrich existing components with further functionalities. As the class name 
suggests, <code>Behavior</code> adds a generic behavior to a component 
modifying its markup and/or contributing to the header section of the page 
(<code>Behavior</code> implements the interface 
<code>IHeaderContributor</code>).<p class="paragraph"/>One or more behaviors 
can be added to a component with <code>Component</code>'s method 
<code>add(Behavior...)</code>, while to remove a behavior we must use method 
<code>remove(Behavior)</code>.<p class="paragraph"/>Here is a partial list of 
methods defined inside class <code>Behavior</code> along with a brief 
description of what they do:
+<ul class="star">
+<li><strong class="bold">beforeRender(Component component)</strong>: called 
when a component is about to be rendered.</li>
+<li><strong class="bold">afterRender(Component component)</strong>: called 
after a component has been rendered.</li>
+<li><strong class="bold">onComponentTag(Component component, ComponentTag 
tag)</strong>: called when component tag is being rendered.</li>
+<li><strong class="bold">getStatelessHint(Component component)</strong>: 
returns if a behavior is stateless or not.</li>
+<li><strong class="bold">bind(Component component)</strong>: called after a 
behavior has been added to a component.</li>
+<li><strong class="bold">unbind(Component component)</strong>: called when a 
behavior has been removed from a component.</li>
+<li><strong class="bold">detach(Component component)</strong>: overriding this 
method a behavior can detach its state before being serialized.</li>
+<li><strong class="bold">isEnabled(Component component)</strong>: tells if the 
current behavior is enabled for a given component. When a behavior is disabled 
it will be simply ignored and not executed.</li>
+<li><strong class="bold">isTemporary(Component component)</strong>: tells 
component if the current behavior is temporary. A temporary behavior is 
discarded at the end of the current request (i.e it's executed only once).</li>
+<li><strong class="bold">onConfigure(Component component)</strong>: called 
right after the owner component has been configured.</li>
+<li><strong class="bold">onRemove(Component component)</strong>: called when 
the owner component has been removed from its container.</li>
+<li><strong class="bold">renderHead(Component component, IHeaderResponse 
response)</strong>: overriding this method behaviors can render resources to 
the header section of the page.</li>
+</ul><p class="paragraph"/>For example the following behavior prepends a red 
asterisk to the tag of a form component if this one  is required:<p 
class="paragraph"/><div class="code"><pre><span 
class="java&#45;keyword">public</span> class RedAsteriskBehavior <span 
class="java&#45;keyword">extends</span> Behavior &#123;<p class="paragraph"/>  
@Override
+  <span class="java&#45;keyword">public</span> void beforeRender(Component 
component) &#123;
+      Response response = component.getResponse();
+      <span class="java&#45;object">StringBuffer</span> asterisktHtml = <span 
class="java&#45;keyword">new</span> <span 
class="java&#45;object">StringBuffer</span>(200);<p class="paragraph"/>      
<span class="java&#45;keyword">if</span>(componet <span 
class="java&#45;keyword">instanceof</span> FormComponent 
+            &#38;&#38; ((FormComponent)component).isRequired())&#123;
+        asteriskHtml.append(<span class="java&#45;quote">" &#60;b 
style=&#34;color:red;font&#45;size:medium&#34;&#62;&#42;&#60;/b&#62;"</span>);
+      &#125;  
+      response.write(asteriskHtml);
+  &#125;
+&#125;</pre></div><p class="paragraph"/>Since method <code>beforeRender</code> 
is called before the coupled component is rendered, we can use it to prepend 
custom markup to component tag. This can be done writing our markup directly to 
the current  Response object, as we did in the example above.<p 
class="paragraph"/>Please note that we could achieve the same result overriding 
component method <code>onBeforeRender</code>. However using a behavior we can 
easily reuse our custom code with any other kind of component without modifying 
its source code. As general best practice we should always consider to 
implement a new functionality using a behavior if it can be shared among 
different kinds of component.<p class="paragraph"/>Behaviors play also a 
strategic role in the built-in AJAX support provided by Wicket, as we will see 
in the next chapter. 
+
+
+
+<h2 id="advanced_2">17.2 Generating callback URLs with IRequestListener</h2>
+<p class="paragraph"/>With Wicket it's quite easy to build a callback URL that 
executes a specific method on server side. This method must be defined in a 
functional interface (i.e. an an interface that defines just one method) that 
inherits from built-in <code>org.apache.wicket.IRequestListener</code> and it 
must be a void method with no parameters in input:<p class="paragraph"/><div 
class="code"><pre><span class="java&#45;keyword">public</span> <span 
class="java&#45;keyword">interface</span> IMyListener <span 
class="java&#45;keyword">extends</span> IRequestListener
+&#123;
+       /&#42;&#42;
+        &#42; Called when the relative callback URL is requested.
+        &#42;/
+       void myCallbackMethod();
+&#125;</pre></div><p class="paragraph"/>To control how the method will be 
invoked we must use class 
<code>org.apache.wicket.RequestListenerInterface</code>. In Wicket is a common 
practice to instantiate this class as a public static field inside the relative 
callback interface:<p class="paragraph"/><div class="code"><pre><span 
class="java&#45;keyword">public</span> <span 
class="java&#45;keyword">interface</span> IMyListener <span 
class="java&#45;keyword">extends</span> IRequestListener
+&#123;
+       /&#42;&#42;RequestListenerInterface instance&#42;/
+       <span class="java&#45;keyword">public</span> <span 
class="java&#45;keyword">static</span> <span 
class="java&#45;keyword">final</span> RequestListenerInterface INTERFACE = 
<span class="java&#45;keyword">new</span> 
+                               RequestListenerInterface(IMyListener.class);
+       /&#42;&#42;
+        &#42; Called when the relative callback URL is requested.
+        &#42;/
+       void myCallbackMethod();
+&#125;</pre></div><p class="paragraph"/>By default 
<code>RequestListenerInterface</code> will respond rendering the current page 
after the callback method has been executed (if we have a non-AJAX request). To 
change this behavior we can use setter method 
<code>setRenderPageAfterInvocation(boolean)</code>.<p class="paragraph"/>Now 
that our callback interface is complete we can generate a callback URL with 
<code>Component</code>'s method <code>urlFor(RequestListenerInterface, 
PageParameters)</code> or with method <code>urlFor (Behavior, 
RequestListenerInterface, PageParameters)</code> if we are using a callback 
interface with a behavior (see the following example).<p 
class="paragraph"/>Project CallbackURLExample contains a behavior (class 
<code>OnChangeSingleChoiceBehavior</code>) that implements a callback interface 
to update the model of an <code>AbstractSingleSelectChoice</code> component 
when user changes the selected option (it provides the same functionality of 
method <code>want
 OnSelectionChangedNotifications</code>).<p class="paragraph"/>Instead of a 
custom callback interface, <code>OnChangeSingleChoiceBehavior</code> implements 
built-in interface <code>org.apache.wicket.behavior.IBehaviorListener</code> 
which is designed to generate a callback URL for behaviors. The callback method 
defined in this interface is <code>onRequest()</code> and the following is the 
implementation provided by <code>OnSelectionChangedNotifications</code>:<p 
class="paragraph"/><div class="code"><pre>@Override
+<span class="java&#45;keyword">public</span> void onRequest() &#123;   
+       Request request = RequestCycle.get().getRequest();
+       IRequestParameters requestParameters = request.getRequestParameters();
+       StringValue choiceId = requestParameters.getParameterValue(<span 
class="java&#45;quote">"choiceId"</span>);
+       //boundComponent is the component that the behavior it is bound to.
+       boundComponent.setDefaultModelObject( 
convertChoiceIdToChoice(choiceId.toString()));
+&#125;</pre></div><p class="paragraph"/>When invoked via URL, the behavior 
expects to find a request parameter (choiceId) containing the id of the 
selected choice. This value is used to obtain the corresponding choice object 
that must be used to set the model of the component that the behavior is bound 
to (boundComponent). Method <code>convertChoiceIdToChoice</code> is in charge 
of retrieving the choice object given its id and it has been copied from class 
<code>AbstractSingleSelectChoice</code>.<p class="paragraph"/>Another 
interesting part of <code>OnChangeSingleChoiceBehavior</code> is its method 
<code>onComponentTag</code> where some JavaScript “magic” is used to move 
user's browser to the callback URL when event “change” occurs on bound 
component:<p class="paragraph"/><div class="code"><pre>@Override
+<span class="java&#45;keyword">public</span> void onComponentTag(Component 
component, ComponentTag tag) &#123;
+       <span class="java&#45;keyword">super</span>.onComponentTag(component, 
tag);<p class="paragraph"/>       CharSequence callBackURL = getCallbackUrl();
+       <span class="java&#45;object">String</span> separatorChar = 
(callBackURL.toString().indexOf('?') &#62; &#45;1 ? <span 
class="java&#45;quote">"&#38;"</span> : <span 
class="java&#45;quote">"?"</span>);<p class="paragraph"/>   <span 
class="java&#45;object">String</span> finalScript = <span 
class="java&#45;quote">"<span class="java&#45;keyword">var</span> isSelect = 
$(<span class="java&#45;keyword">this</span>).is('select');&#110;"</span> +
+                                <span class="java&#45;quote">"<span 
class="java&#45;keyword">var</span> component;&#110;"</span> +     
+                                <span class="java&#45;quote">"<span 
class="java&#45;keyword">if</span>(isSelect)&#110;"</span> +
+                                <span class="java&#45;quote">" component = 
$(<span class="java&#45;keyword">this</span>);&#110;"</span> +
+                                <span class="java&#45;quote">"<span 
class="java&#45;keyword">else</span> &#110;"</span> +
+                                <span class="java&#45;quote">" component = 
$(<span 
class="java&#45;keyword">this</span>).find('input:radio:checked');&#110;"</span>
 +
+                                <span 
class="java&#45;quote">"window.location.href='"</span> + callBackURL +  
separatorChar + 
+                                <span class="java&#45;quote">"choiceId=' + 
"</span> + <span class="java&#45;quote">"component.val()"</span>;<p 
class="paragraph"/>     tag.put(<span class="java&#45;quote">"onchange"</span>, 
finalScript);
+&#125;</pre></div><p class="paragraph"/>The goal of 
<code>onComponentTag</code> is to build an onchange handler that forces user's 
browser to move to the callback URL (modifing standard property 
window.location.href). Please note that we have appended the expected parameter 
(choiceId) to the URL retrieving its value with a JQuery selector suited for 
the current type of component (a drop-down menu or a radio group). Since we are 
using JQuery in our JavaScript code, the behavior comes also with method 
<code>renderHead</code> that adds the bundled JQuery library to the current 
page.<p class="paragraph"/>Method <code>getCallbackUrl()</code> is used to 
generate the callback URL for our custom behavior and it has been copied from 
built-in class <code>AbstractAjaxBehavior</code>:<p class="paragraph"/><div 
class="code"><pre><span class="java&#45;keyword">public</span> CharSequence 
getCallbackUrl()&#123;
+       <span class="java&#45;keyword">if</span> (boundComponent == <span 
class="java&#45;keyword">null</span>)&#123;
+               <span class="java&#45;keyword">throw</span> <span 
class="java&#45;keyword">new</span> IllegalArgumentException(
+                       <span class="java&#45;quote">"Behavior must be bound to 
a component to create the URL"</span>);
+       &#125;<p class="paragraph"/>    <span 
class="java&#45;keyword">final</span> RequestListenerInterface rli;<p 
class="paragraph"/> rli = IBehaviorListener.INTERFACE;<p class="paragraph"/>    
    <span class="java&#45;keyword">return</span> boundComponent.urlFor(<span 
class="java&#45;keyword">this</span>, rli, <span 
class="java&#45;keyword">new</span> PageParameters());
+&#125;</pre></div><p class="paragraph"/>Static field 
<code>IBehaviorListener.INTERFACE</code> is the implementation of 
<code>RequestListenerInterface</code> defined inside callback interface 
<code>IBehaviorListener</code>.<p class="paragraph"/>The home page of project 
<code>CallbackURLExample</code> contains a <code>DropDownChoice</code> and a 
<code>RadioChoice</code> which use our custom behavior. There are also two 
labels to display the content of the models of the two components:<p 
class="paragraph"/><img border="0" class="center" 
src="../img/CallbackURLExample-screenshot.png"></img><p 
class="paragraph"/><blockquote class="note">
+Implementing interface <code>IBehaviorListener</code> makes a behavior 
stateful because its callback URL is specific for a given instance of component.
+</blockquote><p class="paragraph"/>
+<h3>Wicket events infrastructure</h3><p class="paragraph"/>Starting from 
version 1.5 Wicket offers an event-based infrastructure for inter-component 
communication. The infrastructure is based on two simple interfaces (both in 
package <code>org.apache.wicket.event</code>) : <code>IEventSource</code> and 
<code>IEventSink</code>.<p class="paragraph"/>The first interface must be 
implemented by those entities that want to broadcast en event while the second 
interface must be implemented by those entities that want to receive a 
broadcast event.<p class="paragraph"/>The following entities already implement 
both these two interfaces (i.e. they can be either sender or receiver): 
<code>Component</code>, <code>Session</code>, <code>RequestCycle</code> and 
<code>Application</code>.
+<code>IEventSource</code> exposes a single method named send which takes in 
input three parameters:
+<ul class="star">
+<li><strong class="bold">sink</strong>: an implementation of 
<code>IEventSink</code> that will be the receiver of the event.</li>
+<li><strong class="bold">broadcast</strong>: a <code>Broadcast</code> enum 
which defines the broadcast method used to dispatch the event to the sink and 
to other entities such as sink children, sink containers, session object, 
application object and the current request cycle. It has four possible 
values:</li>
+</ul><p class="paragraph"/><table class="wiki-table" cellpadding="0" 
cellspacing="0" border="0"><tr><th><strong 
class="bold">Value</strong></th><th><strong 
class="bold">Description</strong></th></tr><tr 
class="table-odd"><td>BREADTH</td><td>The event is sent first to the specified 
sink and then to all its children components following a breadth-first 
order.</td></tr><tr class="table-even"><td>DEPTH</td><td>The event is sent to 
the specified sink only after it has been dispatched to all its children 
components following a depth-first order.</td></tr><tr 
class="table-odd"><td>BUBBLE</td><td>The event is sent first to the specified 
sink and then to its parent containers.</td></tr><tr 
class="table-even"><td>EXACT</td><td>The event is sent only to the specified 
sink.</td></tr></table>
+<ul class="star">
+<li><strong class="bold">payload</strong>: a generic object representing the 
data sent with the event.</li>
+</ul><p class="paragraph"/>Each broadcast mode has its own traversal order for 
<code>Session</code>, <code>RequestCycle</code> and <code>Application</code>. 
See JavaDoc of class <code>Broadcast</code> for further details about this 
order.<p class="paragraph"/>Interface <code>IEventSink</code> exposes callback 
method <code>onEvent(IEvent&#60;?&#62; event)</code> which is triggered when a 
sink receives an event. The interface <code>IEvent</code> represents the 
received event and provides getter methods to retrieve the event broadcast 
type, the source of the event and its payload. Typically the received event is 
used checking the type of its payload object:<p class="paragraph"/><div 
class="code"><pre>@Override
+<span class="java&#45;keyword">public</span> void onEvent(IEvent event) &#123;
+  //<span class="java&#45;keyword">if</span> the type of payload is 
MyPayloadClass perform some actions 
+  <span class="java&#45;keyword">if</span>(event.getPayload() <span 
class="java&#45;keyword">instanceof</span> MyPayloadClass) &#123;
+     //execute some business code.
+  &#125;<span class="java&#45;keyword">else</span>&#123;
+     //other business code
+  &#125;               
+&#125;</pre></div><p class="paragraph"/>Project 
<code>InterComponetsEventsExample</code> provides a concrete example of sending 
an event to a component (named 'container in the middle') using all the 
available broadcast methods:<p class="paragraph"/><img border="0" 
class="center" src="../img/InterComponentsEventsExample-screenshot.png"></img>
+
+
+
+<h2 id="advanced_3">17.3 Initializers</h2>
+<p class="paragraph"/>Some components or resources may need to be configured 
before being used in our applications. While so far we used Application's init 
method to initialize these kinds of entities, Wicket offers a more flexible and 
modular way to configure our classes.<p class="paragraph"/>During application's 
bootstrap Wicket searches for any properties file named wicket.properties  
placed in one of the classpath roots visible to the application. When one of 
these files is found, the initializer defined inside it will be executed. An 
initializer is an implementation of interface 
<code>org.apache.wicket.IInitializer</code> and is defined inside 
wicket.properties with a line like this:<p class="paragraph"/><div 
class="code"><pre>initializer=org.wicketTutorial.MyInitializer</pre></div><p 
class="paragraph"/>The fully qualified class name corresponds to the 
initializer that must be executed. Interface <code>IInitializer</code> defines 
method init(Application) which should contain ou
 r initialization code, and method <code>destroy(Application)</code> which is 
invoked when application is terminated:<p class="paragraph"/><div 
class="code"><pre><span class="java&#45;keyword">public</span> class 
MyInitializer <span class="java&#45;keyword">implements</span> 
IInitializer&#123;<p class="paragraph"/>    <span 
class="java&#45;keyword">public</span> void init(Application application) &#123;
+               //initialization code 
+       &#125;<p class="paragraph"/>    <span 
class="java&#45;keyword">public</span> void destroy(Application application) 
&#123;
+               //code to execute when application is terminated
+       &#125;  
+&#125;</pre></div><p class="paragraph"/>Only one initializer can be defined in 
a single wicket.properties file. To overcome this limit we can create a main 
initializer that in turn executes every initializer we need:<p 
class="paragraph"/><div class="code"><pre><span 
class="java&#45;keyword">public</span> class MainInitializer <span 
class="java&#45;keyword">implements</span> IInitializer&#123;<p 
class="paragraph"/>      <span class="java&#45;keyword">public</span> void 
init(Application application) &#123;
+               <span class="java&#45;keyword">new</span> 
AnotherInitializer().init(application);
+               <span class="java&#45;keyword">new</span> 
YetAnotherInitializer().init(application);
+               //&#8230; 
+       &#125;
+       //destroy&#8230; 
+&#125;</pre></div>
+
+
+<h2 id="advanced_4">17.4 Using JMX with Wicket</h2>
+<p class="paragraph"/>JMX (Java Management Extensions) is the standard 
technology adopted in Java for managing and monitoring running applications or 
Java Virtual Machines. Wicket offers support for JMX through module wicket-jmx. 
In this paragraph we will see how we can connect to a Wicket application using 
JMX. In our example we will use JConsole as JMX client. This program is bundled 
with Java SE since version 5 and we can run it typing jconsole in our OS 
shell.<p class="paragraph"/>Once JConsole has started it will ask us to 
establish a new connection to a Java process, choosing between a local process 
or a remote one. In the following picture we have selected the process 
corresponding to the local instance of Jetty server we used to run one of our 
example projects:<p class="paragraph"/><img border="0" class="center" 
src="../img/JMX-new-connection.png"></img><p class="paragraph"/>After we have 
established a JMX connection, JConsole will show us the following set of 
tabs:<p class=
 "paragraph"/><img border="0" class="center" 
src="../img/JMX-console.png"></img><p class="paragraph"/>JMX exposes 
application-specific informations using special objects called MBeans 
(Manageable Beans), hence if we want to control our application we must open 
the corresponding tab. The MBeans containing the application's informations is 
named <code>org.apache.wicket.app.&#60;filter/servlet name&#62;</code>.<p 
class="paragraph"/>In our example we have used wicket.test as filter name for 
our application:<p class="paragraph"/><img border="0" class="center" 
src="../img/JMX-console2.png"></img><p class="paragraph"/>As we can see in the 
picture above, every MBean exposes a node containing its attributes and another 
node showing the possible operations that can be performed on the object. In 
the case of a Wicket application the available operations are clearMarkupCache 
and clearLocalizerCache:<p class="paragraph"/><img border="0" class="center" 
src="../img/JMX-console3.png"></img><p class=
 "paragraph"/>With these two operations we can force Wicket to clear the 
internal caches used to load components markup and resource bundles. This can 
be particularly useful if we have our application running in DEPLOYMENT mode 
and we want to publish minor fixes for markup or bundle files (like spelling or 
typo corrections) without restarting the entire application. Without cleaning 
these two caches Wicket would continue to use cached values ignoring any change 
made to markup or bundle files.<p class="paragraph"/>Some of the exposed 
properties are editable, hence we can tune their values while the application 
is running. For example if we look at the properties of 
<code>ApplicationSettings</code> we can set the maximum size allowed for an 
upload modifying the attribute DefaultMaximumUploadSize:<p 
class="paragraph"/><img border="0" class="center" 
src="../img/JMX-console4.png"></img>
+
+
+<h2 id="advanced_5">17.5 Generating HTML markup from code</h2>
+<p class="paragraph"/>So far, as markup source for our pages/panels we have 
used a static markup file, no matter if it was inherited or directly associated 
to the component. Now we want to investigate a more complex use case where we 
want to dynamical generate the markup directly inside component code.<p 
class="paragraph"/>To become a markup producer, a component must simply 
implement interface 
<code>org.apache.wicket.markup.IMarkupResourceStreamProvider</code>. The only 
method defined in this interface is 
<code>getMarkupResourceStream(MarkupContainer, Class&#60;?&#62;)</code> which 
returns an utility interface called <code>IResourceStream</code> representing 
the actual markup.<p class="paragraph"/>In the following example we have a 
custom panel without a related markup file that generates a simple 
&#60;div&#62; tag as markup:<p class="paragraph"/><div class="code"><pre><span 
class="java&#45;keyword">public</span> class AutoMarkupGenPanel <span 
class="java&#45;keyword">extends</span
 > Panel <span class="java&#45;keyword">implements</span> 
 > IMarkupResourceStreamProvider &#123;
+       <span class="java&#45;keyword">public</span> AutoMarkupGenPanel(<span 
class="java&#45;object">String</span> id, IModel&#60;?&#62; model) &#123;
+               <span class="java&#45;keyword">super</span>(id, model);         
+       &#125;<p class="paragraph"/>    @Override
+       <span class="java&#45;keyword">public</span> IResourceStream 
getMarkupResourceStream(MarkupContainer container,
+                       <span class="java&#45;object">Class</span>&#60;?&#62; 
containerClass) &#123;
+               <span class="java&#45;object">String</span> markup = <span 
class="java&#45;quote">"&#60;div&#62;Panel markup&#60;/div&#62;"</span>;
+               StringResourceStream resourceStream = <span 
class="java&#45;keyword">new</span> StringResourceStream(markup);<p 
class="paragraph"/>             <span class="java&#45;keyword">return</span> 
resourceStream;
+       &#125;
+&#125;</pre></div><p class="paragraph"/>Class StringResourceStream is a 
resource stream that uses a String instance as backing object.<p 
class="paragraph"/><h3>Avoiding markup caching</h3><p class="paragraph"/>As we 
have seen in the previous paragraph, Wicket uses an internal cache for 
components markup. This can be a problem if our component dynamical generates 
its markup when it is rendered because once the markup has been cached, Wicket 
will always use the cached version for the specific component. To overwrite 
this default caching policy, a component can implement interface 
<code>IMarkupCacheKeyProvider</code>.<p class="paragraph"/>This interface 
defines method <code>getCacheKey(MarkupContainer, Class&#60;?&#62;)</code> 
which returns a string value representing the key used by Wicket to retrieve 
the markup of the component from the cache. If this value is null the markup 
will not be cached, allowing the component to display the last generated markup 
each time it is rendered:<p c
 lass="paragraph"/><div class="code"><pre><span 
class="java&#45;keyword">public</span> class NoCacheMarkupPanel <span 
class="java&#45;keyword">extends</span> Panel <span 
class="java&#45;keyword">implements</span> IMarkupCacheKeyProvider &#123;
+       <span class="java&#45;keyword">public</span> NoCacheMarkupPanel(<span 
class="java&#45;object">String</span> id, IModel&#60;?&#62; model) &#123;
+               <span class="java&#45;keyword">super</span>(id, model);         
+       &#125;<p class="paragraph"/>    /&#42;&#42;
+       &#42; Generate a dynamic HTML markup that changes every time
+       &#42; the component is rendered
+       &#42;/
+       @Override
+       <span class="java&#45;keyword">public</span> IResourceStream 
getMarkupResourceStream(MarkupContainer container,
+                       <span class="java&#45;object">Class</span>&#60;?&#62; 
containerClass) &#123;
+               <span class="java&#45;object">String</span> markup = <span 
class="java&#45;quote">"&#60;div&#62;Panel with current nanotime: "</span> + 
<span class="java&#45;object">System</span>.nanoTime() +
+                                <span 
class="java&#45;quote">"&#60;/div&#62;"</span>; 
+               StringResourceStream resourceStream = <span 
class="java&#45;keyword">new</span> StringResourceStream(markup);<p 
class="paragraph"/>             <span class="java&#45;keyword">return</span> 
resourceStream;
+       &#125;<p class="paragraph"/>    /&#42;&#42;
+       &#42; Avoid markup caching <span class="java&#45;keyword">for</span> 
<span class="java&#45;keyword">this</span> component
+       &#42;/
+       @Override
+       <span class="java&#45;keyword">public</span> <span 
class="java&#45;object">String</span> getCacheKey(MarkupContainer arg0, <span 
class="java&#45;object">Class</span>&#60;?&#62; arg1) &#123;
+               <span class="java&#45;keyword">return</span> <span 
class="java&#45;keyword">null</span>;
+       &#125;
+&#125;</pre></div>
+
+
+<h2 id="advanced_6">17.6 Summary</h2>
+<p class="paragraph"/>In this chapter we have introduced some advanced topics 
we didn't have the chance to cover yet. We have started talking about behaviors 
and we have seen how they can be used to enrich existing components (promoting 
a component-oriented approach). Behaviors are also fundamental to work with 
AJAX in Wicket, as we will see in the next chapter.<p class="paragraph"/>After 
behaviors we have learnt how to generate callback URLs to execute a custom 
method on server side defined inside a specific callback interface.<p 
class="paragraph"/>The third topic of the chapter has been the event 
infrastructure provided in Wicket for inter-component communication which 
brings to our components a desktop-like event-driven architecture.<p 
class="paragraph"/>Then, we have introduced a new entity called initializer 
which can be used to configure resources and component in a modular and 
self-contained way.<p class="paragraph"/>We have also looked at Wicket support 
for JMX and we have s
 een how to use this technology for monitoring and managing our running 
applications.<p class="paragraph"/>Finally we have introduced a new technique 
to generate the markup of a component from its Java code.<p 
class="paragraph"/><p class="paragraph"/>
+
+
+
+                <div style="clear:both;margin-top:15px;"></div>
+                
+                    <div class="toc-item prev-left"><a 
href="../guide/jsintegration.html">&lt;&lt; <strong>16</strong><span>An example 
of integration with JavaScript</span></a></div>
+                
+                    <div class="toc-item next-right"><a 
href="../guide/ajax.html"><strong>18</strong><span>Working with AJAX</span> 
>></a></div>
+                
+                <div style="clear:both"></div>
+            </div>
+        </td>
+        <td id="col2">
+            <div class="local clearfix">
+                <div class="local-title">
+                    <a href="../guide/index.html" target="mainFrame">Quick 
Reference</a>
+                    <span class="toggle">(<a href="#" onclick="localToggle(); 
return false;">hide</a>)</span>
+                </div>
+                <div class="menu">
+                    
+                </div>
+            </div>
+        </td>
+    </tr>
+</table>
+
+<div id="footer">
+    
+Copyright &copy; 2013-2014 — <a href="http://www.apache.org/"; 
target="_blank">The Apache Software Foundation</a> 
+                      — <b style="color:#E8590A !important;">(Generated on: 
2014-01-28)</b>
+
+    
+</div>
+
+<script type="text/javascript" src="../js/docs.js"></script>
+
+</body>
+</html>


Reply via email to