Using a generic backing bean actions framework
In this recipe we will create a base backing bean class that we will use to encapsulate common functionality for common JSF page actions, such as committing and rolling back data, creating new records, deleting records and so on. Creating and using such a generic backing bean actions framework will guarantee that you provide consistent functionality throughout the application and encapsulate common functionality at a base class level. This class is not intended to be used as a utility class. Any new helper methods that were developed to demonstrate the recipe were added to the ADFUtils
utility class discussed earlier in this chapter.
Getting ready
We will be adding the generic backing bean actions framework to the SharedComponents
ViewController project that we developed in the Breaking up the application in multiple workspaces recipe in this chapter.
How to do it…
1. Right-click on the shared ViewController project and select New….
2. On the New Gallery dialog, select Java under the General category and Java Class from the list of items on the right.
3. On the Create Java Class dialog, enter
CommonActions
for the class name andcom.packt.jdeveloper.cookbook.shared.view.actions
for the class package.4. Let's go ahead and add methods to provide consistent commit functionality:
public void commit(ActionEvent actionEvent) { if (ADFUtils.hasChanges()) { // allow derived beans to handle before commit actions onBeforeCommit(actionEvent); // allow derived beans to handle commit actions onCommit(actionEvent); // allow derived beans to handle after commit actions onAfterCommit(actionEvent); } else { // display "No changes to commit" message JSFUtils.addFacesInformationMessage(BundleUtils. loadMessage("00002")); } } protected void onBeforeCommit(ActionEvent actionEvent) { } /** protected void onCommit(ActionEvent actionEvent) { // execute commit ADFUtils.execOperation(Operations.COMMIT); } protected void onAfterCommit(ActionEvent actionEvent) { // display "Changes were committed successfully" message JSFUtils.addFacesInformationMessage(BundleUtils. loadMessage("00003")); }
5. We have also added similar methods for consistent rollback behaviour. To provide uniform record creation/insertion functionality, let's add these methods:
public void create(ActionEvent actionEvent) { if (hasChanges()) { onCreatePendingChanges(actionEvent); } else { onContinueCreate(actionEvent); } } protected void onBeforeCreate(ActionEvent actionEvent) { // commit before creating a new record ADFUtils.execOperation(Operations.COMMIT); } public void onCreate(ActionEvent actionEvent) { execOperation(Operations.INSERT); } protected void onAfterCreate(ActionEvent actionEvent) { } public void onCreatePendingChanges(ActionEvent actionEvent) { ADFUtils.showPopup("CreatePendingChanges"); } public void onContinueCreate(ActionEvent actionEvent) { onBeforeCreate(actionEvent); onCreate(actionEvent); onAfterCreate(actionEvent); }
6. Similar methods were added for consistent record deletion behaviour. In this case, we have added functionality to show a delete confirmation pop-up.
How it works…
To provide consistent functionality at the JSF page actions level, we have implemented the commit(), rollback(), create()
, and remove()
methods. Derived backing beans should handle these actions by simply delegating to this base class via calls to super.commit(), super.rollback()
, and so on. The base class commit()
implementation first calls the helper ADFUtils.hasChanges()
to determine whether there are transaction changes. If there are, then the onBeforeCommit()
is called to allow derived backing beans to perform any pre-commit processing. Commit processing continues by calling onCommit()
. Again, derived backing beans can override this method to provide specialized commit processing. The base class implementation of onCommit()
calls the helper ADFUtils.execOperation()
to execute the Operations.COMMIT
bound operation. The commit processing finishes by calling the onAfterCommit()
. Derived backing beans can override this method to perform post-commit processing. The default base class implementation displays a Changes were committed successfully message on the screen.
The generic functionality for a new record creation is implemented in the create()
method. Derived backing beans should delegate to this method for default record creation processing by calling super.create()
. In create()
, we first check to see if we have any changes to the existing transaction. If we do, we will inform the user by displaying a message dialog. We do this in the onCreatePendingChanges()
method. The default implementation of this method displays the CreatePendingChanges
confirmation pop-up. The derived backing bean can override this method to handle this event in a different manner. If the user chooses to go ahead with the record creation, the onContinueCreate()
is called. This method calls onBeforeCreate()
to handle precreate functionality. The default implementation commits the current record by calling ADFUtils.execOperation(Operations.COMMIT)
. Record creation continues with calling onCreate()
. The default implementation of this method creates and inserts the new record by calling ADFUtils.execOperation(Operations.INSERT)
. Finally, onAfterCreate()
is called to handle any creation post processing.
The generic rollback and record deletion functionality is similar. For the default delete processing, a pop-up is displayed asking the user to confirm whether the record should be deleted or not. The record is deleted only after the user's confirmation.
There's more…
Note that this framework uses a number of pop-ups in order to confirm certain user choices. Rather than adding these pop-ups to all JSF pages, these pop-ups are added once to your JSF page template, providing reusable pop-ups for all of your JSF pages. In order to support this generic functionality, additional plumbing code will need to be added to the actions framework. We will talk at length about it in the Using page templates for pop-up reuse recipe in Chapter 7,Face Value: ADF Faces, JSPX Pages and Components
See also
Using page templates for pop-up reuse, Chapter 7,Face Value: ADF Faces, JSPX Pages and Components
Breaking up the application in multiple workspaces, in this chapter