Archive

Archive for June, 2007

Apache Wicket - New Top Level Project

June 20th, 2007

After a great deal of work and time by several of the Wicket developers, Wicket has been promoted to a top level project under the Apache umbrella. Wicket is now known as Apache Wicket.

Congratulations to the Apache Wicket developers. This is a significant and well-deserved achievement.

nick Entry

Versioning Your Wicket Models

June 13th, 2007

Occasionally you’ll run into a use case where multiple users might edit the same object/data at the same time. If two people are editing the same information, generally the last one to submit the web form wins (last writer). ORM frameworks, like Hibernate, provide the ability to detect when the object’s version changed. If you’re using something like Wicket, with it’s detachable model support, integrating version support is very easy.

What’s a detachable model?
Unlike standard Wicket models, which serialize the wrapped object to the session store, detachable models only contain an identifier used to reload the object when needed. This way, less memory and disk (in Wicket 1.3) is used. Detachable models should generally be used throughout your Wicket applications.

Let’s create a simple detachable model by subclassing LoadableDetachableModel:

public class MyModel extends LoadableDetachableModel {

  private Integer id;
  private MyDao dao;

  public MyModel(Integer id, MyDao dao) {
    this.id = id;
    this.dao = dao;
  }

  /*
    This method is inherited from LoadableDetachableModel
    and must be implemented by concrete classes.
  */
  public Object load() {
    return dao.get(id);
  }
}

When Wicket’s request cycle starts, MyModel’s load() method is called, retrieving the object using the DAO. (You might be concerned about the model storing a reference to the DAO, but if you’re using something like Wicket’s Spring Annotation package, the DAO won’t be serialized with the model.) As you can see, the DAO has the object’s id, which is just enough information to retrieve the object.

Now, we need to add support for detecting the version change:

public class MyModel extends LoadableDetachableModel {

  private Integer id;
  private Integer version;
  private MyDao dao;

  public MyModel(Integer id, Integer version, MyDao dao) {
    this.id = id;
    this.dao = dao;
    this.version = version;
  }

  /*
    There are a few different ways to detect a version
    mismatch. I'm being intentionally illustrative here.
  */
  public Object load() {
    MyObject myobj = dao.get(id);
    if (version == null) {
      version = myobj.getVersion();
    }
    else  if (!myobject.getVersion().equals(version)) {
      throw new MyVersionMismatchException(MyObject.class, id, version);
    }

    return myobj;
  }
}

When the object is loaded, we first ensure the version isn’t null and set it to the object’s current version if it is. This might be the first time we’ve seen the object, so we may not know the version when the model was created. Setting it allows us to check for differences later.

If the version is not null, we do an equality check. If the versions aren’t equal, we throw a fictional runtime exception handled by the Wicket component using the model.

Let’s step through the scenario using our version-sensitive detachable model:

  • Sue clicks the “Edit MyObject” link on the web page. The edit page creates a new instance of MyModel which loads the relevant MyObject instance using the passed id. Since the version is null when load() is called, it’s set.
  • Lucy also clicks “Edit MyObject” for the same object Sue is editing. The same process with MyModel occurs.
    Sue clicks submit, saving her object.
  • Lucy clicks submit. When MyModel#load() is called, the version from the loaded object (the one Sue saved, thereby updating the version number) doesn’t match the version number in the model, so the exception is thrown.
  • The exception handling code should inform Lucy about the version mismatch and prompt her to reload the object for editing.

The combination of Hibernate and Wicket allows for easy handling of a feature traditionally difficult to implement.

nick Entry

Upgrading to Wicket 1.3

June 7th, 2007

Over the last week or so I’ve been upgrading Eventful to Wicket 1.3. Overall, the process was fairly painless. Rename some packages, update any custom validators I’d created, and change the signatures of IModel’s getObject(…) and setObject(…) methods.

In fact, the most significant change to my code has been using Wicket’s servlet filter instead of a servlet. This is really how API upgrades should be - painless.

nick Entry

OPEN Forum Networking Event Redux

June 3rd, 2007

Last week I attended an OPENForum event hosted by American Express. While a good networking event all around, the keynote speaker, Jennifer Kushell of YSN offered some valuable insights into growing a business using a network of contacts, as well as some valuable peripheral advise:

Use a Customer Relationship Management application
This is something I’ve been bad about in the past, but I’ve recently installed SugarCRM. There are quite a few open source CRM applications out there if Sugar doesn’t meet your needs, but maintaining contact with your customer base is critical to expanding your business.

Make use of blogs to advertise and generate grassroots marketing
This is no-brainer for most people in the technical field, but a large number of business, from printing to legal to executive coaching, have a hard time understanding how blogging will improve customer relations and expand business. One thing Jennifer didn’t mention was the need for corporate blogs to be transparent - readers can smell a PR snowjob a mile away.

Interns
This was a valuable piece of advise, one that I’m looking to take advantage of. Interns are a great, low-cost resource for any company. Some people are concerned about quality of work, but if you provide interns with interesting projects, you can get great returns. And the intern you’ve spent a summer developing may turn into a great future employee.

Those are the three peripheral pieces of advise I took from Jennifer’s presentation. Try to catch her if she’s going to be in your area.

nick Entry