Controller Components

The Struts framework provides a rich set of features upon which an implementation can be based. The decisions to be taken at this point include:

In this application, the actions performed in the content pane of a given page exhibit a high degree of cohesion. Consider, for example, the Compose page. The actions of sending, saving a draft, adding an attachment, etc. are all associated with a message. At this point in the design process the definition of business objects comprising the model have not been addressed, but one perceives that some sort of “message object” can assumed to be in play. Similarly, actions in the Folder page will cohere around some sort of “folder object”.

This cohesion leads to the decision to group related actions into single Action objects associated with each of the Compose, Folder, and Read pages. The Address Book and Address Select pages will share one Action object, since they can be assumed to deal with some manner of object representing an address book entry.

Struts provides two standard Action objects which are useful for mapping a set of user actions to a set of methods in a single Action objects. The org.apache.struts.actions.DispatchAction maps the values of a configured parameter to names of methods in the object. Similarly, org.apache.struts.actions.LookupDispatchAction maps the localized values of the labels of form submission buttons to methods, via a reverse mapping from the label value back to the resource value. .

From the UI Type column in Table 1, we see that there will be a mix of these two types of submission. This led me to the conception of a general purpose Action class combining the capabilities of the Struts DispatchAction and LookupDispatchActon. This GeneralDispatchAction serves as the parent class of the ComposeAction, FolderAction, AddressAction and ReadAction classes.

(All Java classes in this project are rooted in a package "com.micromail". I have omitted the package prefixes here for simplicity. You can view the entire javadoc set here.)

Table 2 records the same page transition mapping information as Table 1, but adds specification of the Action classes, and the methods within each, required to handle each type of submission.

Origin Page

Action Trigger Label

Action Class

Method Name

Condition

Destination Page

(Browser login dialog)

Submit

LoginAction

execute

new user

New User

existing user

Folder

New User

Proceed

NewUserAction

registerPersonalName

 

Folder

any (menu pane)

Compose

ComposeAction

compose

 

Compose

any (menu pane)

Inbox/Sent/Drafts/Trash

FolderAction

selectFolder

 

Folder

any (menu pane)

Address Book

AddressAction

goTo

 

Address Book

Address Book

Save Address

AddressAction

save

 

Address Book

Address Book

Edit

AddressAction

edit

 

Address Book

Address Book

Delete

AddressAction

delete

 

Address Book

Address Select

Insert Selected Addresses

AddressAction

insert

 

Compose

Compose

Addresses

ComposeAction

selectAddresses

 

Address Select

Compose

Save Draft

ComposeAction

saveDraft

 

Folder

Compose

Send

ComposeAction

send

 

Folder

Compose

Browse

(browser)

    Compose

Compose

Add

ComposeAction

addAttachment

 

Compose

Compose

Delete Selected Attachments

ComposeAction

deleteAttachments

 

Compose

Folder

Sort

FolderAction

sort

 

Folder

Folder

Delete

FolderAction

delete

 

Folder

Folder

Read

FolderAction

read

 

Read

Folder

Select All

(javascript)

    Read

Read

Delete

ReadAction

delete

folder not empty

Read

folder empty

Folder

Read

Next/Previous

ReadAction

next / previous

 

Read

Read

Forward

ReadAction

forward

 

Compose

Read

Reply

ReadAction

reply

 

Compose

Read

Reply All

ReadAction

replyAll

 

Compose

Read

Resume Draft

ReadAction

resumeDraft

 

Compose

I chose to use a single DynaActionForm class to be populated with submitted form data. The total number of possible parameters is fairly small