Realization of Site Administration Use Cases


The following subsections will provide the use case realization for use cases in the Site Administration package.

Note

The following subsections will provide readers with an opportunity to understand class interactions and dependencies visualized through class and sequence diagrams. Please refer to Chapter 1 for use case descriptions. Recurring solutions have been documented as patterns to enhance the readability and reuse of the GreaterCause implementation.

Manage NPO Profile Use Case

The task of updating the NPO Profile information is preceded by the registration process. However, since this is a much simpler implementation, it is being discussed before other use cases. Several concepts exposed in this section will create the foundation for realizing other use cases. Figure 5-6 illustrates a class diagram for realizing this use case; the semantics of this class diagram is explained using the multi-page pattern.

click to expand
Figure 5-6: Manage NPO Profile class diagram

start sidebar
Pattern Discovery and Documentation

Object-oriented architectures contain repeatable solutions, also called patterns. Recognizing and documenting these patterns promotes reuse of solutions that otherwise may be implemented by another developer in a different way, thus reducing manageability and increasing complexity of the system. Patterns establish a vocabulary for the system, and permit efficient reuse of this vocabulary in the design and implementation phases. A problem solved by one developer can be reapplied in several other scenarios. Harvesting such reusable design patterns, applied within a context, will provide leverage for other parts of the solution because such patterns are proven to follow best practices and have endured the test of time. The advantage of using patterns is that it will make the software easier to understand by the development team, reduces the complexity of the system, and builds upon the success of other developers.

In later sections, I have attempted to document certain recurring solutions discerned in the course of developing the GreaterCause site administration services. The recurring solutions are documented to assist the readers in understanding how certain complex user interactions can be addressed using the Struts framework. Use of these proven techniques enables faster assimilation of Struts functionality into applications. Hopefully, these patterns will serve as templates for our readers, and a starting point from which to evolve.

end sidebar

Multi-Page Pattern

This pattern is applicable when user interaction constitutes a series of forms. Functionally, it may be desirable to collect information from multiple pages into a single form-bean for accomplishing a unit of work. Using fewer form-beans keeps the number of form-beans to a minimum, and keeps related data together. It is easier to manage changes when page semantics are altered because the changes are localized to a single form-bean.

Structure The implementation of this pattern employs the page property of the form-bean. If the form-bean extends ValidatorForm, then it will inherit the page property from the ValidatorForm; if the form-bean extends the ActionForm, then this property will have to be defined in the form-bean. Figure 5-7 and Figure 5-8 illustrates the static and dynamic aspects of the multi-page pattern. Updating NPO profile is a two-step process when the site administrator impersonates an NPO administrator. First, as illustrated in Figure 5-9, the site administrator has to specify the EIN (for identifying a non-profit) it would like to impersonate; in the next step, the system allows the site administrator to update the profile information, as illustrated in Figure 5-10. The NPO administrator is taken directly to the update page without the intervening Enter EIN page because the system can identify the related EIN using the NPO administrator's login username. Figure 5-8 shows the usage of the page property in controlling the process flow within the request handler.

click to expand
Figure 5-7: Multi-page pattern

click to expand
Figure 5-8: Multi-page pattern sequence diagram

click to expand
Figure 5-9: Enter EIN

click to expand
Figure 5-10: Update Profile

Note

All class diagrams using the stereotype <<View>>, do not show the intermediate Struts controller for the sake of simplifying the diagram. The controller will intercept the request resulting from a view and invoke the corresponding request handler. Also, note that with few exceptions, the view names used in pattern diagrams are labeled using their <forward> names of struts-config.xml file.

In the sample application, we use the page field (as a hidden field) in most forms for two reasons:

  • The site administrator navigation scheme is different from the navigation scheme of the NPO administrator. The site administrator can impersonate an NPO administrator, and therefore has to specify the EIN as a precursor to most operations. The Enter EIN page has the page field set to 1.

  • The validations performed by the ValidatorForm.validate method have to be advised which properties must be validated based on the navigation scheme chosen for different administrators. For example, the ein property is not required to be validated when the administrator is an NPO administrator. Please refer to the section "Factoring Validator into the Design Process" for further details.

Configuration Semantics The struts-config.xml declarations are shown in the following code. The site administrator is attached to an extra step "/ManageNPOStep1", which is invoked from the navigation bar illustrated in the next subsection.

 <form-bean name="ManageNPOForm" type="com.gc.prez.admin.ManageNPOForm"/> <!-- Site Administration step invoked from navigation bar --> <action path="/ManageNPOStep1" forward="/2_4B_EnterEIN.jsp"/> <action path="/ManageNPOStep2"     type="com.gc.prez.admin.ManageNPOAction"     name="ManageNPOForm"     scope="session" validate="false">     <forward name="EnterEIN" path="/2_4B_EnterEIN.jsp"/>     <forward name="ShowNPOProfile" path="/2_4_2_UpdateNPOProfile.jsp"/>     <forward name="success" path="/2_SiteAdministratorServicesMainPage.jsp"/> </action> 

Please note that the ActionMapping identified by the path "/ManageNPOStep2" will have three possible ActionForward(s); the resulting views are discussed in the next section.

View Semantics The following snippet is from the dynamic navigation bar 2_Administration ServicesNavBar that is included with all administrator JSPs. The navigation bar will invoke the ActionMapping identified by the path/render "/ManageNPOStep1" which will invoke the view 2_4B_EnterEIN.jsp shown next; in turn this view will use the ActionMapping identified by the path "/ManageNPOStep2". The NPO administrator will use the ActionMapping identified by the path "/ManageNPOStep2", which will invoke the view 2_4_2_UpdateNPOProfile.jsp shown later in this subsection.

 <gc:hasAccess role="SiteAdminRole">     ... rest of JSP ...     <html:link page="/ManageNPOStep1.do"> <!-- Invoke 2_4B_EnterEIN.jsp -->         <bean:message key="NPOAdminServices.UpdateProfile"/>     </html:link><br><br>     ... rest of JSP ... </gc:hasAccess> <gc:hasAccess role="NPOAdminRole">     ... rest of JSP ...         <html:link page="/ManageNPOStep2.do"> <!-- Invoke                                            2_4_2_UpdateNPOProfile.jsp -->             <bean:message key="NPOAdminServices.UpdateProfile"/>         </html:link><br><br>     ... rest of JSP ... </gc:hasAccess> 

The view 2_4B_EnterEIN.jsp will result in the invocation of the request handler ManageNPOAction using the ActionMapping identified by the path "/ManageNPOStep2" (refer to struts-config.xml shown earlier) with the page attribute property of the corresponding form-bean set to 1. The view 2_4B_EnterEIN.jsp is shown here:.

 <html:form method="POST" action="/ManageNPOStep2.do" focus="ein">     <table border="0" cellspacing="0" cellpadding="5">         <tr>             <td ><bean:message key="SiteAdminServices.EnterEIN"/></td>             <td><html:text property="ein" size="14" maxlength="14"/></td>             <html:hidden property="page" value="1"/>         </tr>         <tr>             <td>&nbsp;</td>             <td><html:submit><bean:message key="prompt.Submit"/>                 </html:submit></td>         </tr>     </table> </html:form> 

ActionMapping identified by the path "/ManageNPOStep2" will be responsible for invoking the request handler ManageNPOAction. This request handler will render the view 2_4_2_UpdateNPOProfile.jsp. This is discussed in the Request Handler section of this pattern. The view 2_4_2_UpdateNPOProfile.jsp can also invoke the request handler using the ActionMapping identified by the path "/ManageNPOStep2" (refer to struts-config.xml shown earlier) with the page property of the corresponding form-bean set to 2. The view 2_4_2_UpdateNPOProfile.jsp is shown here:

 <html:form method="POST" action="/ManageNPOStep2.do" focus="firstName">     <html:hidden property="page" value="2"/>     ... rest of JSP ...     <p align="center"><html:submit><bean:message key="prompt.Update"/></html:submit></p> </html:form> 

ActionForm Bean The action form-bean corresponding to ActionMapping identified by the path "/ManageNPOStep2" is shown here. A single form is used to store information gathered from two views, namely, 2_4B_EnterEIN.jsp and 2_4_2_UpdateNPOProfile.jsp.

 public class ManageNPOForm extends ValidatorForm implements Serializable {     public ManageNPOForm() {     }     /* EIN is collected from page 1 */     public String getEin() {         return ein;     }     public void setEin( String ein ) {         this.ein = ein;     }     ... rest of the accessors ...     //Form Data     private String ein;     private String adminID;     private String firstName;     private String lastName;     private String email;     private String phone;     private String url;     private String missionStatement;     public void reset( ActionMapping mapping, HttpServletRequest req ) {     }     public ActionErrors validate( ActionMapping mapping,     HttpServletRequest req ) {         ActionErrors errors = new ActionErrors();         /* NPO Administrator does not have to specify an EIN */         if ( ( page ==1)&&((ein== null ) ||            ( ein.trim().length() < 1 ) ) ) {             errors.add( "ein", new ActionError( "error.ein.required" ) );         }         /* Call the validate method of ValidatorForm */         else if ( page == 2 ) {             errors = super.validate( mapping, req );         }         return errors;     } } 

Request Handler This request handler is created from the ActionMapping identified by the path "/ManageNPOStep2". The page attribute property will identify the current page, which will also decide the resulting ActionForward shown earlier. Note that for the NPO administrator, the initial invocation of the request handler will have the page attribute property set to the value 0 because no HTML form with a page parameter has been processed yet; the first view displayed to the NPO administrator will be the profile page with the page attribute property set to 2. The semantics of the corresponding request handler is illustrated using the following code fragment. Please refer to Figure 5-8 for a high-level sequencing diagram.

 public class ManageNPOAction extends Action {     public ActionForward execute( ActionMapping mapping,     ActionForm form, HttpServletRequest req,     HttpServletResponse res ) throws Exception {         ManageNPOForm npoForm = ( ManageNPOForm )form;         ActionErrors errors = npoForm.validate( mapping, req );         /* Ensure EIN is present on EnterEIN page (First page for          * site administrator) */         if ( npoForm.getPage() == 1 ) {                 if ( !errors.empty() ) {                 saveErrors( req, errors );                 return mapping.findForward( "EnterEIN" );             }             /* Show profile information if EIN is provided              * (page 2 for updating profile information)*/             return showNPOProfile( mapping, form, req, res );         }         /* The Profile page is identified by page == 2 */         if ( npoForm.getPage() == 2 ) {             if ( !errors.empty() ) {                 saveErrors( req, errors );                 return mapping.findForward( "ShowNPOProfile" );             }             return ( updateProfile( mapping, form, req, res ) );         }         /* 'page' property is set to 0 for NPO Administrator,          * and this step is executed */         return showNPOProfile( mapping, form, req, res );     }     public ActionForward showNPOProfile( ActionMapping mapping,         ActionForm form, HttpServletRequest req,         HttpServletResponse res ) throws Exception {         ... rest of the code ...         return mapping.findForward( "ShowNPOProfile" );     }     public ActionForward updateProfile( ActionMapping mapping,         ActionForm form, HttpServletRequest req,         HttpServletResponse res ) throws Exception {         ... rest of the code ...         return mapping.findForward( "success" );     } } 

Register Portal-Alliance Use Case

A site administrator can create and update the registration information for a portal-alliance. However, the portal-alliance administrator can only view this information. Figure 5-11 illustrates the class diagram for realizing this use case; the semantics of this class diagram is explained using the multi-action pattern.

click to expand
Figure 5-11: Register portal-alliance class diagram

Multi-Action Pattern Using the Action Class Strategy

A multi-action pattern can be used for enabling a request handler to process different actions (a.k.a. commands) submitted by one or more forms. The sample application defines three actions: create, update, and view. If different forms are utilized for each of these actions, then related fields will be spread across, or duplicated across, multiple forms, which creates redundancy and defeats modularity; in this scenario, a change in the form will require retrofitting several forms. The multi-action pattern enables creation of multiple views from a single JSP based on the action chosen by the user, while allowing the same request handler to service all variations of the view (in this case, a JSP).

Structure Both, dynamic view creation and request processing are synergistic functions. The participating view must indicate the initiated "action," and the request handler must save this knowledge in a JavaBean (which is usually the form-bean) for controlling conditional processing. The intent projected by the state of the action property in the form-bean will subsequently influence the view generated from a single JSP. The Portal-Alliance Registration use case is realized using a multi-action pattern in conjunction with a multi-page pattern. Figures 5-12 and 5-13 illustrate the static and dynamic aspects of the multi-action pattern. Figure 5-13 shows the usage of the action property in controlling the process flow within the request handler.

click to expand
Figure 5-12: Multi-action form pattern

click to expand
Figure 5-13: Multi-action form pattern sequence diagram

Configuration Semantics The struts-config.xml declarations are shown in the following code. In this pattern, we will use a single Action class and a corresponding ActionForm. The ActionForm extends ValidatorForm, which provides the page property for muti-page interaction, as explained in the section "Multi-Page Pattern."

 <action path="/PortalAllianceRegistration"         type="com.gc.prez.admin.PortalAllianceRegistrationAction"         name="PortalAllianceRegistrationForm"         scope="session"         validate="false">     <forward name="ShowPage" path="/2_1_PortalAllianceRegistration.jsp"/>     <forward name="EnterPortalID" path="/2_3A_EnterPortalID.jsp"/>     <forward name="success" path="/2_SiteAdministratorServicesMainPage.jsp"/> </action> 

Please note that the ActionMapping identified by the path "/PortalAllianceRegistration" will have three possible ActionForward(s); the resulting views are discussed in the next section.

View Semantics The following snippet is from the dynamic navigation bar 2_Administration ServicesNavBar that is included with all administrator JSPs. Observe that all requests are directed to same URL, "/PortalAllianceRegistration", which is the identifier for the ActionMapping object that will be used by the framework for invoking the associated request handler PortalAllianceRegistrationAction. Because the "Update" action by the site administrator requires a Portal ID, the request handler will invoke the view 2_3A_EnterPortalID.jsp. For the "View" action by the portal-alliance administrator, the request handler will use the login username to identify the associated Portal ID. Observe that the request time action parameter is used for setting the action property in the corresponding form-bean shown later.

 <gc:hasAccess role="SiteAdminRole">     <html:link page="/PortalAllianceRegistration.do?action=Create">         <bean:message key="SiteAdminServices.PortalRegistration"/>     </html:link><br> </gc:hasAccess> <gc:hasAccess role="SiteAdminRole">     <html:link page="/PortalAllianceRegistration.do?action=Update">         <bean:message key="SiteAdminServices.UpdatePortalRegistration"/>     </html:link><br> </gc:hasAccess> <gc:hasAccess role="PortalAdminRole">     <html:link page="/PortalAllianceRegistration.do?action=View">         <bean:message key="PortalAdminServices.ViewRegistration"/> </gc:hasAccess> 

The view 2_3A_EnterPortalID.jsp will invoke the request handler PortalAllianceRegistrationAction using the ActionMapping identified by the path "/PortalAllianceRegistration" (refer to struts-config.xml shown earlier) with the page property of the corresponding form-bean set to 1. The view 2_3A_EnterPortalID.jsp is shown here:

 <html:form method="POST" action="/PortalAllianceRegistration.do" focus=portalID">     <html:hidden property="page" value="1"/>     <table border="0" cellspacing="0" cellpadding="5">         <tr>             <td ><bean:message                     key="SiteAdminServices.EnterPortalID"/></td>             <td><html:text property="portalID" size="16" maxlength="16"/></td>         </tr>         <tr>             <td>&nbsp;</td>             <td><html:submit><bean:message key="prompt.Submit"/></html:submit>             </td>         </tr>     </table> </html:form> 

The view 2_1_PortalAllianceRegistration.jsp will invoke the request handler using the ActionMapping identified by the path "/ PortalAllianceRegistration" (refer to struts-config.xml shown earlier) with the page attribute property of the corresponding form-bean set to 2. The action property of the form beanform-bean PortalAllianceRegistrationForm is checked for the values Create/Update/View; the <logic:equal> custom tag will conditionally display parts of the JSP based on the value of the action property. The view 2_1_PortalAllianceRegistration.jsp.jsp is shown here:

 <html:form method="POST" action="/PortalAllianceRegistration.do"            focus="portalID">      <html:hidden property="page" value="2"/>            <logic:equal name="PortalAllianceRegistrationForm"                        property="action" scope="session" value="Create">                        ... display the registration creation part ...            <html:submit>                <bean:message key="prompt.Register"/>            </html:submit></td>       </logic:equal>       <logic:equal name="PortalAllianceRegistrationForm"                      property="action" scope="session" value="Update">          ... display the registration update part ...          <html:submit>             <bean:message key="prompt.Update"/>          </html:submit>       </logic:equal>       <logic:equal name="PortalAllianceRegistrationForm"                         property="action" scope="session" value="View">             ... display the registration view part ...             <html:submit>                <bean:message key="prompt.Back"/>             </html:submit>       </logic:equal> </html:form> 

ActionForm Bean The action form-bean corresponding to ActionMapping identified by the path "/PortalAllianceRegistration" is shown here. The form has the action and the page property that is used for controlling the application flow. The page is inherited from ValidatorForm.

 public class PortalAllianceRegistrationForm extends ValidatorForm implements Serializable {    public PortalAllianceRegistrationForm() {    }    public String getAction() {        return action;    }    public void setAction( String action ) {        this.action = action;    }    ... rest of the accessors ...    private String action;    private String portalID;    private String adminID;    private String portalName;    private String email;    private String activationDate;    private String testCertification;    public void reset( ActionMapping mapping,    HttpServletRequest req ) {        ... rest of the code ...    }    public ActionErrors validate( ActionMapping mapping,    HttpServletRequest req ) {        ... rest of the code ...        return errors;    } } 

Request Handler This request handler is created from the ActionMapping identified by the path "/PortalAllianceRegistration". The page property is used to identify the HTML form being currently processed. Please review the entire code in the accompanying source distribution to see how the action property is used in conjunction with the page property.

The following code fragment demonstrates how the request handler PortalAllianceRegistrationAction uses the same form to provide different views for different user actions. In this example, the site administrator can create and update the Portal Alliance Registration, whereas a portal-alliance administrator can only view the registration information. Please refer to Figure 5-13 for a high-level sequence diagram.

 public class PortalAllianceRegistrationAction extends Action {    public ActionForward execute( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {       PortalAllianceRegistrationForm regForm =          ( PortalAllianceRegistrationForm )form;       String action = regForm.getAction();       if ( action.equals( "Create" ) )       { return ( createRegistration( mapping, form, req, res ) ); }       else if ( action.equals( "Update" ) ) {          return ( updateRegistration( mapping, form, req, res ) );       }       else if ( action.equals( "View" ) )       { return ( viewRegistration( mapping, form, req, res ) ); }       else { return null; }    }    public ActionForward createRegistration( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {       ... rest of the code ...       return mapping.findForward( "success" );    }    public ActionForward updateRegistration( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {       ... rest of the code ...       return mapping.findForward( "success" );    }    public ActionForward viewRegistration( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {       ... rest of the code ...       return mapping.findForward( "success" );    } } 

Manage Portal-Alliance Profile Use Case

The development of this use case has been combined with the Perform UI Customization use case by making use of the multi-action pattern discussed in the preceding section. Figure 5-14 illustrates the static model used in the realization of this use case.

click to expand
Figure 5-14: Manage portal-alliance class diagram

Multi-Action Pattern Using Action Class Strategy

The implementation here is only slightly different from the one used in the "Register Portal-Alliance Use Case" section. Here we define two actions—updateProfile and navigationBarSetup— to realize the use cases ‘Manage Portal-Alliance Profile’ and Perform UI Customization, respectively. The only difference in this implementation is that the actions are associated with different views, as depicted later in the upcoming "Configuration Semantics" section.

Structure Figures 5-15 and 5-16 illustrates the static and dynamic aspects of the multi-action pattern. Figure 5-16 shows the usage of page and action properties in controlling the process flow within the request handler

click to expand
Figure 5-15: Multi-action pattern

click to expand
Figure 5-16: Multi-action pattern sequence diagram

Configuration Semantics The struts-config.xml declarations are shown here. In this pattern, we will use a single Action class and a corresponding ActionForm. The ActionForm extends ValidatorForm, which provides the page property for mutlti-page interaction:

 <action path="/EnterPortalID"    name="ManagePortalAllianceForm"    scope="session"    validate="false"    forward="/2_3B_EnterPortalID.jsp"/> <action path="/ManagePortalAlliance"    type="com.gc.prez.admin.ManagePortalAllianceAction"    name="ManagePortalAllianceForm"    scope="session"    validate="false">    <forward name="EnterPortalID" path="/2_3B_EnterPortalID.jsp"/>    <forward name="ShowPortalProfile" path="/2_3_2_UpdatePortalProfile.jsp"/>    <forward name="ShowNavigationBarSetup" path="/2_3_3_PortalNavBar.jsp"/>    <forward name="success" path="/2_SiteAdministratorServicesMainPage.jsp"/> </action> 

Note that the ActionMapping identified by the path "/ManagePortalAlliance" will have four possible ActionForward(s). The ShowPortalProfile <forward> declaration is selected for updateProfile action, which will result in the view illustrated in Figure 5-17; and the ShowNavigationBarSetup <forward> declaration is selected for navigationBarSetup action, which will result in the view illustrated in Figure 5-18 . The rest of the semantics are similar to the one demonstrated in the "Register Portal-Alliance Use Case" section. Readers are encouraged to review the implementation provided in the accompanying CD-ROM.

click to expand
Figure 5-17: Update portal-alliance profile

click to expand
Figure 5-18: Update navigation bar URL

Request Handler The request handler in this case has to track the page sequence, that is the value of the page property of two different views, and the action property of these views; this makes the request handler slightly complex to implement. The semantics of the request handler is illustrated using the following code fragment. Please refer to Figure 5-16 for a high-level sequence diagram.

 public class ManagePortalAllianceAction extends Action {    public ActionForward execute( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {       ManagePortalAllianceForm portalForm =                ( ManagePortalAllianceForm )form;       ActionErrors errors = portalForm.validate( mapping, req );       String action = portalForm.getAction();       /* First page for Site Administrator */       if ( !errors.empty() && portalForm.getPage() ==1){           saveErrors( req, errors );           return mapping.findForward( "EnterPortalID" );       }       /* Second page for updating profile */       if ( ( !errors.empty() ) && ( portalForm.getPage() == 2 )          && ( action.equals( "updateProfile"))){           saveErrors( req, errors );           return mapping.findForward( "ShowPortalProfile" );       }       /* Second page for navigation bar setup */       if ( ( !errors.empty() ) && ( portalForm.getPage() ==2)&&       ( action.equals( "navigationBarSetup"))){           saveErrors( req, errors );           return mapping.findForward( "ShowNavigationBarSetup" );       }       /* Page number is 0, i.e. request handler was invoked from        * navigation bar by portal-alliance administrator using the          "Update Profile" or the Navigation Bar Setup" link*/       if ( action.equals( "updateProfile")){           return ( updateProfile( mapping, form, req, res ) );       }       if ( action.equals( "navigationBarSetup")){          return ( navigationBarSetup( mapping, form, req, res ) );       }       return null;    }    public ActionForward updateProfile( ActionMapping mapping,    ActionForm form, HttpServletRequest req, HttpServletResponse res )    throws Exception {        ... rest of the code ...    }    public ActionForward navigationBarSetup( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) throws Exception {        ... rest of the code ...    } } 

Register NPO Use Case

A site administrator can create and update the registration information for a non-profit, while the NPO administrator can only view this information. Figure 5-19 illustrates the class diagram for realizing this use case; the semantics of this class diagram are explained in the following section.

click to expand
Figure 5-19: Register NPO class diagram

Multi-Action Pattern Using DispatchAction Class Strategy

The multi-action pattern discussed in the section "Register Portal-Alliance Use Case" was implemented using an Action subclass. The Struts framework invokes the execute method on a request handler that extends the Action class. In this section, we will implement the multi-action pattern using the DispatchAction subclass. When a request handler extends the DispatchAction class, it must provide a parameter attribute in the <action> declaration of the struts-config.xml file, whose value is the name of a request time parameter that will be used to identify method names to be called in the DispatchAction subclass. This is depicted shortly in the "Configuration Semantics" section. The advantage of being able to specify method names other than the standard execute method is that the request handler methods can be directly coupled to user actions, embedded within the HTML form, rather than having to route all actions through the execute method. In the following subsections, we will look at an implementation that is identical in terms of functionality to the Register Portal Alliance Use Case but differs in implementation.

Structure Figures 5-20, 5-21, and 5-22 illustrates the static and dynamic aspects of the multi-action pattern using the DispatchAction class strategy. Figure 5-21 shows the setting of the action property as a result of the method call specified in the navigation bar using the request time parameter method (refer to the subsection "View Semantics" for more information); Figure 5-22 shows how the action property is used to control the process flow within the request handler.

click to expand
Figure 5-20: Multi-action pattern using dispatch action class strategy

click to expand
Figure 5-21: Multi-action pattern sequence diagram

click to expand
Figure 5-22: Multi-action pattern sequence diagram

Configuration Semantics The struts-config.xml declarations are shown here. Observe the parameter attribute specification that identifies the request time parameter method to be used for identifying the request handler method that will be called instead of the execute method.

 <action path="/NPORegistration"    type="com.gc.prez.admin.NPORegistrationAction"    name="NPORegistrationForm"    scope="session"    parameter="method"    validate="false">    <forward name="ShowPage" path="/2_2_NPORegistration.jsp"/>    <forward name="EnterEIN" path="/2_4A_EnterEIN.jsp"/>    <forward name="success" path="/2_SiteAdministratorServicesMainPage.jsp"/> </action> 

View Semantics Again, the following snippet is from the dynamic navigation bar 2_AdministrationServicesNavBar that is included with all administrator JSPs. Observe that all requests are directed to same URL "/NPORegistration", which is the identifier for the ActionMapping object that will be used by the framework for invoking the associated request handler NPORegistrationAction. However, in this case the execute method of the request handler is not invoked; instead, the method to be invoked is specified by the request time parameter method, as shown next. Each of the methods shown in the following snippet is responsible for setting the corresponding action property; this was illustrated in Figure 5-21.

 <gc:hasAccess role="SiteAdminRole">    <html:link page="/NPORegistration.do?method=ShowNPORegistrationForm">       <bean:message key="SiteAdminServices.NPORegistration"/>    </html:link><br><br> </gc:hasAccess> <gc:hasAccess role="NPOAdminRole">    <html:link page="/NPORegistration.do?method=viewRegistration">       <bean:message key="NPOAdminServices.ViewRegistration"/>    </html:link><br><br> </gc:hasAccess> <gc:hasAccess role="SiteAdminRole">    <html:link page="/NPORegistration.do?method=preUpdateRegistration">       <bean:message key="SiteAdminServices.UpdateNPORegistration"/>    </html:link><br> </gc:hasAccess> 

In the preceding snippet, a selection on the navigation bar will first invoke a method that will set the desired action and then exit with an ActionForward pertinent to that action. For example, the ShowNPORegistration method will execute the following code:

 public ActionForward ShowNPORegistrationForm( ActionMapping mapping,    ActionForm form, HttpServletRequest req,    HttpServletResponse res ) {       NPORegistrationForm regForm = ( NPORegistrationForm )form;       regForm.setAction( "Create" );       saveToken( req );       return mapping.findForward( "ShowPage" ); } 

Comparing the DispatchAction subclass strategy with the Action subclass strategy, it is obvious that while this strategy reduces the complexity in the request handler, it introduces extra methods for displaying the initial view (the process start-up view). Applications with complex navigation schemes can benefit from this strategy at the cost of coupling the method invocations to the request time method parameter specified in the HTML form; however, it does take away the need to specify the action parameter at request time, as shown in the section View Semantics for the Multi-Action Pattern Using the Action Class Strategy.

The views participating in this use case, namely, 2_4A_EnterEIN.jsp and 2_2_NPORegistration .jsp, both invoke the method multiplexer of the request handler NPORegistrationAction (again, using the request time method parameter); this method has similar functionality as the execute method of the PortalAllianceRegistrationAction of the Register Portal Alliance Use Case. All other semantics of the DispatchAction subclass strategy are similar to the Action subclass strategy, readers are urged to review the implementation provided with the accompanying source distribution for additional details.




Practical J2ee Application Architecture
Practical J2EE Application Architecture
ISBN: 0072227117
EAN: 2147483647
Year: 2003
Pages: 111
Authors: Nadir Gulzar

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net