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

<channel>
	<title>Molindo Techblog &#187; Wicket</title>
	<atom:link href="http://techblog.molindo.at/category/java/wicket/feed" rel="self" type="application/rss+xml" />
	<link>http://techblog.molindo.at</link>
	<description>Molindo Techblog - formerly known as talk-on-tech.blogspot.com</description>
	<lastBuildDate>Fri, 05 Feb 2010 16:06:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>wicketstuff-merged-resources: 2.1 and 3.0 released!</title>
		<link>http://techblog.molindo.at/2010/02/wicketstuff-merged-resources-2-1-and-3-0-released.html</link>
		<comments>http://techblog.molindo.at/2010/02/wicketstuff-merged-resources-2-1-and-3-0-released.html#comments</comments>
		<pubDate>Fri, 05 Feb 2010 13:57:34 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[wicketstuff-merged-resources]]></category>

		<guid isPermaLink="false">http://techblog.molindo.at/?p=172</guid>
		<description><![CDATA[I&#8217;m happy to announce the releases of wicketstuff-merged-resources 2.1 and 3.0.
Changes from 2.0 to 2.1 (Wicket 1.3.x):

Annotation-based Mounting of Resources
[WMR-7] Failure to load resources if this library is provided in a parent classloader
[WMR-9] Make it possible to define some sort of order in the way files are included in the overall file
[WMR-10] wicketstuff-merged-resources does not [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce the releases of <a href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-merged-resources" target="_blank">wicketstuff-merged-resources</a> 2.1 and 3.0.</p>
<p><span id="more-172"></span><strong>Changes from 2.0 to 2.1 (Wicket 1.3.x):</strong></p>
<ul>
<li><a href="http://techblog.molindo.at/2009/10/wicket-annotation-based-mounting-of-resources.html">Annotation-based Mounting of Resources</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-7" target="_blank">[WMR-7] Failure to load resources if this library is provided in a parent classloader</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-9" target="_blank">[WMR-9] Make it possible to define some sort of order in the way files are included in the overall file</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-10" target="_blank">[WMR-10] wicketstuff-merged-resources does not compile; missing jetty plugin artifact</a></li>
<li>and a few minor bug fixes and performance improvements: <a href="http://fisheye3.atlassian.com/changelog/~branchConstraint=wicket-1.3.x,startDate=2009-08-24T00:00:00,endDate=2010-02-02T23:59:59/wicket-stuff/branches/wicket-1.3.x/wicketstuff-merged-resources" target="_blank">See full FishEye Activity report</a></li>
</ul>
<p>(Note: <a href="http://wicketstuff.org/jira/browse/WMR-12" target="_blank">[WMR-12]</a> and <a href="http://wicketstuff.org/jira/browse/WMR-14" target="_blank">[WMR-14]</a> already went into <a href="http://wicketstuff.org/maven/repository/org/wicketstuff/wicketstuff-merged-resources/2.2-SNAPSHOT/" target="_blank">2.2-SNAPSHOT</a>)</p>
<p><strong>Changes for 3.0 (Wicket 1.4.x):</strong></p>
<ul>
<li><a href="http://techblog.molindo.at/2009/10/wicket-annotation-based-mounting-of-resources.html">Annotation-based Mounting of Resources</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-6" target="_blank">[WMR-6] Compatibility to wicket 1.4</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-7" target="_blank">[WMR-7] Failure to load resources if this library is provided in a parent classloader</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-7" target="_blank"></a><a href="http://wicketstuff.org/jira/browse/WMR-9">[WMR-9] Make it possible to define some sort of order in the way files are included in the overall file</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-9" target="_blank"></a><a href="http://wicketstuff.org/jira/browse/WMR-10">[WMR-10] wicketstuff-merged-resources does not compile; missing jetty plugin artifact</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-12" target="_blank">[WMR-12] Allow CSS media to be specified in ResourceMount, and honored by build()</a></li>
<li><a href="http://wicketstuff.org/jira/browse/WMR-14" target="_blank">[WMR-14] Error detection for adding CSS and JavaScript resources to ResourceMount</a></li>
<li>and a few minor bug fixes and performance improvements: <a href="http://fisheye3.atlassian.com/changelog/~branchConstraint=trunk,startDate=2009-08-06T00:00:00,endDate=2010-02-05T23:59:59/wicket-stuff/trunk/wicketstuff-merged-resources" target="_blank">See full FishEye Activity report</a></li>
</ul>
<p><strong>Downloads:</strong></p>
<ul>
<li>wicketstuff-merged-resources 2.1: <a href="http://wicketstuff.org/maven/repository/org/wicketstuff/wicketstuff-merged-resources/2.1/wicketstuff-merged-resources-2.1.jar" target="_blank">Jar</a> <a href="http://wicketstuff.org/maven/repository/org/wicketstuff/wicketstuff-merged-resources/2.1/wicketstuff-merged-resources-2.1-sources.jar" target="_blank">Sources</a></li>
<li>wicketstuff-merged-resources 3.0: <a href="http://wicketstuff.org/maven/repository/org/wicketstuff/wicketstuff-merged-resources/3.0/wicketstuff-merged-resources-3.0.jar" target="_blank">Jar</a> <a href="http://wicketstuff.org/maven/repository/org/wicketstuff/wicketstuff-merged-resources/3.0/wicketstuff-merged-resources-3.0-sources.jar" target="_blank">Sources</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2010/02/wicketstuff-merged-resources-2-1-and-3-0-released.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wicket: Annotation-based Mounting of Resources</title>
		<link>http://techblog.molindo.at/2009/10/wicket-annotation-based-mounting-of-resources.html</link>
		<comments>http://techblog.molindo.at/2009/10/wicket-annotation-based-mounting-of-resources.html#comments</comments>
		<pubDate>Tue, 13 Oct 2009 12:05:48 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[wicketstuff-merged-resources]]></category>

		<guid isPermaLink="false">http://techblog.molindo.at/?p=128</guid>
		<description><![CDATA[Today, I&#8217;m happy to announce the availability of annotation-based mounting and merging of resources in wicketstuff-merged-resources (version 3.0-SNAPSHOT for Wicket 1.4, version 2.1-SNAPSHOT for Wicket 1.3). In order to mount resources, all that&#8217;s needed is adding annotations to component classes:

@JsContribution
@CssContribution&#40;media = &#34;print&#34;&#41;
@ResourceContribution&#40;value = &#34;accept.png&#34;, path = &#34;/img/accept.png&#34;&#41;
public class PanelOne extends Panel &#123;
&#160;
    public PanelOne&#40;String id&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I&#8217;m happy to announce the availability of annotation-based mounting and merging of resources in <a title="Wicketstuff Wiki: wicketstuff-merged-resources" href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-merged-resources" target="_blank">wicketstuff-merged-resources</a> (version 3.0-SNAPSHOT for Wicket 1.4, version 2.1-SNAPSHOT for Wicket 1.3). In order to mount resources, all that&#8217;s needed is adding annotations to component classes:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@JsContribution
@CssContribution<span style="color: #009900;">&#40;</span>media <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;print&quot;</span><span style="color: #009900;">&#41;</span>
@ResourceContribution<span style="color: #009900;">&#40;</span>value <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;accept.png&quot;</span>, path <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/img/accept.png&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PanelOne <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Panel</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> PanelOne<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span id="more-128"></span><br />
The example above mounts and merges PanelOne.js (default is simple name of class + &#8220;.js&#8221;) into all.js (another default) and PanelOne-print.css into print.css which will be included with scope print. Additionally, accept.png will be mounted to /img/accept.png (as path starts with a &#8216;/&#8217;) which makes it easy to use from css files.</p>
<p>There&#8217;s not much left for this to work. All it takes is a single method call in your Application&#8217;s init code:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">ResourceMount.<span style="color: #006633;">mountAnnotatedPackageResources</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/files&quot;</span>, <span style="color: #0000ff;">&quot;com.example.components&quot;</span>, <span style="color: #000000; font-weight: bold;">this</span>, mount<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In this example, all components in package com.example.components (including sub-packages) will be scanned for annotations. If not defined otherwise, all resources will be merged into  single files for JS (/files/all.js) and all CSS media types (/files/all.css, /files/screen.css, /files/print.css, &#8230;).</p>
<p>As an added benefit, you&#8217;ll get all the other features of wicketstuff-merged-resources:</p>
<ul>
<li>merging of multiple files into one for less HTTP requests</li>
<li>adding of versions to resource paths for aggressive caching</li>
<li>pre-processing of resources (e.g. replacing colors in CSS files)</li>
<li>optionally uploading them to Amazon Cloudfront (well, at least you can expect this feature soon &#8211; <a title="setlist.fm - the setlist wiki" href="http://www.setlist.fm/" target="_blank">we are using it already</a>)</li>
</ul>
<p>So you will <a title="Molindo Techblog: Wicket Interface Speed-Up" href="/2008/08/wicket-interface-speed-up.html" target="_blank">speed up rendering of your pages</a> while simplifying and reducing your code (there&#8217;s no need to merge, mount or add HeaderContributors manually anymore)!</p>
<p><a title="wicketstuff-merged-resources on Wicket Stuff Wiki" href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-merged-resources" target="_blank">Further instructions are available on wicketstfuff-merged-resources&#8217; page on Wicket Stuff Wiki</a>.</p>
<p><small>(This new feature is mainly based on the idea and code of <a title="Jörn Zaefferer's profile at LinkedIn" href="http://www.linkedin.com/in/joernzaefferer" target="_blank">Jörn Zaefferer</a> &#8211; Tanks!)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2009/10/wicket-annotation-based-mounting-of-resources.html/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>wicketstuff-merged-resources: New (much simpler) Version</title>
		<link>http://techblog.molindo.at/2009/09/wicketstuff-merged-resources-new-much-simpler-version.html</link>
		<comments>http://techblog.molindo.at/2009/09/wicketstuff-merged-resources-new-much-simpler-version.html#comments</comments>
		<pubDate>Thu, 24 Sep 2009 19:17:56 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[wicketstuff-merged-resources]]></category>

		<guid isPermaLink="false">http://techblog.molindo.at/?p=113</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve last posted here. Nevertheless, I&#8217;ve been busy working on some (yet to be released) Open Source projects. Others are already released but not documented/promoted yet. One of these unpromoted releases is the new version of wicketstuff-merged-resources.  wicketstuff-merged-resources was the result of my &#8220;Wicket Interface Speed-up&#8221; series where I investigate [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve last posted here. Nevertheless, I&#8217;ve been busy working on some (yet to be released) Open Source projects. Others are <a title="groovy-mb-mysql - Groovy port of MB_MySQL - the &quot;MusicBrainz Database for MySQL&quot;" href="http://code.google.com/p/groovy-mb-mysql/" target="_blank">already released but not documented/promoted yet</a>. One of these unpromoted releases is the <a title="wicketstuff-merged-resources - a set of simple helper classes to improve Wicket interface loading performance" href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-merged-resources" target="_blank">new version of wicketstuff-merged-resources</a>.  wicketstuff-merged-resources was the result of my <a href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up.html">&#8220;Wicket Interface Speed-up&#8221; series</a> where I investigate how to reduce time spent rendering Wicket pages on the client side. wicketstuff-merged-resources has two main purposes: reducing the number of HTTP requests by merging resources (i.e. JS and CSS files) and enabling aggressive caching (up to a year) by adding a version number to mounted resources (e.g. /css/all-42.css instead of /css/all.css). While wicket has the <a title="IResourceSettings#getAddLastModifiedTimeToResourceReferenceUrl()" href="http://wicket.apache.org/docs/1.4/org/apache/wicket/settings/IResourceSettings.html#getAddLastModifiedTimeToResourceReferenceUrl()" target="_blank">option to add a timestamp</a> to references (something like /css/all.css?t=20090924), <a href="http://developer.yahoo.com/performance/rules.html#expires" target="_blank">adding the version to the name is preferred</a> over adding a query string. This said, let&#8217;s see how to use wicketstuff-merged-resources&#8217; new version.<span id="more-113"></span></p>
<p>The main class now is <a title="SVN: ResourceMount.java" href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources/src/main/java/org/wicketstuff/mergedresources/ResourceMount.java" target="_blank">ResourceMount</a> which replaces the deprecated <a title="SVN: ResourceMountHelper.java" href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/branches/wicket-1.3.x/wicketstuff-merged-resources/src/main/java/org/wicketstuff/mergedresources/ResourceMountHelper.java" target="_blank">ResourceMountHelper (already removed in trunk version)</a>. Mounting is now much simpler. Just see this example:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">ResourceMount mount <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ResourceMount<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
.<span style="color: #006633;">setResourceVersionProvider</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> RevisionVersionProvider<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
.<span style="color: #006633;">setPath</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/style/all.css&quot;</span><span style="color: #009900;">&#41;</span>
.<span style="color: #006633;">addResourceSpecsMatchingSuffix</span><span style="color: #009900;">&#40;</span>PanelOne.<span style="color: #000000; font-weight: bold;">class</span>, ComponentB.<span style="color: #000000; font-weight: bold;">class</span>, MyForm.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
.<span style="color: #006633;">mount</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Note that you still use the resources as you are used to, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">add<span style="color: #009900;">&#40;</span>HeaderContributor.<span style="color: #006633;">forCss</span><span style="color: #009900;">&#40;</span>MyForm.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;MyForm.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add<span style="color: #009900;">&#40;</span>HeaderContributor.<span style="color: #006633;">forJavaScript</span><span style="color: #009900;">&#40;</span>MyForm.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;MyForm.js&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This example simply mounts PanelOne.css, ComponentB.css and MyForm.css into a single file at /style/all.css (the suffix &#8220;.css&#8221; is determined from the path &#8211; &#8220;/style/all.js&#8221; would mount all &#8220;.js&#8221; files). Additionally, the <a title="SVN: RevisionVersionProvider.java" href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources/src/main/java/org/wicketstuff/mergedresources/versioning/RevisionVersionProvider.java">RevisionVersionProvider</a> is used to determine which version to append (you may implement your own <a title="SVN: IResourceVersionProvider.java" href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources/src/main/java/org/wicketstuff/mergedresources/versioning/IResourceVersionProvider.java" target="_blank">IResourceVersionProvider</a> that best fits your environment). For example, the merged file may be mounted at /style/all-42.css (while still being available at /style/all.css through a permanent redirect).</p>
<p>While ResourceMount tries to autodetect most properties of the merged resource (e.g. style, locale, compression) it comes with a ton of customization options. For instance, it&#8217;s possible to use a custom <a title="JavaDoc: IRequestTargetUrlCodingStrategy" href="http://wicket.apache.org/docs/1.4/org/apache/wicket/request/target/coding/IRequestTargetUrlCodingStrategy.html" target="_blank">IRequestTargetUrlCodingStrategy</a>. Doesn&#8217;t that sound interesting to you? Well, we used this option to upload all resources to <a title="Amazon S3" href="https://s3.amazonaws.com/" target="_blank">Amazon Simple Storage Service</a>/<a title="Amazon CloudFront" href="http://aws.amazon.com/cloudfront/" target="_blank">CloudFront</a> in order to transparently leverage Amazon&#8217;s <a title="Wikipedia: Content Delivery Network" href="http://en.wikipedia.org/wiki/Content_delivery_network" target="_blank">CDN</a> by simply mounting them in <a title="Setlist.fm - A Molindo Wicket Application" href="http://www.setlist.fm/" target="_blank">our applications</a> (Isn&#8217;t that awesome? Stay tuned for another blog post. Donating might speed things up though).</p>
<p><a title="Jörn Zäfferer's Blog" href="http://bassistance.de/" target="_blank">Jörn Zaefferer</a> suggested adding <a title="Wicketstuff Wiki: wicketstuff-annotations" href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-annotation" target="_blank">wicketstuff-annotations</a>-like mounting of (merged) resources using <a title="Java language guide: Annotations" href="http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html" target="_blank">annotations</a>, which will hopefully be added in a later version. In the meantime, I may provide Jörn&#8217;s solution for those interested (Jörn, you don&#8217;t mind, do you?) &#8211; just leave a message.</p>
<p>Additional feature include CSS compression using <a title="YUI Compressor" href="http://developer.yahoo.com/yui/compressor/" target="_blank">Yahoo&#8217;s YUI Compressor</a> and resource preprocessing. The later is particularly interesting, as you might implement things like replacing colors in CSS files or add internationalization from .properties files to JS files &#8211; just implement the <a title="SVN: IResourcePreProcessor" href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources/src/main/java/org/wicketstuff/mergedresources/preprocess/IResourcePreProcessor.java" target="_blank">IResourcePreProcessor</a> interface (or use <a title="SVN: StringResourcePreProcessor" href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources/src/main/java/org/wicketstuff/mergedresources/preprocess/StringResourcePreProcessor.java" target="_blank">StringResourcePreProcessor</a> if your only dealing with Strings).</p>
<p>I think I&#8217;ve mentioned the most important features now. Just <a title="WicketStuff Wiki: wicketstuff-merged-resources" href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-merged-resources" target="_blank">see wicketstuff-merged-resources in WicketStuff&#8217;s Wiki for more (and possibly up-to-date) documentation</a>. If you have any questions, don&#8217;t hesitate to post a comment! It you&#8217;re grateful, don&#8217;t hesitate to donate! <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="2705854">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif" border="0" name="submit" alt="">
<img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
</form></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2009/09/wicketstuff-merged-resources-new-much-simpler-version.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Detaching and Attaching Persistent Objects on Serialization</title>
		<link>http://techblog.molindo.at/2009/03/detaching-and-attaching-persistent-objects-on-serialization.html</link>
		<comments>http://techblog.molindo.at/2009/03/detaching-and-attaching-persistent-objects-on-serialization.html#comments</comments>
		<pubDate>Wed, 25 Mar 2009 15:52:05 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://techblog.molindo.at/?p=100</guid>
		<description><![CDATA[Today I&#8217;ve received a mail by someone interested in a serialization mechanism I described some days ago. This mechanism was implemented to avoid dealing with detached Hibernate objects in different HTTP (i.e. Wicket) requests (it&#8217;s not restricted to Hibernate though). The idea is quite simple: detach objects if they are persistent, serialize them if they [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ve received a mail by someone interested in <a href="http://stronglytypedblog.blogspot.com/2009/03/wicket-patterns-and-pitfalls-1.html?showComment=1236931620000#c7920901088559233703">a serialization mechanism I described some days ago</a>. This mechanism was implemented to avoid dealing with detached Hibernate objects in different HTTP (i.e. Wicket) requests (it&#8217;s not restricted to Hibernate though). The idea is quite simple: detach objects if they are persistent, serialize them if they are transient, deserialize and attach for the next request &#8211; all transparently. So far, this isn&#8217;t very special and doesn&#8217;t justify such a complicated approach. However, it&#8217;s the only way of attaching and detaching object graphs that consist of transient <strong>and</strong> persistent objects I know.<br />
<span id="more-100"></span>The mechanism uses the magic serialization hooks readResolve() and writeReplace() (<a href="http://www.jguru.com/faq/view.jsp?EID=44039">see jGuru</a>). Knowing these hooks (yeah, knowing &#8230; as it is probably harder to know them than to actually use them), the rest is quite easy. Replace persistent object with a placeholder but serialize regular objects:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> writeReplace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ObjectStreamException</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isTransient<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ReplaceHolder<span style="color: #009900;">&#40;</span>getClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The ReplaceHolder &#8211; isn&#8217;t it a lovely name? &#8211; is responsible for replacing itself with the persistent object we didn&#8217;t want to serialize before:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">class</span> ReplaceHolder <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> _entityName<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Serializable</span> _id<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> ReplaceHolder<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">Class</span> entity, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Serializable</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    _entityName <span style="color: #339933;">=</span> entity.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    _id <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Serializable</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> _id<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @SuppressWarnings<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;unchecked&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">Class</span> getEntity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassNotFoundException</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">Class</span>.<span style="color: #006633;">forName</span><span style="color: #009900;">&#40;</span>_entityName<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> readResolve<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ObjectStreamException</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> loadEntity<span style="color: #009900;">&#40;</span>getEntity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">ClassNotFoundException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">InvalidClassException</span><span style="color: #009900;">&#40;</span>_entityName, e.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSimpleName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;: &quot;</span> <span style="color: #339933;">+</span> e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And that&#8217;s it. Well, not completely, but <a title="AbstractPersistentObject.java" href="http://techblog.molindo.at/files/AbstractPersistentObject.java">see the attached .java file</a> for details.</p>
<p>There is only one thing Wicket developers have to be aware of. Objects aren&#8217;t serialized between requests &#8211; don&#8217;t confuse it with model detaching. If I remember correctly, there is always one page kept detached but un-serialized. So if one would like to use the serialization, one has to make sure, that the objects are already serialized as soon as the models are detached. For this purpose, I implemented <a title="SerializingModel.java" href="http://techblog.molindo.at/files/SerializingModel.java">a special Model, that serializes its object on detach</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> detach<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>_object <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">ByteArrayOutputStream</span> bs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectOutputStream</span><span style="color: #009900;">&#40;</span>bs<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">writeObject</span><span style="color: #009900;">&#40;</span>_object<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      _bytes <span style="color: #339933;">=</span> bs.<span style="color: #006633;">toByteArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      _object <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> WicketRuntimeException<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You might say that this feels like a hack &#8211; at least that&#8217;s what I think of it <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But it works perfectly, especially for complex forms where you add persistent objects to transient ones. Furthermore, you make sure that you&#8217;ll never serialize a huge persistent object graph into your Wicket session, which definetely is a Bad Thing &#8482;.</p>
<p>EDIT: This blogger is thirsty! Please buy him a beer: <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="2705854">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif" border="0" name="submit" alt="">
<img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
</form></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2009/03/detaching-and-attaching-persistent-objects-on-serialization.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Talk On Tech now Molindo Techblog</title>
		<link>http://techblog.molindo.at/2009/01/talk-on-tech-now-molindo-techblog.html</link>
		<comments>http://techblog.molindo.at/2009/01/talk-on-tech-now-molindo-techblog.html#comments</comments>
		<pubDate>Fri, 23 Jan 2009 10:00:24 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Compass]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/?p=84</guid>
		<description><![CDATA[Talk On Tech (talk-on-tech.blogspot.com &#8211; the tech blog you truly love, don&#8217;t you?) was our nice, green home since August 2007. Now, after 1.5 years it was time to move on &#8230; Well, okay, we just want to consolidate all our blogs on a single self-hosted platform. In the course of doing that, we also [...]]]></description>
			<content:encoded><![CDATA[<p>Talk On Tech (talk-on-tech.blogspot.com &#8211; the tech blog you truly love, don&#8217;t you?) was our nice, green home since August 2007. Now, after 1.5 years it was time to move on &#8230; Well, okay, we just want to<a href="http://tech.molindo.at/2008/12/virtual-wordpress-hosts-made-easy.html"> consolidate all our blogs on a single self-hosted platform</a>. In the course of doing that, we also changed the name from Talk on Tech (Let&#8217;s create a blog! How do we name it? What about &#8220;Talk on Tech&#8221;? Yeah, that name is free!) to Molindo Techblog (where Molindo is the name of <a href="http://www.molindo.at/">our very own startup</a>).</p>
<p>If it comes to new posts, We have a lot of ideas but not enough time to elaborate them all. Some ideas are:<br />
<span id="more-84"></span></p>
<ul>
<li>An easy to use <a title="Wicket" href="http://wicket.apache.org">Wicket</a> component for advanced Google Analytics (Outgoing link tracking, search tracking, AJAX events tracking, user defined variables, &#8230;)</li>
<li>Faster batch indexing for <a title="Compass Project" href="http://compass-project.org/">Compass</a></li>
<li>Managing <a title="Subversion" href="http://subversion.tigris.org/">Subversion</a> user access privileges with <a title="Drupal" href="http://drupal.org/">Drupal</a> &#8211; and probably how to move to Wordpress afterwards <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li>Wicket <a title="Blueprint CSS Framework" href="http://www.blueprintcss.org/">Blueprint</a> integration</li>
<li>How to apply some on-site SEO with a little help of Wicket</li>
<li>Unleashing the full power of Wicket with <a title="Cometd project" href="http://cometdproject.dojotoolkit.org/">Cometd</a> using <a title="wicketstuff-dojo-1.1" href="http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-dojo-1.1">wicketstuff-dojo-1.1</a> and <a title="&quot;Wicket: Loose Coupling of Componens for Ajax Updates&quot; on Molindo Techblog" href="http://tech.molindo.at/2008/09/wicket-loose-coupling-of-componens-for-ajax-updates.html">loose coupling of components</a>.</li>
</ul>
<p>If you particulary like one of the ideas post a wish in the comments &#8211; and think about enforcing your wish with a donation: <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="2705854">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif" border="0" name="submit" alt="">
<img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1">
</form></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2009/01/talk-on-tech-now-molindo-techblog.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wicket: A Neat Url Encoding Strategy and some basic SEO</title>
		<link>http://techblog.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html</link>
		<comments>http://techblog.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html#comments</comments>
		<pubDate>Tue, 09 Dec 2008 09:03:00 +0000</pubDate>
		<dc:creator>Michael Sparer</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html</guid>
		<description><![CDATA[After a year of working extensively with Apache Wicket I want to share some stuff I&#8217;ve been using over and over again and might be useful for you as well. In this first post it&#8217;s a custom URL Encoding Strategy and some related basic SEO.
Pages often depend on entities &#8211; e.g. a Customer or a [...]]]></description>
			<content:encoded><![CDATA[<p>After a year of working extensively with <a href="http://wicket.apache.org">Apache Wicket</a> I want to share some stuff I&#8217;ve been using over and over again and might be useful for you as well. In this first post it&#8217;s a custom URL Encoding Strategy and some related basic SEO.</p>
<p>Pages often depend on entities &#8211; e.g. a Customer or a product and as those pages should be bookmarkable as well, there has to be a unique way to tell the page which entity to use. As entities either don&#8217;t have unique names or one wants to avoid having an (database) index over the name column, the index-ID is for most applications the way to go. As it&#8217;s usually undesireable to expose the database ID of an entity in the URL, it has to be encoded and decoded somehow to get from myshop.com/customer/12 to myshop.com/customer/ea34cff &#8230; or something like that.<br />
<span id="more-31"></span><br />
Using a custom Url-mounting strategy makes it a breeze:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> IndexedIdEncryptingUrlCodingStrategy <span style="color: #000000; font-weight: bold;">extends</span> LowercaseOnlyIndexedUrlEncodingStrategy <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> _encryptedParams<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// serverroot is e.g. http://www.mypage.com - required for 301 redirects in baseclass</span>
<span style="color: #000000; font-weight: bold;">public</span> IndexedIdEncryptingUrlCodingStrategy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> mountPath, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> serverRoot, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">Class</span> bookmarkablePageClass, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span>... <span style="color: #006633;">encryptedParmas</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>mountPath, serverRoot, bookmarkablePageClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_encryptedParams <span style="color: #339933;">=</span> encryptedParmas<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> IndexedIdEncryptingUrlCodingStrategy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> mountPath, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> serverRoot, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">Class</span> bookmarkablePageClass, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> pageMapName, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span>... <span style="color: #006633;">encryptedParmas</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>mountPath, serverRoot, bookmarkablePageClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_encryptedParams <span style="color: #339933;">=</span> encryptedParmas<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@SuppressWarnings<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;unchecked&quot;</span><span style="color: #009900;">&#41;</span>
@Override
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> appendParameters<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> AppendingStringBuffer url, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Map</span> params<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">:</span> _encryptedParams<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> indexStr <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span>index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> val <span style="color: #339933;">=</span> params.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>indexStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> val <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
params.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>indexStr, encodeId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span><span style="color: #009900;">&#41;</span> val<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">appendParameters</span><span style="color: #009900;">&#40;</span>url, params<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@Override
<span style="color: #000000; font-weight: bold;">protected</span> ValueMap onDecodeParameters<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> urlFragment, <span style="color: #000000; font-weight: bold;">final</span> ValueMap urlParameters<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">:</span> _encryptedParams<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> indexStr <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span>index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> val <span style="color: #339933;">=</span> urlParameters.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>indexStr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>val <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> val <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
urlParameters.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>indexStr, decodeId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> val<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">return</span> urlParameters<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getEncryptedParams<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">return</span> _encryptedParams<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #003399;">String</span> encodeId<span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span> val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #003399;">Integer</span> decodeId<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This class&#8217;s baseclass is used for SEO only: it just checks if there are only lowercase letters in the URL and does a 301 redirect to the lowercase variant of the page if not.<br />
Why lowercase only: The first of the Ten SEO Commandments (if there was such a thing) is: &#8220;<span style="font-weight:bold;">Thou shalt only have one URL per page</span>&#8221; &#8211; and for bots <span style="font-style:italic;">http://www.myshop.com/customer/Foobar</span> and <span style="font-style:italic;">http://www.myshop.com/customer/fOoBar</span> are two different URLs &#8211; which is a bad thing as far as duplicate content is concerned. Well, it could also be uppercase only or camelcase only &#8211; but lowercase makes it easier to read for humans and is also easier to implement than camelcase.</p>
<p>Then just mount the page like that:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">mount<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> IndexedIdEncryptingUrlCodingStrategy<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/customer&quot;</span>, <span style="color: #0000ff;">&quot;http://www.mypage.com&quot;</span>, HomePage.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>and construct the page params like that:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">final</span> PageParameters params <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PageParameters<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
params.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span>, myEntity.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// add e.g. a link</span>
add<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> BookmarkablePageLink<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;link&quot;</span>, HomePage.<span style="color: #000000; font-weight: bold;">class</span>, params<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Download the files:<br />
<a href="http://molindo.at/files/msp/IndexedIdEncryptingUrlCodingStrategy.java">IndexedIdEncryptingUrlCodingStrategy.java</a><br />
<a href="http://molindo.at/files/msp/LowercaseOnlyIndexedUrlEncodingStrategy.java">LowercaseOnlyIndexedUrlEncodingStrategy.java</a></p>
<p>In my next post I&#8217;ll get a bit more into Wicket &amp; SEO: Show a more SEO way to encode URLs, how to deal with the JSESSIONID and how to apply the code shown today on a Page. Stay tuned &#8211; and consider subscribing</p>
<p>PS: If &#8220;thou convet my code&#8221;: the code is public domain, feel free to do whatever you like to do with it. If you have any suggestions or implement enhancements, just post them in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2008/12/wicket-a-neat-url-encoding-strategy-and-some-basic-seo.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wicket: Loose Coupling of Componens for Ajax Updates</title>
		<link>http://techblog.molindo.at/2008/09/wicket-loose-coupling-of-componens-for-ajax-updates.html</link>
		<comments>http://techblog.molindo.at/2008/09/wicket-loose-coupling-of-componens-for-ajax-updates.html#comments</comments>
		<pubDate>Sat, 13 Sep 2008 10:37:00 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/2008/09/wicket-loose-coupling-of-componens-for-ajax-updates.html</guid>
		<description><![CDATA[While developing Wicket applications, one often has to write a simple input form (e.g. a search box) that updates the content of another panel (e.g. a search result panel). And of course, we all use Wicket&#8217;s AJAX support to search as it is so damn cool and easy to use.
Normally, you do this by either [...]]]></description>
			<content:encoded><![CDATA[<p>While developing <a href="http://wicket.apache.org/">Wicket</a> applications, one often has to write a simple input form (e.g. a search box) that updates the content of another panel (e.g. a search result panel). And of course, we all use Wicket&#8217;s AJAX support to search as it is so damn cool and easy to use.</p>
<p>Normally, you do this by either putting everything on one panel or by passing a reference of the list panel to the form panel.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> SearchBoxPanel<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id, SearchResultPanel results<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
_results <span style="color: #339933;">=</span> results<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// snip</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onSubmit<span style="color: #009900;">&#40;</span>AjaxRequestTarget target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
_results.<span style="color: #006633;">setQuery</span><span style="color: #009900;">&#40;</span>getQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// or use the same model ;)</span>
target.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>_results<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span id="more-27"></span><br />
Now, we would like to add a nice and shiny &#8220;Did you mean&#8221; panel to our search page. So what can we do? We could add another reference to the search box panel by refactoring it. However, nobody likes refactoring existing components over and over again. One would rather like to write components flexible enough from the beginning. Here, the observer pattern &#8211; or loose coupling &#8211; <a href="http://www.songtexte.com/songtext/tenacious-d/tribute-4bdb1fb2.html">comes in handy, my hard-rocking amigos</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> SearchPage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
_search <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SearchBoxPanel<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;search&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_didYouMean <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DidYouMeanPanel<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;didYouMean&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_results <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SearchResultsPanel<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;results&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_search.<span style="color: #006633;">addObserver</span><span style="color: #009900;">&#40;</span>_didYouMean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
_search.<span style="color: #006633;">addObserver</span><span style="color: #009900;">&#40;</span>_results<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// snip</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// SearchBoxPanel class</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> addObserver<span style="color: #009900;">&#40;</span>IAjaxObserver observer<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
_observers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>observer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onSubmit<span style="color: #009900;">&#40;</span>AjaxRequestTarget target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">// snip</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>IAjaxObserver observer <span style="color: #339933;">:</span> _observers<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
observer.<span style="color: #006633;">notifyAjaxUpdate</span><span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>But let&#8217;s take this a step further. Wouldn&#8217;t it be cool, if simply adding a new component to the page would be sufficient? Yeah, just adding it, no magic or voodoo involved. It really can be that easy! One just has to realize that all components are already connected through the page. Dispatching events to all children of a page can therefore be as simple as visiting all components of a page:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> AjaxUpdateEvent <span style="color: #000000; font-weight: bold;">implements</span> IClusterable <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Component</span> _source<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> AjaxRequestTarget _target<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> AjaxUpdateEvent<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Component</span> source,
<span style="color: #000000; font-weight: bold;">final</span> AjaxRequestTarget target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
_source <span style="color: #339933;">=</span> source<span style="color: #339933;">;</span>
_target <span style="color: #339933;">=</span> target<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Component</span> getSource<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">return</span> _source<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> AjaxRequestTarget getTarget<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">return</span> _target<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">void</span> fire<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
getSource<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">visitChildren</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> NotifyVisitor<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">interface</span> IAjaxUpdateListener <span style="color: #000000; font-weight: bold;">extends</span> IClusterable <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> notifyAjaxUpdate<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> AjaxUpdateEvent event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">class</span> NotifyVisitor <span style="color: #000000; font-weight: bold;">implements</span> IVisitor <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> AjaxUpdateEvent _event<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> NotifyVisitor<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> AjaxUpdateEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
_event <span style="color: #339933;">=</span> event<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> component<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Component</span> component<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>component <span style="color: #000000; font-weight: bold;">instanceof</span> IAjaxUpdateListener<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>IAjaxUpdateListener<span style="color: #009900;">&#41;</span> component<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">notifyAjaxUpdate</span><span style="color: #009900;">&#40;</span>_event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">return</span> IVisitor.<span style="color: #006633;">CONTINUE_TRAVERSAL</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now, all you have to do in your SearchBoxPanel is this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onSubmit<span style="color: #009900;">&#40;</span>AjaxRequestTarget target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">// snip</span>
<span style="color: #000000; font-weight: bold;">new</span> SearchEvent<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, target<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">fire</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Your &#8220;Did you mean&#8221; panel could look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DidYouMeanPanel <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">Panel</span> <span style="color: #000000; font-weight: bold;">implements</span> IAjaxUpdateListeners <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> notifyAjaxUpdateListeners<span style="color: #009900;">&#40;</span>AjaxUpdateEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>event <span style="color: #000000; font-weight: bold;">instanceof</span> SearchEvent<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
setModel<span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getSource</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getModel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
event.<span style="color: #006633;">getTarget</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">addComponent</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Simple, isn&#8217;t it? I&#8217;m currently playing around with some ideas on using this event mechanism together with <a href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-push/">wicketstuff-push</a> (or rather the <a href="http://www.nabble.com/New-wicketstuff-dojo-project-to19070145.html">upcoming release of wicketstuff-dojo-1.1</a> with integrated wicketstuff-push powers &#8211; Should be out this or next week. I&#8217;m working on it, I swear!). This could be a really powerful and easy to use programming model for cometd-based applications.</p>
<p>Now <a href="http://molindo.at/files/wicket-event-demo.tar.gz">download the code</a> and enjoy updating loosely coupled Wicket components <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2008/09/wicket-loose-coupling-of-componens-for-ajax-updates.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Wicket Interface Speed-Up: Merging Resources for Fewer HTTP Requests</title>
		<link>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-merging-resources-for-fewer-http-requests.html</link>
		<comments>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-merging-resources-for-fewer-http-requests.html#comments</comments>
		<pubDate>Thu, 28 Aug 2008 09:15:00 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/2008/08/wicket-interface-speed-up-merging-resources-for-fewer-http-requests.html</guid>
		<description><![CDATA[This entry is part of my &#8220;Wicket Interface Speed-Up&#8221; series.
Now that I spent some time on configuring client-side caching and resource versioning for aggressive caching, I am going to finalize this series with an article on merging of resources and some code that you can easily use right away to speed-up your own applications in [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-style: italic;">This entry is part of my &#8220;<a href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up.html">Wicket Interface Speed-Up</a>&#8221; series.</span></p>
<p>Now that I spent some time on <a href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up-modifying.html">configuring client-side caching</a> and <a href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up-caching.html">resource versioning for aggressive caching</a>, I am going to finalize this series with an article on merging of resources and some code that you can easily use right away to speed-up your own applications in minutes.<br />
<span id="more-26"></span><br />
Merging several (e.g JS) files into a single, monolithic file is an efficient way of reducing the number of HTTP requests. In theory it&#8217;s quite simple: just copy and paste all files together and you&#8217;re done. But no, sorry, it&#8217;s not that easy. If you do so, you&#8217;ll run in a bunch of new problems:</p>
<ul>
<li>Resources won&#8217;t live next to their owning components, therefore</li>
<li>Existing HeaderContributor.forCss(&#8230;) and .forJs(..) will stop working</li>
<li>Any component will come with that big file, which makes reusing components less enjoyable.</li>
</ul>
<p>These are the cons of merging resources &#8211; but the cons you&#8217;ll smile at after reading this tutorial. (If you have other points to add, feel free to use the comment form at the bottom)</p>
<p>It is possible to merge resources without changing the resources themselves and without changing any code of the components they belong to. All it takes is some mount-magic, that will look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
mountMergedSharedResource<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;style&quot;</span>, <span style="color: #0000ff;">&quot;all.css&quot;</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>PanelOne.<span style="color: #000000; font-weight: bold;">class</span>, ComponentB.<span style="color: #000000; font-weight: bold;">class</span>, MyForm.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#125;</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;PanelOne.css&quot;</span>, <span style="color: #0000ff;">&quot;ComponentB.css&quot;</span>, <span style="color: #0000ff;">&quot;MyForm.css&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This code will mount a resource at /style/all-[version].css (e.g. /css/all-1234.css) that has all the contents that would normally be at /resources/my.package.PanelOne/PanelOne.css, /resources/another.package.ComponentB/ComponentB.css&#8221; and /resources/yes.another.package.MyForm/MyForm.css.</p>
<p>Of course, the usual way of referencing resources from a component will keep working:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">add<span style="color: #009900;">&#40;</span>HeaderContributor.<span style="color: #006633;">forCss</span><span style="color: #009900;">&#40;</span>PanelOne.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;PanelOne.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add<span style="color: #009900;">&#40;</span>HeaderContributor.<span style="color: #006633;">forCss</span><span style="color: #009900;">&#40;</span>ComponentB.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;ComponentB.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add<span style="color: #009900;">&#40;</span>HeaderContributor.<span style="color: #006633;">forCss</span><span style="color: #009900;">&#40;</span>MyForm.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;MyForm.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Each header contributor will lead to this style sheet reference (of course only one, regardless of the number of added header contributors for those resources):</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/all-1234.css&quot; /&gt;</pre></div></div>

<p>But what happens behind the scenes? I implemented a MergedResourceStream that aggregates the contents of any number of ResourceStreams into a normal Java String, i.e. the contents of all resources will be kept in memory. I implemented four different types of merged resources</p>
<ul>
<li>MergedResource<br />
any file type, will be served uncompressed</li>
<li>CompressedMergedResource<br />
any file type, will be served compressed</li>
<li>CompressedMergedJsResource<br />
JavaScript files, will be served compressed and stripped using Wicket&#8217;s built in JavascriptStripper.stripCommentsAndWhitespace(..)</li>
<li>CompressedMergedCssResource<br />
CSS files, will be served compressed and stripped using <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>.</li>
</ul>
<p>Okay, now here is the code for all my loyal &#8211; aren&#8217;t you? <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  &#8211; readers: <a style="text-decoration: line-through;" href="http://molindo.at/files/merged-resources.tar.gz">merged-resources.tar.gz</a></p>
<p>UPDATE: commited my code to <a href="http://wicketstuff.org/">wicketstuff</a>, get it from SVN: <a href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources/">wicketstuff-merged-resources</a> and <a href="https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-merged-resources-examples/">wicketstuff-merged-resources-examples</a>.</p>
<p>I created two projects. One is called merged-resources and can be added to your project using maven. The second one is called merged-resources-test with two simple test cases and a sample application. To add merged-resources to your project simply add the following to your list of dependencies:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>at.molindo.wicket<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>merged-resources<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.3.4-SNAPSHOT<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>(Unfortunately, there&#8217;s no Maven repository available at the moment, so you&#8217;ll have to build it yourself: `mvn install`)</p>
<p>Here is how to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
IResourceVersionProvider p <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RevisionVersionProvider<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ResourceMountHelper h <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ResourceMountHelper<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, p<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
h.<span style="color: #006633;">mountMergedSharedResource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;style&quot;</span>, <span style="color: #0000ff;">&quot;all.css&quot;</span>, <span style="color: #000066; font-weight: bold;">true</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>PanelOne.<span style="color: #000000; font-weight: bold;">class</span>, ComponentB.<span style="color: #000000; font-weight: bold;">class</span>, MyForm.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#125;</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;PanelOne.css&quot;</span>, <span style="color: #0000ff;">&quot;ComponentB.css&quot;</span>, <span style="color: #0000ff;">&quot;MyForm.css&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
h.<span style="color: #006633;">mountMergedSharedResource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;script&quot;</span>, <span style="color: #0000ff;">&quot;all.js&quot;</span>, <span style="color: #000066; font-weight: bold;">true</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>PanelOne.<span style="color: #000000; font-weight: bold;">class</span>, ComponentB.<span style="color: #000000; font-weight: bold;">class</span>, MyForm.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#125;</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;PanelOne.js&quot;</span>, <span style="color: #0000ff;">&quot;ComponentB.js&quot;</span>, <span style="color: #0000ff;">&quot;MyForm.js&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>By the way, MergedResourceStream uses Wicket&#8217;s ModificationWatcher, so any changes you make at development time will be immediately available without restarting your application.</p>
<p>Have fun and thanks for reading!</p>
<p><span style="font-style:italic;">UPDATE: There is an ongoing discussion on my &#8220;Wicket Interface Speed-Up&#8221; on <a href="http://www.nabble.com/Discussion-on-%22Wicket-Interface-Speed-Up%22-to19197540.html">Wicket&#8217;s mailing list</a>.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-merging-resources-for-fewer-http-requests.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Wicket Interface Speed-Up: Caching Resources Forever</title>
		<link>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-caching-resources-forever.html</link>
		<comments>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-caching-resources-forever.html#comments</comments>
		<pubDate>Wed, 20 Aug 2008 07:24:00 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/2008/08/wicket-interface-speed-up-caching-resources-forever.html</guid>
		<description><![CDATA[This entry is part of my &#8220;Wicket Interface Speed-Up&#8221; series.
In my last post, I explained how to change (i.e. increase) the time a client should cache resources like JavaScript and CSS files served by a Wicket application. In this post, I&#8217;ll show you how to cache resources for a year. Caching for a year is [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-style: italic;">This entry is part of my &#8220;</span><a style="font-style: italic;" href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up.html">Wicket Interface Speed-Up</a><span style="font-style: italic;">&#8221; series.</span></p>
<p>In <a href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up-modifying.html">my last post</a>, I explained how to change (i.e. increase) the time a client should cache resources like JavaScript and CSS files served by a <a href="http://wicket.apache.org/">Wicket</a> application. In this post, I&#8217;ll show you how to cache resources for a year. Caching for a year is close enough to forever and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21">a recommendation by W3C</a>:</p>
<blockquote><p>&#8220;To mark a response as &#8220;never expires,&#8221; an origin server sends an    Expires date approximately one year from the time the response is    sent. HTTP/1.1 servers SHOULD NOT send Expires dates more than one    year in the future.&#8221;</p></blockquote>
<p><span id="more-25"></span><br />
Allowing users to cache resources forever is an efficient way to reduce the number of requests, server load and interface loading time (with a &#8220;primed cache&#8221;). However, aggressive caching comes a long with a major problem: cached versions of resources might be outdated but still valid for a long time. <a href="http://developer.yahoo.com/yslow/">YSlow&#8217;s</a> <a href="http://developer.yahoo.com/performance/rules.html#expires">suggestion</a>:</p>
<blockquote><p>&#8220;Keep in mind, if you use a far future Expires header you have to change the component&#8217;s filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component&#8217;s filename, for example, yahoo_2.0.6.js.&#8221;</p></blockquote>
<p>While I don&#8217;t like the idea to do such stuff at build time, I do back up the idea of using version numbers. I prefer determining the version number of resources at application startup (i.e. before mounting them).</p>
<p>This leads to another question though: How to get a version for each resource? Using your application&#8217;s version (if you have one) might be appropriate but depends on how often you deploy new versions, as a new version will make all cached (i.e. even unchanged) resources obsolete.</p>
<p>As we are deploying new builds quite regularly, I am using <a href="http://subversion.tigris.org/">SVN</a> revision numbers  as resource versions (e.g. all-1234.css instead of all.css). If you now reckon that the revision number isn&#8217;t available at startup, you&#8217;re certainly right &#8230; well, normally it isn&#8217;t. In order to retrieve the revision number at runtime, I introduced a simple header to all my JS and CSS files. This header (a single line) looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* $Revision$ */</span></pre></div></div>

<p>After adding this header to your files, enable the SVN keyword &#8220;Revision&#8221; (<a href="http://svnbook.red-bean.com/en/1.0/ch07s02.html">see &#8220;svn:keywords&#8221; section</a>). After commiting, SVN will expand the above line to</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* $Revision: 1234 $ */</span></pre></div></div>

<p>This line can now easily be parsed with a simple regular expression at startup;</p>
<p>Note: You can also configure SVN to automatically enable SVN keywords (<a href="http://svnbook.red-bean.com/en/1.0/ch07s02.html">see &#8220;Automatic Property Setting&#8221; seciton</a>).</p>
<p>Now that we have a version for our resources, the Application init code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// snip</span>
  mountVersionedResource<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/css/&quot;</span>, CssScope.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;all.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">protected</span> ResourceReference mountVersionedResource<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> prefix,
  <span style="color: #000000; font-weight: bold;">Class</span> scope, <span style="color: #003399;">String</span> path<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #003399;">String</span> unversionedPath <span style="color: #339933;">=</span> prefix <span style="color: #339933;">+</span> path<span style="color: #339933;">;</span>
  <span style="color: #003399;">String</span> versionedPath <span style="color: #339933;">=</span> prefix <span style="color: #339933;">+</span> getVersionedPath<span style="color: #009900;">&#40;</span>scope, path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  ResourceReference ref <span style="color: #339933;">=</span> getResourceRef<span style="color: #009900;">&#40;</span>scope, path<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  mountSharedResource<span style="color: #009900;">&#40;</span>versionedPath, ref.<span style="color: #006633;">getSharedResourceKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// redirect all.css to all-1234.css, just to be safe</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>unversionedPath.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>versionedPath<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    mount<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> RedirectStrategy<span style="color: #009900;">&#40;</span>unversionedPath, WebPage.<span style="color: #000000; font-weight: bold;">class</span>,
      <span style="color: #000066; font-weight: bold;">null</span>, versionedPath<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">return</span> ref<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">class</span> RedirectStrategy
  <span style="color: #000000; font-weight: bold;">extends</span> BookmarkablePageRequestTargetUrlCodingStrategy
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> _redirectPath<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> RedirectStrategy<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> mountPath, <span style="color: #000000; font-weight: bold;">Class</span> pageClass,
    <span style="color: #003399;">String</span> pageMapName, <span style="color: #003399;">String</span> redirectPath<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>mountPath, pageClass, pageMapName<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    _redirectPath <span style="color: #339933;">=</span> redirectPath<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> IRequestTarget decode<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> RequestParameters params<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> RedirectRequestTarget<span style="color: #009900;">&#40;</span>_redirectPath<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #003399;">String</span> getVersionedPath<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span> scope, <span style="color: #003399;">String</span> path<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// snip: removed for simplicity, i'll provide code if desired</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">protected</span> ResourceReference getResourceRef<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span> scope,<span style="color: #003399;">String</span> path<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    ResourceReference ref<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>path.<span style="color: #006633;">endsWith</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.js&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      ref <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ResourceReference<span style="color: #009900;">&#40;</span>scope, path<span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">protected</span> Resource newResource<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
          <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> JavascriptPackageResource<span style="color: #009900;">&#40;</span>scope,path,<span style="color: #000066; font-weight: bold;">null</span>,<span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
          <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">int</span> getCacheDuration<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
              <span style="color: #000000; font-weight: bold;">return</span> CACHE_DURATION<span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
          <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>path.<span style="color: #006633;">endsWith</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// snip: choose appropriate resource references</span>
    <span style="color: #009900;">&#125;</span>
    ref.<span style="color: #006633;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> ref<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Yay, now we have versioned resources that can be cached forever (well, still only for about 20 days, see <a href="https://issues.apache.org/jira/browse/WICKET-1777">WICKET-1777</a>). And yes, you still use the resources as usual:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">public MyPanel<span style="color: #00AA00;">&#40;</span>String id<span style="color: #00AA00;">&#41;</span>
<span style="color: #00AA00;">&#123;</span>
  <span style="color: #993333;">super</span><span style="color: #00AA00;">&#40;</span>id<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
  add<span style="color: #00AA00;">&#40;</span>HeaderContributor.forCss<span style="color: #00AA00;">&#40;</span>CssScope<span style="color: #6666ff;">.class</span><span style="color: #00AA00;">,</span> <span style="color: #ff0000;">&quot;all.css&quot;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
  // snip
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Resulting in</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&nbsp;</pre></div></div>

<p><span style="font-style:italic;">UPDATE: There is an ongoing discussion on my &#8220;Wicket Interface Speed-Up&#8221; on <a href="http://www.nabble.com/Discussion-on-%22Wicket-Interface-Speed-Up%22-to19197540.html">Wicket&#8217;s mailing list</a>.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-caching-resources-forever.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Wicket Interface Speed-Up: Modifying Expires and Cache-Control Headers</title>
		<link>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-modifying-expires-and-cache-control-headers.html</link>
		<comments>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-modifying-expires-and-cache-control-headers.html#comments</comments>
		<pubDate>Fri, 15 Aug 2008 16:13:00 +0000</pubDate>
		<dc:creator>Stefan Fußenegger</dc:creator>
				<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://tech.molindo.at/2008/08/wicket-interface-speed-up-modifying-expires-and-cache-control-headers.html</guid>
		<description><![CDATA[This entry is part of my &#8220;Wicket Interface Speed-Up&#8221; series.
Let&#8217;s start with a short introduction before we talk about setting Expires and Cache-Control HTTP-Headers:
By default, all WebResources are cacheable for one hour, which is defined by WebResource.getCacheDuration():


protected int getCacheDuration&#40;&#41;
&#123;
return 3600;
&#125;

While one hour is nice, it would be beneficial to increase the value for resources that [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-style: italic;">This entry is part of my &#8220;<a href="http://techblog.molindo.at/2008/08/wicket-interface-speed-up.html">Wicket Interface Speed-Up</a>&#8221; series.</span></p>
<p>Let&#8217;s start with a short introduction before we talk about setting <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21">Expires</a> and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">Cache-Control</a> HTTP-Headers:</p>
<p>By default, all <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/markup/html/WebResource.html">WebResources</a> are cacheable for one hour, which is defined by WebResource.<a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/markup/html/WebResource.html#getCacheDuration%28%29">getCacheDuration()</a>:<br />
<span id="more-24"></span></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">int</span> getCacheDuration<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">3600</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>While one hour is nice, it would be beneficial to increase the value for resources that are known to change rarely (or never). In order to change that default to something different, one has to override this method. However, it&#8217;s not very obvious how to do that if you are used to this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> MyPanel<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> id<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add<span style="color: #009900;">&#40;</span>HeaderContributor.<span style="color: #006633;">forCss</span><span style="color: #009900;">&#40;</span>MyPanel.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #0000ff;">&quot;MyPanel.css&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// snip</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>So how to cache MyPanel.css for more than an hour? In order to answer that question it&#8217;s nice to know what happens behind the scenes. HeaderContributor.forCss(&#8230;) returns a HeaderContributor that will do the following, as soon as the head section of your HTML is rendered:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> renderHead<span style="color: #009900;">&#40;</span>IHeaderResponse response<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
response.<span style="color: #006633;">renderCSSReference</span><span style="color: #009900;">&#40;</span>
<span style="color: #000000; font-weight: bold;">new</span> CompressedResourceReference<span style="color: #009900;">&#40;</span>scope, path<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Okay, so we are dealing with a CompressedResourceReference. But how do <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/ResourceReference.html">ResourceReferences</a> translate into the actual <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/Resource.html">Resource</a>? ResourceReferences will be translated into a URL using a <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/request/target/resource/SharedResourceRequestTarget.html">SharedResourceRequestTarget</a> and <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/request/IRequestCodingStrategy.html">IRequestCodingStrategy</a>.<a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/request/IRequestCodingStrategy.html#encode%28org.apache.wicket.RequestCycle,%20org.apache.wicket.IRequestTarget%29">encode</a>(&#8230;) (<a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/protocol/http/request/WebRequestCodingStrategy.html">WebRequestCodingStrategy</a> by default). The default implementation is as follows:</p>
<ol>
<li> to check if the <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/IRequestTarget.html">IRequestTarget</a> is mounted</li>
<li>use ResourceReference.getSharedResourceKey() to encode a URL (those URL&#8217;s will start with &#8220;/resource&#8221;)</li>
</ol>
<p>Every time ResourceReference.<a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/ResourceReference.html#getSharedResourceKey%28%29">getSharedResourceKey</a>() is called, Wicket will make sure that the resource is bound to the <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/Application.html">Application</a> (i.e. stored in Application.<a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/Application.html#getSharedResources%28%29">getSharedResources</a>()) and return a unique key made up of scope, path, locale and style. If the ResourceReference hasn&#8217;t been bound to the Application before, it will make sure, that Application.getSharedResources() will contain a Resource (not a ResourceReference!) by calling ResourceReference.<a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/ResourceReference.html#newResource%28%29">newResource()</a>. In the case of a CSS file, newResource() will return a <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/ResourceReference.html#newResource%28%29">CompressedPackageResource</a> &#8230; but only if it isn&#8217;t already bound to the Application &#8211; well, you probably can&#8217;t check often enough <img src='http://techblog.molindo.at/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Okay, so now we know how ResourceReferences translate into Resources: They will be looked up in an application&#8217;s shared resources and be created if not already present. However, this check doesn&#8217;t take the type of ResourceReference into account. This means that a CompressedResourceReference needn&#8217;t translate into a CompressedPackageResource. It can also translate into anything else that has been bound before.</p>
<p>Therefore, the trick is to bind a shared resource to the application before it is used the first time. This can easily be done inside an Application&#8217;s <a href="http://wicket.apache.org/docs/wicket-1.3.2/wicket/apidocs/org/apache/wicket/Application.html#init%28%29">init()</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">Class</span> scope <span style="color: #339933;">=</span> MyPanel.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">;</span>
<span style="color: #003399;">String</span> path <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;MyPanel.css&quot;</span><span style="color: #339933;">;</span>
WebResource resource <span style="color: #339933;">=</span>
<span style="color: #000000; font-weight: bold;">new</span> CompressedPackageResource<span style="color: #009900;">&#40;</span>scope, path, <span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">int</span> getCacheDuration<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">3600</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">24</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">7</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
getSharedResources<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>scope, path, <span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000066; font-weight: bold;">null</span>, resource<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Therefore, you don&#8217;t have to change any components to change the cache interval of your resources. However, it would be desirable to make the current default of one hour configurable using Application&#8217;s settings. Furthermore, it would also be nice to get control over the newResource() method, e.g. using something like Application.getResourceFactory().newResource(ResourceReference ref).</p>
<p>Attention: An overflow in current Wicket versions (1.3.4 and 1.4-M3 respectively) leads to wrong values for the Expires header. Cache durations greater than Integer.MAX_VALUE/1000 seconds (which is approx. 25 days) cause wrong expiry dates. (see <a href="https://issues.apache.org/jira/browse/WICKET-1777">Wicket-1777</a>). Bugfix will be available in next versions.</p>
<p><span style="font-style:italic;">UPDATE: There is an ongoing discussion on my &#8220;Wicket Interface Speed-Up&#8221; on <a href="http://www.nabble.com/Discussion-on-%22Wicket-Interface-Speed-Up%22-to19197540.html">Wicket&#8217;s mailing list</a>.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.molindo.at/2008/08/wicket-interface-speed-up-modifying-expires-and-cache-control-headers.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
