Archive for August 18th, 2005

Wicket Most Widely Used Framework!

Thursday, August 18th, 2005

On JavaLobby.org a discussion was started on whether or not Wicket was the most widely used framework. Matt Raible commented that it was most likely guerilla warfare from the Wicket team.

Well, I consider myself to be somewhat the evangelist for Wicket, and though I had noticed the about.com blog post requesting which framework was the most popular, I found the method of emailing him rather cumbersome, and I prefer open forums so everybody can see who posted what. I can’t remember asking anybody to respond, so it wasn’t me :-)

Matt also gives some graphs on mailinglist statistics. And yes, Wicket has soared in July with mailinglist activity. More so than ‘competing’ frameworks such as MyFaces, Cocoon, Echo, WebWork. And he quotes me saying that huge mailinglist activity may be a bad sign. I still stand by my standpoint: it may be an AntiPattern when a mailinglist is highly active. But just looking at the number of messages is not enough: looking at the type of messages is more indicative. It is a bummer that qualitative measurements are nigh impossible to take.

So another rather cool measurement Matt likes to do is download numbers. So lets try to figure out what the stats are for our frameworks (sourceforge is not helping though, and Tapestry downloads are missing):

Framework Last week Last 2 months
Wicket 195 2851
WebWork 9 123
MyFaces (sourceforge) 102 4368
MyFaces (apache) ~180 ~400
Struts ~3200 ~78000

Because I don’t have the actual data for the Apache projects, I am not able to calculate them precisely. I have tried to guess the numbers based on the graphs found here.

One thing that is striking is that a lot of people still download the old (2004) release of MyFaces from sourceforge.net. Another is that that number is much higher than the Apache numbers. Struts still dwarfs all other frameworks.

What does this tell us? Not too much. Wicket is at the moment compareable in popularity to MyFaces, and WebWork is seriously falling behind. If you want job security, then download struts now, as it will be around for FAR TOO LONG considering these numbers. When you also want to have fun in your job, download Wicket.

Custom Wicket Stock Quote Component

Thursday, August 18th, 2005

This entry is written as a reaction to Chris Schalke’s article, Building Custom JSF UI Components on the serverside. It shows how to obtain the same functionality with different technology: a custom Stock Quote component using Wicket.

The discussed files are avialable through ViewCVS on:

Intended audience: anyone seeking a better way of developing web applications. I trust you have Java development experience and know your HTML. Other than that…. well… just see. You might want to take a look at some Wicket Examples to see what Wicket is all about.

In Wicket building custom components is very easy. A normal web application will contain many, tailor made components for your application. In fact, each Page you create is a Component and could be put in a jar, and reused in another application.

Creating a Stock Quote component

The Stock Quote component should take a symbol and display the value of the stock obtained through a webservice in its body. I’ve used the same webservice as Chris did, and found some code on devx.com for calling the webservice. In order to keep it simple, I’ve not included this code here, but you can see it in our CVS. The webservice calling code is not the prettiest around, but it suffices.

So: Price of IBM goes here should replace the body contents with the actual value of IBM stock. Here’s the Java code for the component (there is no markup file associated with it):

public class StockQuoteLabel extends WebComponent
{
    public StockQuoteLabel(String id, String symbol)
    {
        super(id, new Model(symbol));
    }
    public StockQuoteLabel(String id, IModel model)
    {
        super(id, model);
    }
    protected void onComponentTagBody(
              final MarkupStream markupStream
            , final ComponentTag openTag)
    {
        String symbol = getModelObjectAsString();
        String quote = getQuote(symbol);
        replaceComponentTagBody(markupStream, openTag, quote);
    }
    private String getQuote(String symbol)
    {
        // do SOAP stuff
    }
}

The first constructor adds the symbol string as a Model to the component. Models are what bind your business application logic to components, they are the glue between your world and the Wicket components. The first constructor is a convenience constructor, allowing you to create the component quickly with a stock symbol such as “IBM”. The second constructor allows you to retrieve the stock symbol from somewhere else, such as a property from a POJO.
The first line in the onComponentTagBody method returns the contents of the model as a String. The second line replaces the text between the span tags with the stock quote retrieved from the web service.

So how would you use this component? Let’s first take a look at the markup (StockQuote.html):





The quote for IBM is:
    foo bar



The idea is to replace the “foo bar” text with the actual value of IBM stock. In the corresponding Java file for this web page the component is added to the page like (StockQuote.java):

public class StockQuote extends WebPage {
     public StockQuote() {
        add(new StockQuoteLabel("stockIBM", "IBM"));
     }
}

That is it.

Using a Form to get the symbol

Now lets use user input for dynamically retrieving the stockquote. The page alters like so:




Enter symbol:
The quote for symbol is: quote

As you can see, I’ve only added the form and an input field, and I’ve added a label to render the symbol in, and renamed the stock quote component. In the Java this looks like:

public class StockQuote extends WebPage {
    private static class Quote implements Serializable {
        private String symbol;
        public Quote() {}
        public String getSymbol() { return symbol; }
        public void setSymbol(String s) { symbol = s; }
    }

    private final Quote quote = new Quote();

    public StockQuote() {
        Form form = new Form("form");
        IModel model = new PropertyModel(quote, "symbol");
        form.add(new TextField("symbol", model));
        add(form);
        add(new Label("symbol", model));
        add(new StockQuoteLabel("quote", model));
    }
}

Here I’ve wired the page such that the text field, label and stock quote label all use the same instance of the Quote class. The property model uses the OGNL library to get and set the value of the property that is bound to the model, in this case the symbol property of the Quote object.

In order to run this example we need to create an application object and tell it what our home page is:

public class StockQuoteApplication extends WebApplication {
    public StockQuoteApplication() {
        getPages().setHomePage(StockQuote.class);
    }
}

Lastly we need to adjust the web.xml to make Wicket available to the servlet container:





    Wicket Examples
    
        StockQuoteApplication
        wicket.protocol.http.WicketServlet
        
applicationClassName
wicket.examples.stockquote.StockQuoteApplication
        
    
    
        StockQuoteApplication
        /stock/*
    

And we’re ready to run.

Conclusion

Wicket makes custom component creation a breeze. In just a few lines of code we’ve created a component that can play nicely with other Wicket components, and works without having to resort to configuration files, component registries and other fluff.

NB

Normally you wouldn’t want to make a custom component for this functionality. The getQuote() soap client would be part of a POJO that looks like:

public class StockQuote {
    private String symbol;
    public StockQuote() {}
    public StockQuote(String s) {symbol = s; }
    public void setSymbol(String s) {symbol = s; }
    public String getSymbol() { return symbol; }
    public String getQuote() { return getQuote(symbol); }
    private String getQuote(String symbol) {
        // do SOAP thingy
    }
}

So all functionality of getting a quote is located in the StockQuote POJO. Now you can
use this directly in your pages, without having to create a new component, just using
the default Label component to display the value of the quote:

quote.setSymbol("IBM");
add(new Label("quote", new PropertyModel(quote, "quote")));