SeamFramework.orgCommunity Documentation

Chapter 12. Writing your presentation layer using Apache Wicket

12.1. Adding Seam to your wicket application
12.1.1. Bijection
12.1.2. Orchestration
12.2. Setting up your project
12.2.1. Defining the Application

Seam supports Wicket as an alternative presentation layer to JSF. Take a look at the wicket example in Seam which shows the Booking Example ported to Wicket.

Note

Wicket support is new to Seam, so some features which are available in JSF are not yet available when you use Wicket (e.g. pageflow). You'll also notice that the documentation is very JSF-centric and needs reorganization to reflect the first class support for Wicket.

The features added to your Wicket application can be split into two categories: bijection and orchestration; these are discussed in detail below.

Extensive use of inner classes is common when building Wicket applications, with the component tree being built in the constructor. Seam fully supports the use of annotation based control in inner classes and constructors (unlike regular Seam components).

Annotations are processed after any call to a superclass. This mean's that any injected attributes cannot be passed as an argument in a call to this() or super().

When a method is called in an inner class, bijection occurs for any class which encloses it. This allows you to place your bijected variables in the outer class, and refer to them in any inner class.

You can secure a Wicket component by using the @Restrict annotation. This can be placed on the outer component or any inner components. If @Restrict is specified, the component will automatically be restricted to logged in users. You can optionally use an EL expression in the value attribute to specify a restriction to be applied. For more refer to the Chapter 15, Security.

For example:

@Restrict

public class Main extends WebPage {
   ...

Tip

Seam will automatically apply the restriction to any nested classes.

You can demarcate conversations from within a Wicket component through the use of @Begin and @End. The semantics for these annotations are the same as when used in a Seam component. You can place @Begin and @End on any method.

Note

The deprecated ifOutcome attribute is not supported.

For example:

item.add(new Link("viewHotel") {


   @Override
   @Begin
   public void onClick() {
      hotelBooking.selectHotel(hotel);
      setResponsePage(org.jboss.seam.example.wicket.Hotel.class);
   }
};

You may have pages in your application which can only be accessed when the user has a long-running conversation active. To enforce this you can use the @NoConversationPage annotation:

@Restrict
@NoConversationPage(Main.class)
public class Hotel extends WebPage {

If you want to further decouple your application classes, you can use Seam events. Of course, you can raise an event using Events.instance().raiseEvent("foo"). Alternatively, you can annotate a method @RaiseEvent("foo"); if the method returns a non-null outcome without exception, the event will be raised.

You can also control tasks and processes in Wicket classes through the use of @CreateProcess, @ResumeTask, @BeginTask, @EndTask, @StartTask and @Transition.

TODO - Implement BPM control - JBSEAM-3194

To enable bijection and orchestration control via annotations in Wicket you must place your classes in WEB-INF/wicket. Seam needs to instrument the bytecode of your Wicket classes to be able to intercept the annotations you use.

A Wicket web application which uses Seam should use SeamWebApplication as the base class; this creates hooks into the Wicket lifecycle allowing Seam to automagically propagate the conversation as needed. It also adds status messages to the page.

For example:

The SeamAuthorizationStrategy delegates authorization to Seam Security, allowing the use of @Restrict on Wicket components. SeamWebApplication installs the authorization strategy for you. You can specify the login page by implementing the getLoginPage() method.

You'll also need to set the home page of the application by implementing the getHomePage() method.

public class WicketBookingApplication extends SeamWebApplication {


   @Override
   public Class getHomePage() {
      return Home.class;
   }
   @Override
   protected Class getLoginPage() {
      return Home.class;
   }
   
}

Seam automatically installs the Wicket filter for you (ensuring that it is inserted in the correct place for you). But you still need to tell Wicket which WebApplication class to use:


<components xmlns="http://jboss.com/products/seam/components"
   xmlns:wicket="http://jboss.com/products/seam/wicket">
         
   <wicket:web-application application-class="org.jboss.seam.example.wicket.WicketBookingApplication" />
</components