C H A P T E R  13

Tutorial--Section 3.1
Create a Command Component

This chapter describes how to create a Command component that can be reused by many command fields (button and HREF components) within the same application. This is the alternative technique to implementing request handling code in the command field's handle request event inside its parent page/pagelet class (handleLoginRequest in LoginPage, for example).

Commands provide great power and flexibility when it comes to code reuse. Any arbitrary Java class can become a Command component simply by implementing the com.iplanet.jato.command.Command interface. In this tutorial, you will create a new Command class using the Suntrademark ONE Application Framework Command wizard to create a login/logout command which will replace the request handler event for the Login button. This Command component can then be reused by command fields on other pages and pagelets if required.


Task 1: Create a Command Component

Create the UserAccessCommand Component

Create a Command component using the Sun ONE Application Framework Command wizard.

1. Select the main module folder, then click the Add Command button on the Sun ONE Application Framework toolbar.

This figure shows the main module folder and the Add Command button that you should select. 

The Select Command Type panel displays.

This figure shows the Select Command Type panel. 

2. Enter UserAccessCommand in the Name textbox.

3. Select Basic Command.

4. Click Finish.

The UserAccessCommand component is added to the application.

 The figure on the left shows the UserAccessCommand component. The figure on the right shows the code.

Double-click the UserAccessCommand to open the Java source code for this component in the editor window.

It is quite a simple class that extends BasicCommand. BasicCommand implements the Command interface which declares only one method:
public void execute(CommandEvent) throws CommmandException

This command currently does nothing. You will need to add some code to the execute method to do what you need it to do, which is, to perform a user login or logout based on the operation name that is passed in via the CommandEvent parameter. The operation names are completely up to the developer (you). The following steps and tasks instruct you on how to pass and evaluate your custom operation names.

Add Code to the execute Method

This step requires nothing more than writing a little code. This might seem like a lot of code, but much of it is reimplementation of the handleLoginRequest event from the LoginPage. This replaces the need for that button event.

Add the following code to the execute method of the UserAccessCommand class.

public void execute(CommandEvent event) throws CommandException
{
    // get the RequestContext
    RequestContext requestContext = event.getRequestContext();
 
    // get the J2EE HttpSession
    javax.servlet.http.HttpSession session = 
 
        requestContext.getRequest().getSession();
 
    // get the operation name that was passed in 
    // by the commandfield object (button/href)
    String opName = event.getOperationName();
 
    // get the LoginPage
    LoginPage loginVB = (LoginPage)requestContext
        .getViewBeanManager().getViewBean(LoginPage.class);
 
    // perform user login
    if (opName.equals("login"))
    {
        // get the customer number that was entered
        int custNum = loginVB.getDisplayFieldIntValue(
            LoginPage.CHILD_CUSTOMER_NUM);
 
        // get the Customer model
        CustomerModel customerModel = (CustomerModel)requestContext
            .getModelManager().getModel(CustomerModel.class);
 
        // execute the CustomerModel with the customer number as criteria
        // to see if the user exists in the database
        customerModel.clearUserWhereCriteria(); 
        customerModel.addUserWhereCriterion(
            "CUSTOMER_TBL_CUSTOMER_NUM", new Integer(custNum));
 
        try
         {
            customerModel.executeSelect(null);
         }
 
        catch (ModelControlException e)
         {
            Log.log("Exception caught in UserAccessCommand.execute(): "
                 + e.toString());
         }
 
        catch (java.sql.SQLException e)
         {
            Log.log("Exception caught in UserAccessCommand.execute(): "
                 + e.toString());
         }
 
        // valid customer number entered
        if (customerModel.getNumRows() == 1) 
         {
            // Display the Customer page
            requestContext.getViewBeanManager().getViewBean(
                 CustomerPage.class).forwardTo(requestContext);
            // put the customer number into an HttpSession attribute
            // for potential use in a later request
            session.setAttribute("hsaCustNum", new Integer(custNum));
         }
 
        // invalid customer number entered
        else
         {
            String msg = "Sorry, " + custNum + 
                 " is not a valid customer number."; 
 
            // Set the output status message
            loginVB.getDisplayField(
                 LoginPage.CHILD_MESSAGE).setValue(msg);
            loginVB.forwardTo(requestContext);
         }
    } // if opName = login
 
    // perform user logout
    else if (opName.equals("logout"))
    {
         // get the customer number from session to use in the logout message
         String hsaCustNum = session.getAttribute("hsaCustNum").toString();
 
         String msg = "Customer " + hsaCustNum + 
            ", you have logged out successfully.";
 
         // invalidate the user's HttpSession
         session.invalidate();
 
         // Set the logout message and display the Login page
         loginVB.getDisplayField(LoginPage.CHILD_MESSAGE).setValue(msg); 
         loginVB.forwardTo(requestContext);
    } // else if opName = logout
 
    else
         throw new CommandException(
                 "Unknown UserAccessCommand operation name: " + opName);
}

Before you can test run this code, you need to configure a command field (Button or HREF) to use it.

Configure a Button's Command Descriptor

Configure the login button to use the UserAccessCommand component via the Command Descriptor property of the button. This also works the same for HREFS.

1. Expand the LoginPage node, and expand the Visual Components node.

2. Select the login button under Visual Components.

This figure shows the expanded Visual Components node with the login button. 

3. Click the ellipsis button for the Request Handler property.

This displays the Command Descriptor editor.

This figure shows the Command Descriptor editor. 

4. Select User-Defined Command (Default) from the list under the Create new shared instance radio button choice.

5. Change the Name property to userAccessCommand

6. Select the Component Properties tab at the bottom of the editor.

This figure shows the Component Properties tab at the bottom of the editor. 

7. Click the ellipsis button for the Command Class Name property.

This displays the Command Class Chooser dialog.

This figure shows the Command Class Chooser dialog. 

8. Expand the Current Application Components node, then jatoturial, and then main.

9. Select the UserAccessCommand command component.

10. Click OK.

11. Change the Operation Name from DEFAULT to login.

Recall in the code what you implemented for the execute method in the UserAccessCommand class. You have an if/else block that is expecting either login or logout as an operation name. These are case sensitive, so you need to be sure you set this correctly, or you will receive the CommandException (Unknown operation name) when you test run this command.

This figure shows the Operation Name entry to update from DEFAULT to login. 

12. Click OK to finish setting the Command Descriptor property for the login button.

Now, when you run the Login page and click the Login button, the UserAccessCommand component handles the request instead of the code in the handleLoginRequest event in the LoginPage.

You can leave the code in the handleLoginRequest event as is, because it will be never be invoked, unless you reconfigure the login button to use the request handler event instead of the command component.

This is because the Sun ONE Application Framework first looks for a Command Descriptor for the command field. If the Command Descriptor is not implemented, it then attempts to invoke the handle<CommandField>Request event. If the event is not implemented, you receive a request handler not found exception.