Friday, October 23, 2009

Page links with Wicket

The default urls created by Wicket do not look very nice. For instance, let IndexPage be the home page of our ShopApplication. Assuming shop is your application's context name and wicket the path where you mapped the Wicket filter, then by default, the url for the IndexPage will be akin to
http://somehost/shop/wicket/index?wicket:interface=:0:headerPanel:index2::ILinkListener::. I said ugly didn't I?

Wicket has a mechanism for prettifying URLs. In ShopApplication, you can instruct wicket to "mount" a page on a specific path. Here is the code.
public class ShopApplication extends WebApplication {
@Override
public Class getHomePage() {
return IndexPage.class;
}
@Override
protected void init() {
mountBookmarkablePage("index", IndexPage.class);
}
}
Wow, that was easy!

Now, assume you have a navigation panel, included on all the pages of your application, where you list links to the various pages of your application. Here is the markup:
<table cellpadding="0" cellspacing="0">
<tr align="center">
<td><a class="menuitem" href="index">Index</a></td>
... other pages
</tr>
</table>
We are referencing the mounted path "index" directly. How convenient is that? Although, convenient such references do not work correctly. The navigator will translate it into http://somehost/shop/index instead of the correct http://somehost/shop/wicket/index.

For bookmarkable links such as "index", Wicket offers the <wicket:link> tag instructing Wicket to to automatically create bookmarkable
link components for the links inside the tags. So let's try that.
<tr align="center">
<wicket:link>
<td><a class="menuitem" href="index">Index</a></td>
... other pages
</wicket:link>
</tr>
The above is easy enough and will work, as long as all your pages are in the same java package.

Indeed, the <wicket:link> tag doctors url references with respect to the java page of the current page belongs to, but if the page is located in a different package, then the urls will be rendered incorrectly. Bummer.

So, we seem to be stuck. Googling for "wicket url mountBookmarkablePage" you will find an article by R.J. Lorimer on controlling Wicket URLs which did not go far in reducing my level of confusion. After further investigation, I found an example which caters for the use case we've been discussing so far, that is the nice-url example.

The nice-url example, after mounting the Home page as "/the/homepage/path", simply adds a BookmarkablePageLink to the Home class on another page, namely Page1. Here is the relavant code.
<a wicket:id="homeLink" href="#">[go back]</a>

public class Page1 extends WicketExamplePage {
public Page1(PageParameters parameters) {
add(new BookmarkablePageLink("homeLink", Home.class));
}
}
which magically works, in the sense that when the link for the url is rendered, it will somehow contain the mounted path "/the/homepage/path". How does BookmarkablePageLink know that Home is mounted on "/the/homepage/path"?

It does not know. Instead, it invokes the
urlFor(IPageMap pageMap, Class pageClass, PageParameters parameters)
method defined in its parent class, Component. This method will in turn ask the request cycle the page is associated with to find the correct url. The request cycle will eventually go through all mount points, asking them whether they apply to Home.class. The first mount point which applies will then be asked to encode the Home page, returning the mounted path. The exact details might vary, but from a 100 feet point of view, wicket does reverse lookup to see which mount point maps to a given page which goes to explain the aforementioned magic.

Friday, October 16, 2009

IDEA open sourced

Coming across Cedric Beust's comments on IDEA going open-source, I thought I'd chime in. Cedric makes valid points, in particular about the unfulfilled expectations after open sourcing a product. As he points out, Jetbrains is unlikely to be flooded with patches and additions from the community, floating them back to the top.

Cedric also correctly identifies that open-sourcing software is an attempt to regain mind-share. He unfortunately qualifies the effort as "last-ditch" which is where I disagree. Companies have to make strategic decisions all the time. Companies live and die by strategic decisions. Who would have guessed 10 years ago that IBM would have survived its transition to services as decided by Louis V. Gerstner? Instead of "last-ditch", in my humble opinion "just-in-time" would be a better qualification for Jetbrains' recent decision.

According to scientific surveys conducted around a glass of beer, people who use IDEA on a daily basis absolutely love it. I am not one of them. But when a company enjoys such a dedicated following, it seems premature to predict its imminent doom.

As Cedric put it, I wish the best to IDEA. I really do.