or a presenter. CDI managed beans can
be directly bound to the JSF 2 view via EL,
and the boundary (EJB 3. 1) can be directly
injected into the presenter. The presenter (or
a controller) can be directly captured with
an @Stereotype annotation. It works like a
macro—you can place in it CDI annotations
that get expanded with the annotation. A
stereotype is a regular Java annotation represented by @Stereotype:
Code Listing 8: persistence.xml for standalone JPA unit tests
@Named
@RequestScoped
@Stereotype
@Retention(RUNTIME)
@Target(TYPE)
public @interface Presenter {}
<persistence>
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider> org.eclipse.persistence.jp
a.PersistenceProvider</provider>
<class>com.abien.messageme.business.messaging.entity.Message</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name=" javax.persistence.jdbc.url" value="jdbc:derby:
./sample;create=true"/>
<property name=" javax.persistence.jdbc.password" value="app"/>
<property name=" javax.persistence.jdbc.driver" value=" org.apache.derby
<property name=" javax.persistence.jdbc.user" value="app"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</Persistence>
.jdbc.EmbeddedDriver"/>
tion is duplicated and renamed @View, and
the bean is renamed IndexView:
This custom stereotype can be applied
instead of @Named and @RequestScoped—
just like a macro. All CDI annotations iden-
tifying the presenter pattern can then be
replaced with
@Presenter
public class Index {
//
}
@View
public class IndexView {
private Message message = new
Message();
public Message getMessage() {
return message;
The purpose of the presenter is to implement presentation logic. The structure of
the presenter is tightly coupled with the
view, in that the state of a JSF component
in the view is mapped to a property inside
the presenter. The property can be either a
value (with value binding) or the component
instance itself (with component binding). In
trivial cases, there is a one-to-one relationship between the view and the presenter.
The presenter contains the view’s data as
well as all the presentation logic. Injecting
the boundary into the presenter involves
using the @Inject annotation.
As the amount of presentation logic
grows inside the presenter, the code can
become harder to maintain and test. With
CDI, it is fairly easy to split the monolithic
presenter into separate data and presenta-
tion logic parts. For example, the following
code shows how to refactor the backing
bean from the earlier example by moving
the save method into a newly created
IndexPresenter bean. The presenter annota-
The IndexPresenter bean gets the old
@Presenter annotation. As the following
code shows, the only purpose of the
IndexPresenter bean in this case is to imple-
ment the presentation logic.
@Presenter
public class IndexPresenter {
@Inject
Messaging boundary;
@Inject
IndexView indexView;
public void save(){
}
}
Because the unit test and the IndexPresenter
reside in the same package, the default
visible fields can be set directly. Private
fields with public setters can be used, but
packagewide fields are good enough in most
cases and can reduce code size.
Listing 9 shows how to test the presentation logic by mocking out the IndexView as
well as the boundary Messaging class. The
test, which invokes the IndexPresenter
.save() method, is successful if the method
store gets invoked exactly once with the
Message-Instance being returned by the
IndexView. Verifying the invocation means
passing the mock to the Mockito.verify()
method. The IndexView is mocked out to
manipulate the return value without interacting with the JSF rendering.
The Messaging boundary is mocked
out for a different reason: to verify that the
expected method actually gets invoked:
public void save(){
boundary.store(indexView
}
Because the boundary and the view are
injected into the IndexPresenter, they can
be easily mocked out. In a unit test environment, both fields would be set directly
with the mock, whereas in a production
environment, the container would perform
the injection and set the actual dependency.
The design of the JSF 2 presentation is
similar to that of a rich Swing application.
Common patterns such as Model-View-Controller and their refinements—Supervising
Controller and Passive View—can be applied
to JSF 2 as well. The main difference between
JSF and a rich client technology is the way
the view is rendered. In Swing the developer
implements the view in Java, whereas in
JSF 2 the developer uses XHTML markup.