In This Post
We will be creating a new GWT  module and linking it to our Pizza Shop application.  The new module  will allow Pizza Shop customers to view the status of their orders.
Targeted Functionality
Our  main goal is to provide a Web interface for Pizza Shop customers to  view the status of their orders.  Customers will enter their phone  numbers and query the status of the pizza order they've placed using the given phone number.  The following six status values will be supported by the  application:
-  New Order
- Preparing
- Oven
- Ready
- Delivery
- Delivered
One of these six status values or an "order not found" error message will be displayed after a phone number is submitted.
The new interface will not support a view for mobile devices. 
Generating OrderStatus Enumeration
Lets get started by launching the Roo Shell from within SpringSource  Tool Suite and entering the following commands to create an 
OrderStatus enumeration.
Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
roo> enum type --class ~.shared.OrderStatus
Created SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared
Created SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> enum constant --name NEW_ORDER
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> enum constant --name PREPARING
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> enum constant --name OVEN
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> enum constant --name READY
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> enum constant --name DELIVERY
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> enum constant --name DELIVERED
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\shared\OrderStatus.java
~.shared.OrderStatus roo> 
 
 
Notice that Roo first creates the 
OrderStatus enumeration and then updates it with each 
enum constant command.
Updating PizzaOrder Entity
Those of you  who have gone through the previous post will notice that we are missing  a couple of things here; currently, we are storing neither phone number  nor status intormation for a 
PizzaOrder.  We will need to add  these.
Using the STS Roo Shell, we will add a new 
orderStatus field to the 
PizzaOrder entity with the following Roo command. 
~.shared.OrderStatus roo> field enum --fieldName orderStatus --type ~.shared.OrderStatus --class ~.server.domain.PizzaOrder
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\request\PizzaOrderProxy.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileDetailsView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderDetailsView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderListView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileEditView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderEditView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder_Roo_ToString.aj
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder_Roo_JavaBean.aj
Updated SRC_TEST_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrderDataOnDemand_Roo_DataOnDemand.aj
~.server.domain.PizzaOrder roo>
 
 
We will also need to add a phoneNumber field to the 
PizzaOrder entity.
~.server.domain.PizzaOrder roo> field string --fieldName phoneNumber --notNull --sizeMin 7
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\request\PizzaOrderProxy.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileDetailsView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderDetailsView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderListView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileEditView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderEditView_Roo_Gwt.java
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderEditView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderMobileDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\client\managed\ui\PizzaOrderDetailsView.ui.xml
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder_Roo_ToString.aj
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder_Roo_JavaBean.aj
Updated SRC_TEST_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrderDataOnDemand_Roo_DataOnDemand.aj
~.server.domain.PizzaOrder roo>
 
 
Notice that the View files are automatically updated by Roo along with the 
PizzaOrder entity and associated AspectJ files.
We are ready to move on now that our 
PizzaOrder entity stores 
orderStatus and customer 
phoneNumber information. 
Adding a Finder Using the Roo Shell
Since the requirements state that customers will be entering their phone numbers to view the status of their 
PizzaOrders, we  will need to query 
PizzaOrders by customer phone number in the  
Status module.  However, this functionality is not generated with the  standard Roo-generated application and we will have to use Roo's 
finder add command  to generate a new finder method that creates the necessary query object  as shown below.
~.server.domain.PizzaOrder roo> finder add --finderName findPizzaOrdersByPhoneNumber
Updated SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder.java
Created SRC_MAIN_JAVA\com\blogspot\gwtsts\pizzashop\server\domain\PizzaOrder_Roo_Finder.aj~.server.domain.PizzaOrder roo> 
 
 
This command generates the 
PizzaOrder_Roo_Finder.aj AspectJ file that contains the necessary finder aspect and its 
findPizzaOrdersByPhoneNumber() method as shown below.
privileged aspect PizzaOrder_Roo_Finder {
    
    public static Query PizzaOrder.findPizzaOrdersByPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.length() == 0) throw new IllegalArgumentException("The phoneNumber argument is required");
        EntityManager em = PizzaOrder.entityManager();
        Query q = em.createQuery("SELECT PizzaOrder FROM PizzaOrder AS pizzaorder WHERE pizzaorder.phoneNumber = :phoneNumber");
        q.setParameter("phoneNumber", phoneNumber);
        return q;
    }
    
}
 
Notice that the new method returns a 
Query object, which will have to be executed to retrieve 
PizzaOrder objects.
Executing the Query
With Roo having generated the finder method for us, all we need to do is execute the 
Query via a call to its 
getResultList() method.  Adding the following method to the 
~.server.domain.PizzaOrder entity class will do the trick.
@RooJavaBean
@RooToString
@RooEntity(finders = { "findPizzaOrdersByPhoneNumber" })
public class PizzaOrder {
    ...
    @SuppressWarnings("unchecked")
    public static List<PizzaOrder> findPizzaOrderEntriesByPhoneNumber(String phoneNumber) {
        return PizzaOrder.findPizzaOrdersByPhoneNumber(phoneNumber).getResultList();
    }
}
 
At this point, our work on the server side has been completed, but we will need to create interfaces on the client side to be able to use our new finder method.
Request Extensions
Lets create extensions to 
PizzaOrderRequest and 
ApplicationRequestFactory interfaces on the client side in order to be able to use the 
findPizzaOrderEntriesByPhoneNumber() method that we created on the server side.
The following files will be created in the 
~.status.client.request package.
StatusPizzaOrderRequest.java:
@ServiceName("com.blogspot.gwtsts.pizzashop.server.domain.PizzaOrder")
public interface StatusPizzaOrderRequest extends PizzaOrderRequest {
    abstract Request<List<PizzaOrderProxy>> findPizzaOrderEntriesByPhoneNumber(String phoneNumber);
}
 
StatusRequestFactory.java:
public interface StatusRequestFactory extends ApplicationRequestFactory {
    StatusPizzaOrderRequest statusPizzaOrderRequest();
}
 
Our application is now able to query 
PizzaOrders by client's 
phoneNumber and we can go ahead and create our new module.
The Status Module
Our aim here is to create a new GWT module that will provide an interface for Pizza Shop users to query their 
PizzaOrders.  The new 
Status module will inherit the Roo-generated 
applicationScaffold module in order to make use of its data access functionality.  Firstly, we will need to remove the 
EntryPoint declaration in the 
applicationScaffold module as having multiple 
EntryPoints will result in successive calls to a different implementation of 
onModuleLoad() for each 
EntryPoint, which is not what we want.  Removing the following line from 
ApplicationScaffold.gwt.xml will allow us to inherit the 
applicationScaffold module without the extra call to 
applicationScaffold's own 
onModuleLoad() method.
<entry-point class="com.blogspot.gwtsts.pizzashop.client.scaffold.Scaffold"/>
 
There is a side-effect to this change; with its 
EntryPoint removed, the 
applicationScaffold module will not run.  We will have to create a new module and update our GWT host pages to allow existing functionality to work again.
Using the "New GWT Module" wizard, lets create a new module named Console in the ~.admin package.  The contents of 
Console.gwt.xml should be as follows.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.2.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.2.0/distro-source/core/src/gwt-module.dtd">
<module rename-to="console">
    <inherits name="com.blogspot.gwtsts.pizzashop.ApplicationScaffold" />
    <entry-point class="com.blogspot.gwtsts.pizzashop.client.scaffold.Scaffold"/>
</module>
 
Script declaration in 
ApplicationScaffold.html should be updated as follows.
<!doctype html>
<html>
    <head>
        ...
        <script type="text/javascript" language="javascript"
                src="console/console.nocache.js"></script>
    </head>
    <body style="-webkit-text-size-adjust: none;">
        ...
    </body>
</html>
 
The same requirement applies to the script declaration in 
console.html.
<!doctype html>
<html>
    <head>
        ...
        <script type="text/javascript" language="javascript"
                src="../console/console.nocache.js"></script>
    </head>
    <body style="-webkit-text-size-adjust: none;">
        ...
    </body>
</html>
 
With the side-effect taken care of, we can now go ahead and create the 
Status module itself using the "New GWT Module" wizard.  Contents of the resulting module definition file, 
Status.gwt.xml, should be as follows.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.2.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.2.0/distro-source/core/src/gwt-module.dtd">
<module rename-to="status">
    <inherits name="com.blogspot.gwtsts.pizzashop.ApplicationScaffold" />
    <source path="client"/>
</module>
 
The 
rename-to attribute has to be entered manually after the module definition file is generated by the wizard.
Next on our to-do list is to create a host page for our new module.  We will create the following HTML page using GPE's "New HTML Page" wizard.
<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>OrderStatus</title>
    <script type="text/javascript" language="javascript" src="status/status.nocache.js"></script>
  </head>
  <body>
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
  </body>
</html>
 
At this point, our module and HTML page have been created and we are ready to start creating our module's 
EntryPoint, 
View and 
Presenter classes.
GIN Support For the Status Module
We could have chosen not to use GIN since we will not be creating a mobile view, but we will use it in order to stay in line with the Roo-generated 
applicationScaffold module and to be ready in case we decide to add a mobile view in the future. 
The following classes and interfaces will be created in the 
~.status.client.ioc package.
StatusModule.java:
public class StatusModule extends AbstractGinModule {
    @Override
    protected void configure() {
        bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
        bind(StatusRequestFactory.class).toProvider(RequestFactoryProvider.class).in(Singleton.class);
        bind(PlaceController.class).toProvider(PlaceControllerProvider.class).in(Singleton.class);
    }
    static class PlaceControllerProvider implements Provider<PlaceController> {
        private final PlaceController placeController;
        @Inject
        public PlaceControllerProvider(EventBus eventBus) {
            this.placeController = new PlaceController(eventBus);
        }
        public PlaceController get() {
            return placeController;
        }
    }
    static class RequestFactoryProvider implements Provider<StatusRequestFactory> {
        private final StatusRequestFactory requestFactory;
        @Inject
        public RequestFactoryProvider(EventBus eventBus) {
            requestFactory = GWT.create(StatusRequestFactory.class);
            requestFactory.initialize(eventBus, new EventSourceRequestTransport(
                    eventBus, new GaeAuthRequestTransport(eventBus)));
        }
        public StatusRequestFactory get() {
            return requestFactory;
        }
    }
}
 
StatusInjector.java:
public interface StatusInjector extends Ginjector {
    StatusApp getStatusApp();
}
 
StatusDesktopInjector.java:
@GinModules(value = {StatusModule.class})
public interface StatusDesktopInjector extends StatusInjector {
    @Override
    public StatusDesktopApp getStatusApp();
}
 
StatusInjectorWrapper.java:
public interface StatusInjectorWrapper {
    StatusInjector getInjector();
}
 
StatusDesktopInjectorWrapper.java:
public class StatusDesktopInjectorWrapper implements StatusInjectorWrapper {
    @Override
    public StatusInjector getInjector() {
        return GWT.create(StatusDesktopInjector.class);
    }
}
 
Status Module's EntryPoint 
Using the "New Entry Point Class" wizard, lets create the following GWT 
EntryPoint class for the 
Status module.  The wizard will automatically add the 
entry-point configuration to our module definition file.
Status.java:
public class Status implements EntryPoint {
    final private StatusInjectorWrapper injectorWrapper = GWT.create(StatusDesktopInjectorWrapper.class);
    @Override
    public void onModuleLoad() {
        injectorWrapper.getInjector().getStatusApp().run();
    }
}
 
Following the pattern set by the 
Scaffold module, the following classes will be created in the 
~.status.client package.
StatusApp.java:
public class StatusApp {
    static boolean isMobile = false;
    public static boolean isMobile() {
        return isMobile;
    }
    public void run() {
    }
}
 
StatusDesktopApp.java:
public class StatusDesktopApp extends StatusApp {
    private final StatusDesktopShell shell;
    private final StatusRequestFactory requestFactory;
    private final EventBus eventBus;
    private final PlaceController placeController;
    private final StatusPlaceHistoryFactory placeHistoryFactory;
    private final StatusActivityMapper statusActivityMapper;
    @Inject
    public StatusDesktopApp(StatusRequestFactory requestFactory, EventBus eventBus,
                PlaceController placeController, StatusPlaceHistoryFactory placeHistoryFactory,
                StatusActivityMapper statusActivityMapper) {
        this.shell = StatusDesktopShell.instance();
        this.requestFactory = requestFactory;
        this.eventBus = eventBus;
        this.placeController = placeController;
        this.placeHistoryFactory = placeHistoryFactory;
        this.statusActivityMapper = statusActivityMapper;
    }
    public void run() {
        /* Add handlers, setup activities */
        init();
        /* And show the user the shell */
        RootLayoutPanel.get().add(shell);
    }
    private void init() {
        // AppEngine user authentication
        new ReloadOnAuthenticationFailure().register(eventBus);
        CachingActivityMapper activityMapper = new CachingActivityMapper(statusActivityMapper);
        final ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
        activityManager.setDisplay(shell.getDisplay());
  
        StatusPlaceHistoryMapper mapper = GWT.create(StatusPlaceHistoryMapper.class);
        mapper.setFactory(placeHistoryFactory);
        PlaceHistoryHandler placeHistoryHandler = new PlaceHistoryHandler(mapper);
        Place defaultPlace = new StatusQueryPlace();
        placeHistoryHandler.register(placeController, eventBus, defaultPlace);
        placeHistoryHandler.handleCurrentHistory();
    }
}
 
The 
@Inject annotation marks the constructor to be used by GIN.  GIN instantiates all arguments to the "annotated" constructor in the same manner and uses the default constructor in case a constructor with an 
@Inject annotation can't be found.
The call to 
placeHistoryHandler.handleCurrentHistory() method in 
StatusDesktopApp.init() is where the first 
PlaceChangeEvent is triggered.  This 
Place change to the default 
StatusQueryPlace allows the first 
Activity, the 
StatusQueryActivity, to be 
start()ed.
The View
The following classes and UiBinder files will be created in the 
~.status.client.ui package using the "New UiBinder" wizard. 
StatusDesktopShell.java:
public class StatusDesktopShell extends Composite {
    private static StatusDesktopShellUiBinder uiBinder = GWT
            .create(StatusDesktopShellUiBinder.class);
    
    @UiField
    SimplePanel display;
    interface StatusDesktopShellUiBinder extends
        UiBinder<Widget, StatusDesktopShell> {
    }
    public StatusDesktopShell() {
        initWidget(uiBinder.createAndBindUi(this));
    }
    
    public SimplePanel getDisplay() {
        return display;
    }
}
 
StatusDesktopShell.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
        xmlns:g="urn:import:com.google.gwt.user.client.ui">
    <ui:style>
        @def contentWidth 850px;
        .banner {
            background-color: #777;
            -moz-border-radius-topleft: 10px;
            -webkit-border-top-left-radius: 10px;
            -moz-border-radius-topright: 10px;
            -webkit-border-top-right-radius: 10px;
            margin-top: 1.5em;
            height: 4em;
        }
        .title {
            color: white;
            padding: 1em;
            position: absolute;
            color: #def;
        }
        .title h2 {
            margin: 0;
        }
        .centered {
            width: contentWidth;
            margin-right: auto;
            margin-left: auto;
        }
    </ui:style>
    <g:DockLayoutPanel unit='EM'>
        <g:north size='6'>
            <g:HTMLPanel styleName='{style.centered}'>
                <div class='{style.banner}'>
                    <span class='{style.title}'>
                        <h2>Pizza Order Status</h2>
                    </span>
                </div>
            </g:HTMLPanel>
        </g:north>
        <g:south size='2'>
            <g:HTML/>
        </g:south>
        <g:center>
            <g:SimplePanel styleName='{style.centered}' ui:field='display'/>
        </g:center>
    </g:DockLayoutPanel>
</ui:UiBinder>
 
StatusDesktopShell forms the frame or shell for other views in our module.  The 
SimplePanel labeled 'display' is the display region that is passed to our 
ActivityManager in 
StatusDesktopApp.init().  The 
ActivityManager will pass this display region on to each 
Activity it manages through the first argument of the 
Activity's 
start() method.
StatusQueryView.java:
public class StatusQueryView extends Composite implements View<StatusQueryView> {
    private static StatusQueryViewUiBinder uiBinder = GWT
            .create(StatusQueryViewUiBinder.class);
 
    private static StatusQueryView instance;
    interface StatusQueryViewUiBinder extends UiBinder<Widget, StatusQueryView> {
    }
    @UiField
    TextBox phoneNumber;
 
    @UiField
    Button query;
    private StatusQueryProxyView.Delegate delegate;
 
    public StatusQueryView() {
        initWidget(uiBinder.createAndBindUi(this));
    }
 
    public static StatusQueryView instance() {
        if (instance == null)
            instance = new StatusQueryView();
        return instance;
    }
 
    @UiHandler("query")
    void onQuery(ClickEvent event) {
        delegate.queryClicked();
    }
    @Override
    public void setDelegate(StatusQueryProxyView.Delegate delegate) {
        this.delegate = delegate;
    }
    @Override
    public String getPhoneNumber() {
        return phoneNumber.getText();
    }
}
 
StatusQueryView.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
        xmlns:g="urn:import:com.google.gwt.user.client.ui">
    <ui:style>
        
    </ui:style>
    <g:HTMLPanel>
        <table>
            <tr>
                <td>
                    <div>Phone Number:</div>
                </td>
                <td>
                    <g:TextBox ui:field='phoneNumber' />
                </td>
                <td>
                    <g:Button ui:field='query'>Query</g:Button>
                </td>
            </tr>
        </table>
    </g:HTMLPanel>
</ui:UiBinder>
 
StatusQueryView is shown in the display region when 
StatusQueryActivity is 
start()ed.
StatusDisplayView.java:
public class StatusDisplayView extends Composite implements
        View<StatusDisplayView> {
    private static StatusDisplayViewUiBinder uiBinder = GWT
            .create(StatusDisplayViewUiBinder.class);
    private static StatusDisplayView instance;
    interface StatusDisplayViewUiBinder extends
            UiBinder<Widget, StatusDisplayView> {
    }
    @UiField
    DivElement errors;
    @UiField
    Label status;
    public StatusDisplayView() {
        initWidget(uiBinder.createAndBindUi(this));
    }
    public static StatusDisplayView instance() {
        if (instance == null)
            instance = new StatusDisplayView();
        return instance;
    }
    @Override
    public void showErrors(List<EditorError> errors) {
        SafeHtmlBuilder b = new SafeHtmlBuilder();
        for (EditorError error : errors) {
            b.appendEscaped(error.getPath()).appendEscaped(": ");
            b.appendEscaped(error.getMessage()).appendHtmlConstant("<br>");
        }
        this.errors.setInnerHTML(b.toSafeHtml().asString());
    }
    @Override
    public void setStatus(String status) {
        this.status.setText(status);
    }
}
 
StatusDisplayView.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
        xmlns:g="urn:import:com.google.gwt.user.client.ui">
    <ui:style>
        .errors {
          padding-left: 0.5em;
          background-color: red;
        }
    </ui:style>
    <g:HTMLPanel>
        <div ui:field='errors' class='{style.errors}'></div>
        <table>
            <tr>
                <td>
                    <div>Status:</div>
                </td>
                <td>
                    <g:Label ui:field='status' />
                </td>
            </tr>
        </table>
    </g:HTMLPanel>
</ui:UiBinder>
 
The display region switches to the 
StatusDisplayView when 
StatusDisplayActivity is 
start()ed as a result of a 
Place change to 
StatusDisplayPlace.
Status Module's Places
There will be two 
Places in the 
Status module; a 
Place where customers will query the status of their pizza order and another where the status of their 
PizzaOrder will be displayed.  The following 
Places will be created in the 
~.status.client.place package.
StatusQueryPlace.java:
public class StatusQueryPlace extends Place {
    /**
     * Tokenizer.
     */
    public static class Tokenizer implements PlaceTokenizer<StatusQueryPlace> {
        public StatusQueryPlace getPlace(String token) {
            return new StatusQueryPlace();
        }
        public String getToken(StatusQueryPlace place) {
            return place.getClass().getName();
        }
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        return true;
    }
}
 
The 
StatusQueryPlace will be a simple 
Place with no additional fields.
StatusDisplayPlace.java:
public class StatusDisplayPlace extends Place {
    private static final String SEPARATOR = "!";
    /**
     * Tokenizer.
     */
    public static class Tokenizer implements PlaceTokenizer<StatusDisplayPlace> {
        public StatusDisplayPlace getPlace(String token) {
            String bits[] = token.split(SEPARATOR);
            return new StatusDisplayPlace(bits[1]);
        }
        public String getToken(StatusDisplayPlace place) {
            return place.getClass().getName() + SEPARATOR
                    + place.getPhoneNumber();
        }
    }
    private String phoneNumber;
    public StatusDisplayPlace(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        return true;
    }
    public String getPhoneNumber() {
        return phoneNumber;
    }
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}
 
The 
StatusDisplayPlace will be used to signal that a 
phoneNumber has been queried and pass this 
phoneNumber on to the 
StatusDisplayActivity.
History Management
The following files will be created in the 
~.status.client.place package.
StatusPlaceHistoryFactory.java:
public class StatusPlaceHistoryFactory {
    private final StatusQueryPlace.Tokenizer queryPlaceTokenizer;
    private final StatusDisplayPlace.Tokenizer displayPlaceTokenizer;
    @Inject
    public StatusPlaceHistoryFactory() {
        this.queryPlaceTokenizer = new StatusQueryPlace.Tokenizer();
        this.displayPlaceTokenizer = new StatusDisplayPlace.Tokenizer();
    }
    public PlaceTokenizer<StatusQueryPlace> getQueryPlaceTokenizer() {
        return queryPlaceTokenizer;
    }
    public PlaceTokenizer<StatusDisplayPlace> getDisplayPlaceTokenizer() {
        return displayPlaceTokenizer;
    }
}
 
StatusPlaceHistoryMapper.java:
public interface StatusPlaceHistoryMapper extends PlaceHistoryMapperWithFactory<StatusPlaceHistoryFactory> {
}
 
StatusPlaceHistoryFactory provides the accessor methods to 
PlaceTokenizers for all 
Places used in the module.  These 
PlaceTokenizers are passed to 
StatusPlaceHistoryMapper, which, together with the 
PlaceHistoryHandler, allows the forward and back buttons of your Web browser work.
Proxy Views
The following files will be created in the 
~.status.client.place package.
StatusProxyView.java:
public interface StatusProxyView<P extends EntityProxy, V extends StatusProxyView<P, V>>
            extends IsWidget {
}
 
StatusDisplayProxyView.java:
public interface StatusDisplayProxyView<P extends EntityProxy, V extends StatusProxyView<P, V>>
            extends StatusProxyView<P, V>, HasEditorErrors<P> {
public void setStatus(String status);
}
 
StatusQueryProxyView.java:
public interface StatusQueryProxyView<P extends EntityProxy, V extends StatusProxyView<P, V>>
            extends StatusProxyView<P, V> {
    /**
     * Implemented by the owner of the view.
     */
    interface Delegate {
        void queryClicked();
    }
    void setDelegate(Delegate delegate);
 
    String getPhoneNumber();
}
 
These 
ProxyViews are 
Presenter-side representations for our 
View implementations and provide a layer of abstraction between the 
Presenter and the 
View components of our MVP model.
Implementing the Presenter
Activity classes make up the 
Presenter component of the MVP model.  The following 
Activity classes will be created in the 
~.status.client.activity package.
StatusQueryActivity.java:
public class StatusQueryActivity extends AbstractActivity implements StatusQueryProxyView.Delegate {
private PlaceController placeController;
    private StatusQueryProxyView<PizzaOrderProxy, ?> view;
    public StatusQueryActivity(PlaceController placeController,
            StatusQueryProxyView<PizzaOrderProxy, ?> view, StatusRequestFactory requests) {
        this.placeController = placeController;
        this.view = view;
    }
    @Override
    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        view.setDelegate(this);
        panel.setWidget(view);
    }
    @Override
    public void queryClicked() {
        placeController.goTo(new StatusDisplayPlace(view.getPhoneNumber()));
    }
}
 
StatusQueryActivity is the default 
Activity that is 
start()ed when the 
Status module is loaded.  It responds to clicks on the Query button by extracting the 
phoneNumber from the 
View and changing the current 
Place to 
StatusDisplayPlace.
StatusDisplayActivity.java:
public class StatusDisplayActivity extends AbstractActivity {
    private PlaceController placeController;
    private StatusDisplayProxyView<PizzaOrderProxy, ?> view;
    private StatusRequestFactory requests;
    public StatusDisplayActivity(PlaceController placeController,
                StatusDisplayProxyView<PizzaOrderProxy, ?> view, StatusRequestFactory requests) {
        this.placeController = placeController;
        this.view = view;
        this.requests = requests;
    }
    @Override
    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        Place place = placeController.getWhere();
        if (place instanceof StatusDisplayPlace) {
            StatusDisplayPlace displayPlace = (StatusDisplayPlace) place;
            requests.statusPizzaOrderRequest().findPizzaOrderEntriesByPhoneNumber(displayPlace.getPhoneNumber()).fire(new Receiver<List<PizzaOrderProxy>>() {
                @Override
                public void onSuccess(List<PizzaOrderProxy> response) {
                    if (response.size() > 0) {
                        view.setStatus(response.get(0).getOrderStatus().toString());
                    }
                    else {
                        view.setStatus("Order not found");
                    }
                }
                @Override
                public void onFailure(ServerFailure error) {
                    view.setStatus(error.getMessage());
                }
            });
        }
        panel.setWidget(view);
    }
}
 
StatusQueryActivity is 
start()ed when the current 
Place is changed to 
StatusDisplayPlace.  It executes the finder method that retrieves all 
PizzaOrders with maching 
phoneNumber values from the server.  If the request is successfully processed, then the 
onSuccess() method is called with the server response as its argument.  The implementation shown above displays only the first item on the list or an error message if the list is empty.
StatusActivityMapper.java:
public class StatusActivityMapper implements ActivityMapper {
    private PlaceController placeController;
    private StatusRequestFactory requests;
    
    @Inject
    public StatusActivityMapper(StatusRequestFactory requests, PlaceController placeController) {
        this.requests = requests;
        this.placeController = placeController;
    }
    @Override
    public Activity getActivity(Place place) {
        if (place instanceof StatusQueryPlace)
            return makeQueryActivity();
  
        if (place instanceof StatusDisplayPlace)
            return makeDisplayActivity();
  
        return null;
    }
 
    private Activity makeQueryActivity() {
        Activity activity = new StatusQueryActivity(placeController,
                StatusQueryView.instance(), requests);
        return new StatusQueryActivityWrapper(activity, requests, StatusQueryView.instance());
    }
 
    private Activity makeDisplayActivity() {
        Activity activity = new StatusDisplayActivity(placeController,
                StatusDisplayView.instance(), requests);
        return new StatusDisplayActivityWrapper(activity, requests, StatusDisplayView.instance());
    }
}
 
The 
StatusActivityMapper's sole job is to map 
Places to corresponding 
Activitys.  The 
ActivityManager calls its 
getActivity() method in response to 
PlaceChangeEvents to get the 
Activity that corresponds to the next 
Place.
StatusActivityWrapper.java:
abstract public class StatusActivityWrapper implements Activity {
protected Activity wrapped; 
    protected ApplicationRequestFactory requests;
    @Override
    public String mayStop() {
        return wrapped.mayStop();
    }
    @Override
    public void onCancel() {
        wrapped.onCancel();
    }
    @Override
    public void onStop() {
        wrapped.onStop();
    }
    @Override
    public void start(AcceptsOneWidget panel, EventBus eventBus) {
        wrapped.start(panel, eventBus);
    }
}
 
StatusQueryActivityWrapper.java:
public class StatusQueryActivityWrapper extends StatusActivityWrapper {
    public interface View<V extends StatusQueryProxyView<PizzaOrderProxy, V>> extends StatusQueryProxyView<PizzaOrderProxy, V> {
    }
    
    protected View<?> view;
 
    public StatusQueryActivityWrapper(Activity activity, ApplicationRequestFactory requests, View<?> view) {
        this.wrapped = activity;
        this.requests = requests;
        this.view = view;
    }
}
 
StatusDisplayActivityWrapper.java:
public class StatusDisplayActivityWrapper extends StatusActivityWrapper {
    public interface View<V extends StatusDisplayProxyView<PizzaOrderProxy, V>> extends StatusDisplayProxyView<PizzaOrderProxy, V> {
    }
    
    protected View<?> view;
 
    public StatusDisplayActivityWrapper(Activity activity, ApplicationRequestFactory requests, View<?> view) {
        this.wrapped = activity;
        this.requests = requests;
        this.view = view;
    }
}
 
The 
ActivityWrappers provide a layer of abstraction between the wrapped 
Activity and the 
Presenter-side representation of the 
View.
Source Code
I have uploaded the source code for the Pizza Shop Web application including all changes made in this post.  It can be downloaded via this 
link.
Uploaded to App Engine 
The new version of Pizza Shop application has been uploaded to App Engine and can be viewed at 
http://pizzashopexample.appspot.com/OrderStatus.html.  The order submitted with phone number '1234567' should have a status of  'NEW_ORDER' and '7654321' should be in the 'OVEN'.
What is Next?
Check out my 
review of Ashish Sarin's 
Spring Roo 1.1 Cookbook.  I recommend this book to everyone who wants to learn more about Roo or to add Spring Security to their application.