2010, 6th week report

Thought week, better to write down results to improve morale :)

After three days in London last week, my working week started on Sunday. I worked on Artivio, actually in private testing to some potential customer, and on my still secret project on social shopping. I had the chance to consolidate some new stuff and I want to share what are the new weapons I can use for my webapps, in no particular order. I also updated my oholo stack.

Hibernate Search
Using Hibernate as persistence technology, integrating text search engine like Lucene has been a breeze. Now I have relevance sorted result, can prepare AND and OR query and stuff like this. This have been more easy than what I could expect. Well documented.

Release with Maven
I started to use Maven on regular basis to make releases. I already published a small article about.

Wicket: images and consistent URLs
I am ready to write a small but important article about best practice to serve images with Wicket, being application resources or user uploaded images. I will also write about a nice "Ajax search" with consistent URLs (a la Gmail) which I just implemented for Artivio. Yes, @kinabalu, I primise, first article in a few days :)

JQuery Tools
Artivio now uses JQuery Tools for some frontend goodies. I have some nice tooltip and overlay and in future also the image gallery will use this amazing piece of technology. I also implemented a really nice table with clickable rows made with CSS + JQuery :)

OpenID
I manage out to complete a OpenId authentication process using openid4java and integrating everything with my Wicket front end, thanks also to this nice article on IBM developerWorks.

iPhone applications
I expanded my collaboration network so from now on I can provide solutions for iPhone and similar devices. First project is on the way.

Research: Apache Shiro and some authorisation design issue.
Resource access authorization can be a mess if implemented the wrong way. I have investigated and tried Apache Shiro which is really nice and very similar to a custom implementation I developed and used since a year. Wicket integration is also a mess but after some investigation I have a solution. Will work again on this the next week for the secret project.

Java User Group
I attended JUG meeting last Tuesday, couple of presentation about distributed SCM: Mercurial and Bazaar this time. Very nice. I also checked for interest about a Wicket presentation that I will make the next JUG meeting sometime in March.

That's all. Now finally comes the weekend, so I can play with something else, I just read an article about........

wicket-slides 0.8.0 released with Smoothgallery 2.1

I managed to deploy a new version of wicket-slides project, a wicket adaptor for the cool and well done Smoothgallery, a javascript slideshow.

The 0.8.x development cycle main introduction is the adoption of the development release of Smoothgallery, named 2.1dev. This release add some new features and even if it's development is blocked till January 2009, it is significantly better than 2.0 in terms of performance, uses mootools 1.2 and include the ReMooz javascript library for zooming.

There is not an official distribution, but I mavenized the build system and deploy artifacts on java.net maven2 repository. Here are the instructions to use in your maven project.

You need java.net maven2 repository:

      <repository>
         <id>java.net</id>
         <name>Java.net Repository for Maven</name>
         <url>http://download.java.net/maven/2/</url>
         <layout>default</layout>
      </repository>

And, of course, the wicket-slides dependencies.

      <dependency>
         <groupId>com.googlecode</groupId>
         <artifactId>wicket-slides</artifactId>
         <version>0.8.0-smoothgallery2.1dev</version>
      </dependency>

If you are not using maven, you can just download wicket-slides jar from here:
http://download.java.net/maven/2/com/googlecode/wicket-slides/

Multi brand (skinned) application with Maven 2 and Wicket (take 1)

In this two parts article, I will explain how to configure a web application built with Maven to support "branding", or skinning. That is, support different distribution skinned with particular images, logo, background, text. In the end we just want to keep separated the static contents and choose the right set when we package our application so that the result is a war with just the content for a single company. I call this a branded distribution using brand as a similar word for skinning. Brand looks more enterprise and general than skinning, anyway :)

In the second part of the article I will also cover the Wicket side of the story. The Maven side works by himself, anyway.

Some thoughts, before to start.

Fundamentals stuff, but important to remember: files that are in the war root are accessible from an HTML file with a relative path, so if we can have an image under myapp.war/images/pic.png we can acess it with src="images/pic.png".
Instead, when we need to load an image or a text file from Java code, it must be in the Classpath, so it had to be under myapp.war/WEB-INF/
Fundamentals, I told.

Another thing: we want to develop in comfort under our IDE, spcifically Eclipse, not being doomed to perform a Maven compile every time to filter some property. Test should run with their own resources, build path in Eclipse should be consistent and not be affected by multi brand configuration so that Eclipse copy modified resources on the fly and we have latest version in place without going to ask Maven again.

Last thing: as always, use what already exists. Wicket has a built-in support for skinning (called styling) and Maven provides "profiles". Let's use everything we can. Ready, go!

Maven Side - Profiles

Let's first introduce the concept that we are running our application in a particular mode, a brand mode, whatever. Comes natural to define a maven property in pom.xml

 <properties>
             .....
            <brand>stage</brand>
</properties>

Where "brand" is the name of the property and "stage" is the value. For those not familiar with Maven properties, let's say just this: in every file that will be processed by maven during a build session, maven will "filter" all the variables and they will be substituted by the value defined in pom. In a few words:

${brand}  --> stage

in every file filtered by Maven. Included pom.xml itself.

So we will have different brands: stage is my word for "demonstration application". We can have companyA, companyB, and so on. To implement different brands, in maven, we use maven profiles. While stage is a top level POM property, we now define:

   <profiles>
      <profile>
         <id>companyA</id>
         <properties>
            <brand>companyA</brand>
         </properties>
       </profile>
   </profiles>

As we all know, to activate a profile we add "-P companyA" in the maven command line and all the profile configuration will override the default ones. So now we have a default brand, stage, and a companyA specific profile.

Maven Side - Resources

In my stage brand I have to use free images, a personal disclaimer and avoid all contents owned by my customer. So I create a folder "brands"  with a sub folder for each "brand" [1]. So in "src/main/brands/stage" I put my free to use contents.

To let maven choose the folder accordingly to the chosen brand, we configure the new resource this way:

<resources>
         <resource>
            <filtering>false</filtering>
             <directory>src/main/brands/${brand}/</directory>
            <includes>
               <include>**/*.txt</include>
            </includes>
         </resource>
     ...
</resources>

In my particular situation, I am interested in having just *.txt files under my Classpath. Please note that I have also put every file in the brand folder under a sub folder I call "contents", so I do not  have a mess of files in the root of my war. Here is how I load resources from java:

getClass().getClassLoader().getResourceAsStream("contents/" + "myResource.txt")

Now let's deal with static images, typically some logo, background and so on. Target is to access images from HTML file simply with an img tag and a src="contents/header.jpg"

We need to configure what in maven are called "web resources", and deal with the maven-war-plugin:

       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <webResources>
                  <resource>
                     <directory>src/main/brands/${brand}/</directory>
                     <includes>
                        <include>**/*.jpg</include>
                         <include>**/*.gif</include>
                        <include>**/*.png</include>
                     </includes>
                  </resource>
               </webResources>
             </configuration>
         </plugin>

In the end, the "src/main/brands/${brand}" folder is just a new folder threated as maven normally threat "src/main/webapp" where we normally found the css folder and other folders with static content. This is the reason I normally keep files under "src/main/brands/${brand}/contents", to keep war root clean.

To summer up, here is the folder layout:



src/main/


  - brands


    - stage


      - contents/disclaimer.txt


    - companyA


        - contents/disclaimer.txt


  - webapp


    -css



This completes the maven side of the problem. In the next article we will attack the "web" side, with Wicket, and finish with fixing the development environment.

[1] Thanks to Simone Bordet for the final tip on this on the JUG Milano mailing list! :) http://bordet.blogspot.comt.

Wicket HybridUrlCodingStrategy and URL with dots

Wicket has some URL encoding strategy, one is the HybridUrlCodingStrategy. As I knew, this strategy uses the dots in the URL to identify the page versioning.

This generate a problem: my application cannot have a dot in the URL. Today I was handling with the Account creation in my application and was pretty normale to me to have a username like "daniele.dellafiore". But then if my Account Page is mounted at "account", a specific account URL should be like this


And when I read the parameters, I just get "daniele". Everything after the dot is reserved for the versioning. What is the solution: if you do not need versioning, use a different strategy like the MixedParamUrlCodingStrategy that I am using recently that also allows prettier very REST style URL.
So instead of mounting pages like this:

mount(new HybridUrlCodingStrategy("account", AccountPage.class));


I can do better this way

 mount(new MixedParamUrlCodingStrategy("account", AccountPage.class, new String[] { "username" }));


This way you also specify at the mount level what is the name of the parameter you will use in the AccountPage, username in this case. It is a sort of duplication but we can get rid of that with a constant.

Extreme duplication riddance: less html in Wicket panels with forms - part 1

In a project I am working on these days, I have two pages that are almost the same, one is the editable version of the other one and is important to have a preview of the "view only" mode, without buttons, text area and everything. I  decided to make something shiny so now I have an Edit button that changes a Panel, replacing the one with the "labels" for the view only mode with the one with the Form and all of its fields, including some with advanced ajax features like the YUI DatePicker and the TinyMCE editor. Wicket is great in reducing the duplication of HTML code using panels and markup inheritance, but I still haev a duplication that, in my scenario comes because for every property of my domain object, say a Product, I have to use a input text in html for the Form and label for the plain text. So I have two HTML files almost identical. I manage out to reduce them to three different html files, being two really small, and just one with all the property, so I resolve the duplication. Let's see how. The basic idea is to have a generic Panel, call it InputPanel, with it's own html that inside define an <input> or a <textarea> or whatever. In this way my application Panel, say the ProductPanel, can show property this way: <span wicket:id="price"></span> without worrying about what kind of component there will be inside, a label or even a input. So, in my ProductPanel I will make:
add(new TextAreaPanel("price", myModel);
How is TextAreaPanel done? See his parent class, InputPanel
public abstract class InputPanel extends Panel { protected AbstractTextComponent field; public InputPanel(String id, IModel<?> model) { super(id, model); } public InputPanel(String id) { this(id, null); } public Component addToField(IBehavior... behaviors) { field.add(behaviors); return this; } }
then the concrete class, very simple.
public TextAreaPanel(String id, IModel<?> model) { super(id, model); field = new TextArea("area", model); add(field); }
I will talk later about the class field named... field. Finally the TextAreaPanel.html
<wicket:panel> <textarea wicket:id="area"></textarea> </wicket:panel>
You get the trick? I can define my panel with many span, which will contain an input or a label or whatever I need, so I can just have a single html files that lists all the properties I need to show and edit. Seems easy but there are a couple of trick. As you noticed, InputPanel redefine a method add(Behavior....). This is because we want to attach behaviours to the actual input field. The method returns the panel to let use fluent interface consistently. Yeah, I can make the field private but... ok, you know. Another trick is needed if, as common, you are wrapping your Model with a CompountPropertyModel. To make the CPM work with this solution, we need to overridde a method, becouse the wicket id used as property expression need to be the one you define in your ProductPanel, not the one defined in generic InputPanel html. So out CPM will override as follow:
@Override protected String propertyExpression(Component component) { return super.propertyExpression(component.getParent()); }
That's all? No. Better, is the end of the first part. Now we need to handle the fact that one of the two panels need to be in a form and that maybe we want to "decorate" our form with a toolbar or something. We will see how in the second article.