6.2. Use a Page enum for Wizards

Here's just a bit of good old-fashioned advice; consider using an enum to track the state of your wizards.

For example, the ClaimWizard in the example app has the following enum defined:

@NotPersistable
public class ClaimWizard extends AbstractDomainObject {

    public enum Page {
        INTRO("This wizard will take you through the process of creating a claim"), 
        CLAIMANT("Enter the claimant that is making this claim"), 
        APPROVER("By default, the claimant's own approver will approve this claim.  " +
          "Update here if another approver will approve this claim."), 
        DESCRIPTION("Update the description if required."), 
        SUMMARY("Confirm all details, or go back and amend if needed");

        private String description;
        private Page(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }

        public boolean hasPrevious() {
            return ordinal() > 0;
        }
        public Page previous() {
            if (hasPrevious()) {
                return values()[ordinal() - 1];
            } else {
                return this;
            }
        }

        public boolean hasNext() {
            return ordinal() < values().length - 1;
        }
        public Page next() {
            if (hasNext()) {
                return values()[ordinal() + 1];
            } else {
                return this;
            }
        }

        @Ignore
        public boolean is(Page... pages) {
            for (Page page : pages) {
                if (page == this) {
                    return true;
                }
            }
            return false;
        }
    }

    ...
}

This not only defines the descriptions of each Page, it also includes some logic for the previous() and next() actions to delegate to:

@NotPersistable
public class ClaimWizard extends AbstractDomainObject {

    // {{ Page
    private Page page;
    @Hidden
    public Page getPage() { ... }
    public void setPage(final Page page) { ... }
    // }}


    // {{ Page Description
    @WizardPageDescription
    @MemberOrder(sequence = "1")
    public String getPageDescription() { ... }

    // {{ previous
    @MemberOrder(sequence = "1")
    public void previous() {
        setPage(getPage().previous());
    }
    public String disablePrevious() {
        return coalesce(noPreviousPage(), confirmIfOnSummaryPage());
    }
    private String noPreviousPage() {
        return !getPage().hasPrevious() ? "no previous page" : null;
    }
    // }}

    // {{ next
    @MemberOrder(sequence = "2")
    public void next() {
        setPage(getPage().next());
    }
    public String disableNext() {
        return coalesce(noNextPage(), confirmIfOnSummaryPage());
    }
    private String noNextPage() {
        return !getPage().hasNext() ? "no next page" : null;
    }
    // }}

    ...
}