SeamFramework.orgCommunity Documentation
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.
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()
.
We are working to improve this.
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.
A Seam enabled Wicket application has full access to the all the
standard Seam contexts (EVENT
, CONVERSATION
,
SESSION
, APPLICATION
and
BUSINESS_PROCESS
).
To access Seam component's from Wicket, you just need to inject it
using @In
:
@In(create=true)
private HotelBooking hotelBooking;
As your Wicket class isn't a full Seam component, there is no
need to annotate it @Name
.
You can also outject an object into the Seam contexts from a Wicket component:
@Out(scope=ScopeType.EVENT, required=false)
private String verify;
TODO Make this more use case driven
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 {
...
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.
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
Seam needs to instrument the bytecode of your Wicket classes to be able to intercept the annotations you use. The first decision to make is: do you want your code instrumented at runtime as your app is running, or at compile time? The former requires no integration with your build environment, but has a performance penalty when loading each instrumented class for the first time. The latter is faster, but requires you to integrate this instrumentation into your build environment.
There are two ways to achieve runtime instrumentation. One relies on placing wicket components to be instrumented in a special folder in your WAR deployment. If this is not acceptable or possible, you can also use an instrumentation "agent," which you specify in the command line for launching your container.
Any classes placed in the WEB-INF/wicket
folder within your
WAR deployment will be automatically instrumented by the seam-wicket runtime.
You can arrange to place your wicket pages and components here by specifying
a separate output folder for those classes in your IDE, or through the use of
ant scripts.
The jar file jboss-seam-wicket.jar
can be used as an iinstrumentation
agent through the Java Instrumentation api. This is accomplished through the following
steps:
Arrange for the jboss-seam-wicket.jar
file to live in a
location for which you have an absolute path, as the Java Instrumentation API does
not allow relative paths when specifying the location of an agent lib.
Add javaagent:/path/to/jboss-seam-wicket.jar
to the command line options
when launching your webapp container:
In addition, you will need to add an environment variable that specifies packages that the agent should instrument. This is accomplished by a comma separated list of package names:
-Dorg.jboss.seam.wicket.instrumented-packages=my.package.one,my.other.package
Note that if a package A is specified, classes in subpackages of A are also examined. The classes chosen for instrumentation can be further limited by specifying:
-Dorg.jboss.seam.wicket.scanAnnotations=true
and then marking instrumentable classes with the @SeamWicketComponent
annotation, see Section 12.2.3, “The @SeamWicketComponent
annotation”.
Seam supports instrumentation at compile time through either Apache Ant or Apache Maven.
Seam provides an ant task in the jboss-seam-wicket-ant.jar
. This is used
in the following manner:
<!-- XML : generated by JHighlight v1.0 (http://jhighlight.dev.java.net) --> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">taskdef</span><span class="xml_plain"> </span><span class="xml_attribute_name">name</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"instrumentWicket"</span><span class="xml_plain"> </span><br /> <span class="xml_plain"> </span><span class="xml_attribute_name">classname</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"org.jboss.seam.wicket.ioc.WicketInstrumentationTask"</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">classpath</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"lib/jboss-seam-wicket-ant.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"web/WEB-INF/lib/jboss-seam-wicket.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"lib/javassist.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">pathelement</span><span class="xml_plain"> </span><span class="xml_attribute_name">location</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"lib/jboss-seam.jar"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">classpath</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols"></</span><span class="xml_tag_name">taskdef</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"></span><br /> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">instrumentWicket</span><span class="xml_plain"> </span><span class="xml_attribute_name">outputDirectory</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"${build.instrumented}"</span><span class="xml_plain"> </span><span class="xml_attribute_name">useAnnotations</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"true"</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">classpath</span><span class="xml_plain"> </span><span class="xml_attribute_name">refid</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"build.classpath"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">fileset</span><span class="xml_plain"> </span><span class="xml_attribute_name">dir</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"${build.classes}"</span><span class="xml_plain"> </span><span class="xml_attribute_name">includes</span><span class="xml_tag_symbols">=</span><span class="xml_attribute_value">"**/*.class"</span><span class="xml_tag_symbols">/></span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols"></</span><span class="xml_tag_name">instrumentWicket</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br />
This results in the instrumented classes being placed in the directory
specified by ${build.instrumented}
. You will then
need to instruct ant to copy these classes into WEB-INF/classes
.
If you want to hot deploy the Wicket components, you can copy the instrumented classes to
WEB-INF/dev
; if you use hot deploy, make sure that
your WicketApplication
class is also hot-deployed.
Upon a reload of hot-deployed classes, the entire WicketApplication
instance has to be re-initialized, in order to pick up new references
to the classes of mounted pages.
The useAnnotations
attribute is used to make the ant task only include
classes that have been marked with the @SeamWicketComponent
annotation,
see Section 12.2.3, “The @SeamWicketComponent
annotation”.
The jboss maven repository repository.jboss.org
provides a plugin named
seam-instrument-wicket
with a process-classes
mojo. An
example configuration in your pom.xml might look like:
<!-- XML : generated by JHighlight v1.0 (http://jhighlight.dev.java.net) --> <span class="xml_tag_symbols"><</span><span class="xml_tag_name">build</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">plugins</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">plugin</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">groupId</span><span class="xml_tag_symbols">></span><span class="xml_plain">org.jboss.seam</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">groupId</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">artifactId</span><span class="xml_tag_symbols">></span><span class="xml_plain">seam-instrument-wicket</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">artifactId</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">version</span><span class="xml_tag_symbols">></span><span class="xml_plain">2.2.0</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">version</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">configuration</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">scanAnnotations</span><span class="xml_tag_symbols">></span><span class="xml_plain">true</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">scanAnnotations</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">includes</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">include</span><span class="xml_tag_symbols">></span><span class="xml_plain">your.package.name</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">include</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">includes</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">configuration</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">executions</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">execution</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">id</span><span class="xml_tag_symbols">></span><span class="xml_plain">instrument</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">id</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">phase</span><span class="xml_tag_symbols">></span><span class="xml_plain">process-classes</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">phase</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">goals</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"><</span><span class="xml_tag_name">goal</span><span class="xml_tag_symbols">></span><span class="xml_plain">instrument</span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">goal</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">goals</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">execution</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">executions</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">plugin</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_plain"> </span><span class="xml_tag_symbols"></</span><span class="xml_tag_name">plugins</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br /> <span class="xml_tag_symbols"></</span><span class="xml_tag_name">build</span><span class="xml_tag_symbols">></span><span class="xml_plain"></span><br />
The above example illustrates that the instrumentation is limited to classes specified by
the includes
element. In this example, the scanAnnotations
is specified, see Section 12.2.3, “The @SeamWicketComponent
annotation”.
Classes placed in WEB-INF/wicket will unconditionally be instrumented. The other instrumentation
mechanisms all allow you to specify that instrumentation should only be applied to classes
annotated with the @SeamWicketComponent
annotation. This annotation is inherited,
which means all subclasses of an annotated class will also be instrumented. An example usage is:
<!-- <br/> --><span class="java_keyword">import</span><!-- <br/> --><span class="java_plain"> org</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">jboss</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">seam</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">wicket</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">ioc</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_type">SeamWicketComponent</span><!-- <br/> --><span class="java_separator">;</span> <!-- --><br/><span class="java_plain">@</span><span class="java_type">SeamWicketComponent</span> <!-- --><br/><span class="java_keyword">public</span><span class="java_plain"> </span><span class="java_keyword">class</span><span class="java_plain"> </span><span class="java_type">MyPage</span><span class="java_plain"> </span><span class="java_keyword">extends</span><span class="java_plain"> </span><span class="java_type">WebPage</span><span class="java_separator">{</span> <!-- --><br/><span class="java_plain"> </span><span class="java_separator">...</span> <!-- --><br/><span class="java_separator">}</span>
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"
xsi:schemaLocation=
"http://jboss.com/products/seam/wicket
http://jboss.com/products/seam/wicket-2.2.xsd">
<wicket:web-application
application-class="org.jboss.seam.example.wicket.WicketBookingApplication" />
</components
In addition, if you plan to use JSF-based pages in the same application as wicket pages, you'll need to ensure that the jsf exception filter is only enabled for jsf urls:
<components xmlns="http://jboss.com/products/seam/components"
xmlns:web="http://jboss.com/products/seam/web"
xmlns:wicket="http://jboss.com/products/seam/wicket"
xsi:schemaLocation=
"http://jboss.com/products/seam/web
http://jboss.com/products/seam/web-2.2.xsd">
<!-- Only map the seam jsf exception filter to jsf paths, which we identify with the *.seam path -->
<web:exception-filter url-pattern="*.seam"/>
</components
Take a look at the Wicket documentation for more on authorization
strategies and other methods you can override on the
Application
class.