Oracle JDeveloper 11gR2 Cookbook

By Nick Haralabidis
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Prerequisites to Success: ADF Project Setup and Foundations

About this book

Oracle’s Application Development Framework (ADF) for Fusion Web Applications leverages Java EE best practices and proven design patterns to simplify constructing complex web solutions with JDeveloper, and this hands-on, task-based cookbook enables you to realize those complex, enterprise-scale applications. With the help of real-world implementations, practical recipes cover everything from design and construction, to deployment, testing, debugging and optimization.

This practical, task-based cookbook takes you, the ADF developer, on a practical journey for building Fusion Web Applications. By implementing a range of real world use cases, you will gain invaluable and applicable knowledge for utilizing the ADF framework with JDeveloper 11gR2.

“Oracle JDeveloper 11gR2 Cookbook” is a task-based guide to the complete lifecycle of Fusion Web Application development using Oracle JDeveloper 11gR2 and ADF.

You will get quickly up and running with concepts like setting up Application Workspaces and Projects, before delving into specific Business Components such as Entity Objects, View Objects, Application Modules and more. Along the way you will encounter even more practical recipes about ADF Faces UI components and Backing Beans, and the book rounds off by covering security, session timeouts and exceptions.

With “Oracle JDeveloper 11gR2 Cookbook” in hand you will be equipped with the practical knowledge of a range of ready to use implementation cases which can be applied to your own Fusion Web ADF Applications.

Publication date:
January 2012
Publisher
Packt
Pages
406
ISBN
9781849684767

 

Chapter 1. Prerequisites to Success: ADF Project Setup and Foundations

In this chapter, we will cover:

  • Installation of JDeveloper on Linux

  • Breaking up the application in multiple workspaces

  • Setting up BC base classes

  • Setting up logging

  • Using a custom exception class

  • Using ADFUtils/JSFUtils

  • Using page templates

  • Using a generic backing bean actions framework

Introduction

JDeveloper and ADF (Application Development Framework) are amazing technologies. What makes them even more incredible is their sheer complexity and the amount of knowledge and effort that lies covered underneath the declarative, almost magical frontend. What amazes me is that once you scratch the surface, you never stop realizing how much you really don't know. Given this complexity, it becomes obvious that certain development guidelines and practices must be established and followed early in the architectural and design phases of an ADF project.

This chapter presents a number of recipes that are geared towards establishing some of these development practices. In particular, you will see content that serves as a starting point in making your own application modular when using the underlying technologies. You will also learn the importance of extending the Business Components framework (ADF-BC) base classes early in the development cycle. We will talk about the importance of laying out other application foundational components, such as logging and exceptions, again early in the development process, and continue with addressing reusability and consistency at the ViewController layer.

The chapter starts with a recipe about installing and configuring JDeveloper on Linux. So, let's get started and don't forget, have fun as you go along. If you get in trouble at any point, take a look at the accompanying source code and feel free to contact me anytime at .

 

Introduction


JDeveloper and ADF (Application Development Framework) are amazing technologies. What makes them even more incredible is their sheer complexity and the amount of knowledge and effort that lies covered underneath the declarative, almost magical frontend. What amazes me is that once you scratch the surface, you never stop realizing how much you really don't know. Given this complexity, it becomes obvious that certain development guidelines and practices must be established and followed early in the architectural and design phases of an ADF project.

This chapter presents a number of recipes that are geared towards establishing some of these development practices. In particular, you will see content that serves as a starting point in making your own application modular when using the underlying technologies. You will also learn the importance of extending the Business Components framework (ADF-BC) base classes early in the development cycle. We will talk about the importance of laying out other application foundational components, such as logging and exceptions, again early in the development process, and continue with addressing reusability and consistency at the ViewController layer.

The chapter starts with a recipe about installing and configuring JDeveloper on Linux. So, let's get started and don't forget, have fun as you go along. If you get in trouble at any point, take a look at the accompanying source code and feel free to contact me anytime at .

 

Installation of JDeveloper on Linux


Installation of JDeveloper is, in general, a straightforward task. So, "why have a recipe for this?" you might ask. Did you notice the title? It says "on Linux". You will be amazed at the number of questions asked about this topic on a regular basis on the JDeveloper and ADF OTN Forum. Besides, in this recipe, we will also talk about configuration options and the usage of 64-bit JDK along with JDeveloper.

Getting ready

You will need a Linux installation of JDeveloper to use this recipe. For the 64-bit configuration, you will need a 64-bit Linux distribution and a 64-bit version of the Java SDK. We will install the latest version of JDeveloper, which is version 11.1.2.1.0 at the time of this writing.

How to do it...

  1. 1. Download JDeveloper from the Oracle JDeveloper Software download page: http://www.oracle.com/technetwork/developer-tools/jdev/downloads/index.html.

  2. 2. Accept the license agreement, select Linux Install, and click on Download File to begin with the download.

  3. 3. Once the file is downloaded, open a console window and start the installation, by typing the following commands:

    $ chmod u+x ./jdevstudio11121install.bin
    $ ./jdevstudio11121install.bin
    
  4. 4. On the Choose Middleware Home Directory page, select Create a new Middleware Home and enter the Middleware home directory.

  5. 5. On the Choose Install Type page, select Complete to ensure that JDeveloper, ADF and WebLogic Server are installed.

  6. 6. Once you confirm your selections, proceed with the installation.

  7. 7. Upon a successful installation, you will see the Installation Complete page. Uncheck the Run Quickstart checkbox and click Done.

  8. 8. To start JDeveloper, go to the /jdeveloper/jdev/bin directory under the Middleware home directory you specified during the installation and type the following:

    $ ./jdev
    
  9. 9. To make things easier, create an application launcher on your Linux desktop for the specific path indicated in the previous step.

How it works...

As noted earlier, installing JDeveloper on Linux is a straightforward task. You simply have to download the binary executable archive and run it. Ensure that you give execute permissions to the installation archive file and run it as noted. If you are having trouble seeing the Welcome page in graphical mode, ensure that the $DISPLAY environment variable is set correctly. The important thing to know here is the name of the file to execute in order to start JDeveloper. As mentioned, it is called jdev and it is located in the /jdeveloper/jdev/bin directory under the Middleware home directory.

There's more...

Now that you have successfully installed JDeveloper, let's spend some time configuring it for optimal performance. Configuration parameters are added to any of the jdev.conf or ide.conf files located in the /jdeveloper/jdev/bin and /jdeveloper/ide/bin directories respectively, under the Middleware home directory.

The following is a list of the important tuning configuration parameters with some recommendations for their values:

Parameter

Description

AddVMOption -Xmx

This parameter is defined in the ide.conf file and indicates the maximum limit that you will allow the JVM heap size to grow to. In plain words, it is the maximum memory that JDeveloper will consume on your system. When setting this parameter, consider the available memory on your system, the memory needed by the OS, the memory needed by other applications running concurrently with JDeveloper, and so on. On a machine used exclusively for development with JDeveloper, as a general rule of thumb consider setting it to around 50 percent of the available memory.

AddVMOption -Xms

This parameter is also defined in the ide.conf and indicates the initial JVM heap size. This is the amount that will be allocated initially by JDeveloper and it can grow up to the amount specified by the previous -Xmx parameter. When setting this parameter, consider whether you want to give JDeveloper a larger amount in order to minimize frequent adjustments to the JVM heap. Setting this parameter to the same value as the one indicated by the -Xmx parameter will supply a fixed amount of memory to JDeveloper.

AddVMOption -XX:MaxPermSize

This parameter indicates the size of the JVM permanent generation used to store class definitions and associated metadata. Increase this value if needed in order to avoid java.lang.OutOfMemoryError: PermGen space errors. A 256MB setting should suffice.

AddVMOption -DVFS_ENABLE

Set it to true in jdev.conf if your JDeveloper projects consist of a large number of files, especially if you will be enabling a version control system from within JDeveloper.

Configuring JDeveloper with a 64-bit JDK

The JDeveloper installation is bundled by default with a 32-bit version of the Java JDK, which is installed along with JDeveloper. On a 64-bit system, consider running JDeveloper with a 64-bit version of the JDK. First download and install the 64-bit JDK. Then configure JDeveloper via the SetJavaHome configuration parameter in the jdev.conf. This parameter should be changed to point to the location of the 64-bit JDK. Note that the 64-bit JDK is supported by JDeveloper versions 11.1.1.4.0 and higher.

Configuring the JDeveloper user directory

This is the directory used by JDeveloper to identify a default location where files will be stored. JDeveloper also uses this location to create the integrated WebLogic domain and to deploy your web applications when running them or debugging them inside JDeveloper. It is configured via the SetUserHomeVariable parameter in the jdev.conf file. It can be set to a specific directory or to an environment variable usually named JDEV_USER_DIR. Note that when JDeveloper is started with the singleuser command-line argument, the user directory is created inside the /jdeveloper directory under the Middleware home directory.

Note

Before starting your development in JDeveloper, consider setting the XML file encoding for the XML files that you will be creating in JDeveloper. These files among others include, the JSF pages, the business component metadata files, application configuration files, and so on. You set the encoding via the Tools | Preferences… menu. Select the Environment node on the left of the Preferences dialog and the encoding from the Encoding drop-down. The recommended setting is UTF-8 to support multi-lingual applications.

Note

The minimum recommended open file descriptors limit for JDeveloper on a Linux system is 4096. Use the command ulimit n to determine the open file descriptors limit for your installation and change it if needed in the limits.conf file located in /etc/security/ directory.

 

Breaking up the application in multiple workspaces


When dealing with large enterprise scale applications, the organization and structure of the overall application in terms of JDeveloper workspaces, projects, and libraries is essential. Organizing and packaging ADF application artifacts, such as business components, task flows, templates, Java code, and so on, into libraries will promote and ensure modularity, and the reuse of these artifacts throughout the application. In this recipe, we will create an application that comprises reusable components. We will construct reusable libraries for shared components, business domain specific components, and a main application for consuming these components.

How to do it…

  1. 1. To create the SharedComponents library, start by selecting New Application… in the Application Navigator. This will start the application creation wizard.

  2. 2. In the New Gallery dialog, click on the Applications node (under the General category) and select Fusion Web Application (ADF) from the list of Items.

  3. 3. In the Name your application page, enter the Application Name, Directory and the Application Package Prefix.

  4. 4. In the Name your project page, enter the business component's Project Name and Directory. For this recipe, we have called it SharedBC.

  5. 5. In the Configure Java settings page for the business components project, accept the defaults for Default Package, Java Source Path, and Output Directory.

  6. 6. Similarly, in the Name your project page for the ViewController project, enter the Project Name and Directory. For this recipe, we have called the project SharedViewController. Ensuring that you enter a unique package structure for both projects is the best guarantee for avoiding naming conflicts when these projects are deployed as ADF Library JARs.

  7. 7. Accept the defaults in the Configure Java settings and click Finish to proceed with the creation of the workspace.

  8. 8. Now, in the Application Navigator, you should see the two projects comprising the SharedComponents workspace, one for the business components and another for the ViewController.

  9. 9. You will be using this workspace to add reusable business and ViewController components. For now, we will package the workspace into an ADF library JAR, without any components in it yet. In order to do this, you will need to first setup the project dependencies. Double-click on the SharedViewController project to bring up the Project Properties dialog and select Dependencies.

  10. 10. Click on Edit Dependencies (the small pen icon) to bring up the Edit Dependencies dialog and then click on the Build Output checkbox under the business components project.

  11. 11. Click OK to close the dialog and return to the Project Properties dialog.

  12. 12. The next step is to set up the deployment profile. While at the ViewController Project Properties dialog, click on the Deployment node.

  13. 13. Since we will not be deploying this application as a WAR, select the default WAR deployment profile generated automatically by JDeveloper and delete it.

  14. 14. Then, click New… to create a new deployment profile.

  15. 15. On the Create Deployment Profile dialog, select ADF Library JAR File for the Profile Type and enter the name of the deployment profile. For this recipe, we have called the deployment profile SharedComponents. Click OK to proceed with its creation.

  16. 16. In the Edit ADF Library JAR Deployment Profile Properties dialog that is opened, select JAR Options and specify a location where you will be placing all the reusable JAR libraries. For this recipe, we will place all reusable libraries in a directory called ReUsableJARs.

  17. 17. When done, completely exit from the Project Properties dialog, saving your changes by clicking OK.

  18. 18. The last step involves the creation of the ADF Library JAR. You do this by right-clicking on the ViewController project in the Application Navigator selecting Deploy and then the name of the deployment profile name (SharedComponents in this case).

  19. 19. Select Deploy to ADF Library JAR file in the Deployment Action page and click Finish to initiate the deployment process. The deployment progress will begin. Its status is shown in the Deployment tab of the Log window.

  20. 20. To create the HRDepartments components library, similarly create a new Fusion web application for the HRDepartment components. Follow the previous steps to setup the project dependencies. No database connection to the HR schema is needed at this stage.

  21. 21. Create the deployment profile and deploy the ADF Library JAR. We will not be placing any components yet in this library.

  22. 22. To create the HREmployees components library, repeat the previous steps once more in order to create another ADF Library JAR for the HR Employee related reusable components.

  23. 23. Now create another Fusion web application, which will be used as the main application. This application will consume any of the components that reside in the ADF Library JARs created in the previous steps.

  24. 24. This can easily be done via the Resource Palette by creating a file system connection to the directory where we saved the reusable ADF Library JARs, that is, the directory called ReUsableJARs. If the Resource Palette is not visible, select View | Resource Palette to show it. In the Resource Palette, click on the New icon and select New Connection | File System….

  25. 25. In the Create File System Connection dialog that is displayed, enter the name of the connection and the directory where you have deployed the reusable components in the previous steps.

  26. 26. Click OK to continue. You should be able to see the new File System Connection in the Resource Palette.

  27. 27. To consume reusable components, first select the appropriate project on the Application Navigator, then right-click on the ADF Library JAR on the Resource Palette and select Add to Project….

  28. 28. On the Confirm Add ADF Library dialog, click on the Add Library button to proceed.

  29. 29. Alternatively, expand the ADF Library JAR and drag-and-drop the reusable component onto its appropriate place in the workspace.

How it works…

When you deploy a project as an ADF Library JAR, all ADF reusable components and code are packaged in it and they become available to other consuming applications and libraries. Reusable components include business components, database connections, data controls, task flows, task flow templates, page templates, declarative components, and of course Java code. By setting up the dependencies among the business components and ViewController projects in the way that we have—that is, including the build output of the business components project during the deployment of the ViewController project—you will be producing a single ADF Library JAR file with all the components from all the projects in the workspace. When you add an ADF Library JAR to your project, the library is added to the project's class path. The consuming project can then use any of the components in library. The same happens when you drag-and-drop a reusable component into your project.

There's more…

For this recipe, we packaged both of the business components and ViewController projects in the same ADF Library JAR. If this strategy is not working for you, you have other options, such as adjusting the dependencies among the two and packaging each project in a separate ADF Library JAR. In this case, you will need an additional deployment profile and a separate deployment for the business components project.

Adding the ADF Library JAR manually

You can add an ADF Library JAR into your project manually using the Project Properties dialog. Select the Libraries and Classpath node and click on the Add Library… button. This will display the Add Library dialog. On it, click the New… button to display the Create Library dialog. Enter a name for the library, select Project for the library location, and click on the Deployed by Default check button. Finally, click on the Add Entry… button to locate the ADF Library JAR. The Deployed by Default checkbox when checked indicates that the library will be copied to the application's destination archive during deployment of the consuming application. If you leave it unchecked, then the library will not be copied and it must be located in some other way (for example, deployed separately as a shared library on the application server).

Defining the application module granularity

One related topic that also needs to be addressed in the early architectural stages of the ADF project is the granularity for the application modules, that is, how the data model will be divided into application modules. As a general rule of thumb, each application module should satisfy a particular use case. Related use cases and, therefore, application modules can then be packaged into the same reusable ADF Library JAR. In general, avoid creating monolithic application modules that satisfy multiple use cases each.

Entity objects, list of values (LOVs), validation queries

Entity objects, list of values (LOVs) and validation queries should be defined only once for each business components project. To avoid duplication of entity objects, LOVs and validation queries among multiple business components projects, consider defining them only once in a separate business components project.

Note

Structuring of the overall ADF application in reusable components should be well thought and incorporated in the early design and architectural phases of the project.

As your application grows, it is important to watch out for and eliminate circular dependencies among the reusable components that you develop. When they occur, this could indicate a flaw in your design. Use available dependency analyzer tools, such as Dependency Finder (available from http://depfind.sourceforge.net) during the development process, to detect and eliminate any circular dependencies that may occur.

 

Setting up BC base classes


One of the first things to consider when developing large-scale enterprise applications with ADF-BC is to allow for the ability to extend the framework's base classes early on in the development process. It is imperative that you do this before creating any of your business objects, even though you have no practical use of the extended framework classes at that moment. This will guarantee that all of your business objects are correctly derived from your framework classes. In this recipe, you will expand on the previous recipe and add business components framework extension classes to the SharedComponents workspace.

Getting ready

You will be adding the business components framework extension classes to the SharedComponents workspace. See the previous recipe for information on how to create one.

How to do it…

  1. 1. To create framework extension classes for the commonly used business components, start with the creation of an extension class for the entity objects. Open the SharedComponents workspace in JDeveloper and right-click on the SharedBC business components project.

  2. 2. From the context menu, select New… to bring up the New Gallery dialog. Select Class from the Java category (under the General category) and click OK.

  3. 3. On the Create Java Class dialog that is displayed, enter the name of the custom entity object class, the package where it will be created, and for Extends enter the base framework class, which in this case is oracle.jbo.server.EntityImpl.

  4. 4. Now, repeat the same steps to create framework extension classes for the following components:

    Business Component

    Framework Class Extended

    Entity Definition

    oracle.jbo.server.EntityDefImpl

    View Object

    oracle.jbo.server.ViewObjectImpl

    View Row

    oracle.jbo.server.ViewRowImpl

    Application Module

    oracle.jbo.server.ApplicationModuleImpl

    Database Transaction Factory

    oracle.jbo.server.DatabaseTransactionFactory

    Database Transaction

    oracle.jbo.server.DBTransactionImpl2

  5. 5. Once you are done, your project should look similar to the following:

  6. 6. The next step is to configure JDeveloper so that all new business components that you create from this point forward will be inherited from the framework extension classes you've just defined. Open the Preferences dialog from the Tools menu, expand the ADF Business Components node, and select Base Classes.

  7. 7. Then enter the framework extension classes that you created previously, each one in its corresponding category.

How it works…

Defining and globally configuring business components framework extension classes via the ADF Business Components Base Classes settings on the Preferences dialog causes all subsequent business components for all projects to be inherited from these classes. This is true for both XML-only components and for components with custom Java implementation classes. For XML-only components observe that the ComponentClass attribute in the object's XML definition file points to your framework extension class.

There's more…

You can configure your business components framework extension classes at two additional levels: the project level and the individual component level.

  • Configuration at the project level is done via the Project Properties Base Classes selection under the ADF Business Components node. These configuration changes will affect only the components created for the specific project.

  • Configuration at the component level is done via the component's Java Options dialog, in the component's definition Java page, by clicking on the Classes Extend… button and overriding the default settings. The changes will only affect the specific component.

Note

Do not attempt to directly change or remove the extends Java keyword in your component's implementation class. This would only be half the change, because the component's XML definition will still point to the original class. Instead, use the Classes Extend… button on the component's Java Options dialog.

Finally, note that the default package structure for all business components can also be specified in the ADF Business Components | Packages page of the Preferences dialog.

See also

  • Creating and using generic extension interfaces, Chapter 5,Putting them all together:Application Modules.

  • Breaking up the application in multiple workspaces, in this chapter

 

Setting up logging


Logging is one of those areas that is often neglected during the initial phases of application design. There are a number of logging framework choices to use in your application, such as log4j by Apache. In this recipe, we will demonstrate the usage of the ADFLogger and Oracle Diagnostics Logging (ODL). The main advantage of using ODL when compared to other logging frameworks is its tight integration with WebLogic and JDeveloper. In WebLogic, the logs produced conform to and integrate with the diagnostics logging facility. Diagnostic logs include, in addition to the message logged, additional information such as the session and user that produced the log entry at run-time. This is essential when analyzing the application logs. In JDeveloper, the log configuration and analysis is integrated via the Oracle Diagnostics Logging Configuration and Oracle Diagnostics Log Analyzer respectively.

Getting ready

We will be adding logging to the application module framework extension class that we developed in the previous recipe.

How to do it…

  1. 1. ODL logs can be generated programmatically from within your code by using the ADFLogger class. Instantiate an ADFLogger via the static createADFLogger() method and use its log() method. Go ahead and add logging support to the application module framework extension class we developed in the previous recipe, as shown in the following code snippet:

    import oracle.adf.share.logging.ADFLogger;
    public class ExtApplicationModuleImpl extends ApplicationModuleImpl {
    // create an ADFLogger
    private static final ADFLogger LOGGER = ADFLogger.createADFLogger(ExtApplicationModuleImpl.class);
    public ExtApplicationModuleImpl() {
    super();
    // log a trace
    LOGGER.log(ADFLogger.TRACE, "ExtApplicationModuleImpl was constructed");
    }
    }
    

    Note

    Downloading the example code

    You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

  2. 2. The next step involves the configuration of the logger in the logging.xml file. The file is located in the config\fmwconfig\servers directory under the WebLogic domain for the server you are configuring. For the integrated WebLogic server, this file is located in the %JDEV_USER_DIR%\system11.1.2.1.38.60.81\DefaultDomain\config\fmwconfig\servers\DefaultServer directory. The exact location can vary slightly depending on the version of JDeveloper that you use.

    Open the file in JDeveloper and create a custom logger called com.packt by clicking on the Add Persistent Logger icon, as shown in the following screenshot:

  3. 3. This will display the Add Persistent Logger dialog to add your logger. Enter com.packt for the Logger Name and choose FINEST for the Logger Level.

  4. 4. Repeat this step and add another logger named com if one does not already exist for it. The final result should look similar to the following screenshot:

  5. 5. One more step that is required to complete the configuration is to use the -Djbo.debugoutput=adflogger and -Djbo.adflogger.level=FINEST options when starting the JVM. You can do this in JDeveloper by double-clicking on the main application's ViewController project to bring up the Project Properties dialog and selecting the Run/Debug/Profile node.

  6. 6. Then select the appropriate Run Configuration on the right and click on the Edit… button.

  7. 7. On the Edit Run Configuration dialog that is displayed, enter these Java options in the Java Options.

How it works…

In this example, we have declared a static ADFLogger and associated it with the class ExtApplicationModuleImpl by passing ExtApplicationModuleImpl.class as a parameter during its construction. We have declared the ADFLogger as static so we don't have to worry about passivating it. We then use its log() method to do our logging. The log() method accepts a java.util.logging.Level parameter indicating the log level of the message and it can be any of the following values: ADFLogger.INTERNAL_ERROR, ADFLogger.ERROR, ADFLogger.WARNING, ADFLogger.NOTIFICATION, or ADFLogger.TRACE.

ADFLogger leverages the Java Logging API to provide logging functionality. Because standard Java logging is used, it can be configured through the logging.xml configuration file. This file is located under the WebLogic domain directory config\fmwconfig\servers for the specific server that you are configuring. The file is opened and a logger is added.

Logging is controlled at the package level; we have added a logger for the com.packt package but we can fine-tune it for the additional levels: com.packt.jdeveloper, com.packt.jdeveloper.cookbook, com.packt.jdeveloper.cookbook.shared, and so on. The class name that we passed as an argument to the ADFLogger during its instantiation—that is, ExtApplicationModuleImpl.class—represents a logger that is defined in the logging configuration file. The logger that is added is a persistent logger, which means that it will remain permanently in the logging.xml configuration file. Transient loggers are also available; these persist only for the duration of the user session.

Each logger configured in the logging.xml is associated with a log handler. There are a number of handlers defined in the logging.xml namely a console-handler to handle logging to the console, an odl_handler to handle logging for ODL and others.

There's more…

Note

You can also use the ADFLogger methods severe(), warning(), info(), config(), fine(), finer(), and finest() to do your logging.

When you configure logging, ensure that you make the changes to the appropriate logging.xml file for the WebLogic server you are configuring.

See also

  • Breaking up the application in multiple workspaces, in this chapter

  • Configuring diagnostics logging, Chapter 11,Refactoring, Debugging,Profiling, Testing

  • Dynamically configure ADF trace logs on WebLogic, Chapter 11,Refactoring, Debugging,Profiling, Testing

 

Using a custom exception class


In this recipe, we will go over the steps necessary to set up a custom application exception class derived from the JboException base exception class. Some Reasons why you might want to do this include:

  • Customize the exception error message

  • Use error codes to locate the error messages in the resource bundle

  • Use a single resource bundle per locale for the error messages and their parameters

Getting ready

We will add the custom application exception class to the SharedComponents workspace we created in the Breaking up the application in multiple workspaces recipe in this chapter.

How to do it…

  1. 1. Start by opening the SharedComponents workspace.

  2. 2. Create a new class called ExtJboException by right-clicking on the business components project and selecting New….

  3. 3. Then select Java under the General category and Java Class from list of Items on the right.

  4. 4. Click OK to display the Create Java Class dialog. Enter ExtJboException for the Name, com.packt.jdeveloper.cookbook.shared.bc.exceptions for the Package and oracle.jbo.JboException for the Extends.

  5. 5. Click OK to proceed with the creation of the custom exception class.

  6. 6. The next step is to add two additional constructors, to allow for the instantiation of the custom application exception using a standard error message code with optional error message parameters. The additional constructors look similar to the following code sample:

    public ExtJboException(final String errorCode, final Object[] errorParameters) {
    super(ResourceBundle.class, errorCode, errorParameters);
    }
    public ExtJboException(final String errorCode) {
    super(ResourceBundle.class, errorCode, null);
    }
    
  7. 7. Now, click on the Override Methods… icon on the top of the editor window and override the getMessage() method, as shown in the following screenshot:

  8. 8. Enter the following code for the getMessage() method:

    public String getMessage() {
    // default message
    String errorMessage = "";
    try {
    // get access to the error messages bundle
    final ResourceBundle messagesBundle = ResourceBundle.getBundle (ERRORS_BUNDLE, Locale.getDefault());
    // construct the error message
    errorMessage =this.getErrorCode() + " - " + messages Bundle.getString(MESSAGE_PREFIX + this.getErrorCode());
    // get access to the error message parameters bundle
    final ResourceBundle parametersBundle = ResourceBundle .getBundle(PARAMETERS_BUNDLE, Locale.getDefault());
    // loop for all parameters
    for (int i = 0; i < this.getErrorParameters().length; i++) {
    // get parameter value
    final String parameterValue =
    parametersBundle.getString(PARAMETER_PREFIX +
    (String)this.getErrorParameters()[i]);
    // replace parameter placeholder in the error message string
    errorMessage = errorMessage.replaceAll ("\\{" + (i + 1) + "}", parameterValue);
    }
    } catch (Exception e) {
    // log the exception
    LOGGER.warning(e);
    }
    return errorMessage;
    }
    
  9. 9. Make sure that you also add the following constants:

    private static final String ERRORS_BUNDLE = "com.packt.jdeveloper. cookbook.shared.bc.exceptions.messages.ErrorMessages";
    private static final String PARAMETERS_BUNDLE = "com.packt. jdeveloper.cookbook.shared.bc.exceptions.messages.ErrorParams";
    private static final String MESSAGE_PREFIX = "message.";
    private static final String PARAMETER_PREFIX = "parameter.";
    private static final ADFLogger LOGGER =ADFLogger .createADFLogger(ExtJboException.class);
    
  10. 10. For testing purposes add the following main() method:

    // for testing purposes; remove or comment if not needed
    public static void main(String[] args) {
    // throw a custom exception with error code "00001" and two parameters
    throw new ExtJboException("00001",
    new String[] { "FirstParameter", "SecondParameter" });
    }
    

How it works…

We have created a custom exception at the ADF-BC level by overriding the JboException class. In order to use application-specific error codes, we have introduced two new constructors. Both of them accept the error code as a parameter. One of them also accepts the message error parameters.

public ExtJboException(final String errorCode, final Object[] errorParameters) {
super(ResourceBundle.class, errorCode, errorParameters);
}

In our constructor, we call the base class' constructor and pass the message error code and parameters to it.

Then we override the getMessage() method in order to construct the exception message. In getMessage(), we first get access to the error messages resource bundle by calling ResourceBundle.getBundle() as shown in the following code snippet:

final ResourceBundle messagesBundle = ResourceBundle.getBundle(ERRORS_BUNDLE, Locale.getDefault());

This method accepts the name of the resource bundle and the locale. For the name of the resource bundle, we pass the constant ERRORS_BUNDLE, which we define as com.packt.jdeveloper.cookbook.shared.bc.exceptions.messages.ErrorMessages. This is the ErrorMessages.properties file in the com/packt/jdeveloper/cookbook/shared/bc/exceptions/messages directory where we have added all of our messages. For the locale, we use the default locale by calling Locale.getDefault().

Then we proceed by loading the error message from the bundle:

errorMessage = this.getErrorCode() + " - " + messagesBundle.getString(MESSAGE_PREFIX + this.getErrorCode());

An error message definition in the messages resource bundle looks similar to the following:

message.00001=This is an error message that accepts two parameters. The first parameter is '{1}'. The second parameter is '{2}'.

As you can see, we have added the string prefix message. to the actual error message code. How you form the error message identifiers in the resource bundle is up to you. You could, for example, use a module identifier for each message and change the code in getMessage() appropriately. Also, we have used braces, that is, {1}, {2} as placeholders for the actual message parameter values. Based on all these, we constructed the message identifier by adding the message prefix to the message error code as: MESSAGE_PREFIX + this.getErrorCode() and called getString() on the messagesBundle to load it.

Then we proceed with iterating the message parameters. In a similar fashion, we call getString() on the parameters bundle to load the parameter values.

The parameter definitions in the parameters resource bundle look similar to the following:

parameter.FirstParameter=Hello
parameter.SecondParameter=World

So we add the prefix parameter to the actual parameter identifier before loading it from the bundle.

The last step is to replace the parameter placeholders in the error message with the actual parameter values. We do this by calling replaceAll() on the raw error message, as shown in the following code snippet:

errorMessage = errorMessage.replaceAll("\\{" + (i + 1) + "}", parameterValue);

For testing purposes, we have added a main() method to test our custom exception. You will similarly throw the exception in your business components code, as follows:

throw new ExtJboException("00001", // message code new String[] { "FirstParameter", "SecondParameter" } // message parameters);

There's more…

You can combine the error message and the error message parameters bundles into a single resource bundle, if you want, and change the getMessage() method as needed to load both from the same resource bundle.

Bundled Exceptions

By default, exceptions are bundled at the transaction level for ADF-BC-based web applications. This means that all exceptions thrown during attribute and entity validations are saved and reported once the validation process is complete. In other words, the validation will not stop on the first error, rather it will continue until the validation process completes and then report all exceptions in a single error message. Bundled validation exceptions are implemented by wrapping exceptions as details of a new parent exception that contains them. For instance, if multiple attributes in a single entity object fail attribute validation, these multiple ValidationException objects are wrapped in a RowValException. This wrapping exception contains the row key of the row that has failed validation. At transaction commit time, if multiple rows do not successfully pass the validation performed during commit, then all of the RowValException objects will get wrapped in an enclosing TxnValException object. Then you can use the getDetails() method of the JboException base exception class to recursively process the bundled exceptions contained inside it.

Exception bundling can be configured at the transaction level by calling setBundledExceptionMode() on the oracle.jbo.Transaction. This method accepts a Boolean value indicating that bundled transactions will be used or not, respectively.

Note

Note that in the Using a generic backing bean actions framework recipe in this chapter, we refactored the code in getMessage() to a reusable BundleUtils.loadMessage() method. Consequently, we changed the ExtJboException getMessage() in that recipe to the following:

public String getMessage() {
return BundleUtils.loadMessage(this.getErrorCode(), this.getErrorParameters());
}

See also

  • Handling security, session timeouts, exceptions and errors, Chapter 9,Handling Security, Session Timeouts, Exceptions and Errors

  • Breaking up the application in multiple workspaces, in this chapter

 

Using ADFUtils/JSFUtils


In this recipe, we will talk about how to incorporate and use the ADFUtils and JSFUtils utility classes in your ADF application. These are utility classes used at the ViewController level that encapsulate a number of lower level ADF and JSF calls into higher level methods. Integrating these classes in your ADF application early in the development process, and subsequently using them, will be of great help to you as a developer and contribute to the overall project's clarity and consistency. The ADFUtils and JSFUtils utility classes, at the time of writing, are not part of any official JDeveloper release. You will have to locate them, configure them, and expand them as needed in your project.

Getting ready

We will be adding the ADFUtils and JSFUtils classes 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. 1. To get the latest version of these classes, download and extract the latest version of the Fusion Order Demo application in your PC. This sample application can be found currently in the Fusion Order Demo (FOD) - Sample ADF Application page at the following address: http://www.oracle.com/technetwork/developer-tools/jdev/index-095536.html.

  2. 2. The latest version of the Fusion Order Demo application is 11.1.2.1 R2 at the time of this writing and is bundled in a zipped file. So go ahead download and extract the Fusion Order Demo application in your PC.

  3. 3. You should be able to locate the ADFUtils and JSFUtils classes in the location where you have extracted the Fusion Order Demo application. If multiple versions of the same class are found, compare them and use the ones that are most up-to-date. For this recipe, we have included in the source code the ADFUtils and JSFUtils found in the SupplierModule\ViewController\src\oracle\fodemo\supplier\view\utils directory.

  4. 4. Copy these classes to a specific location in your shared ViewController components project. For this recipe, we have copied them into the SharedComponents\SharedViewController\src\com\packt\jdeveloper\cookbook\shared\view\util directory.

  5. 5. Once copied, open both files with JDeveloper and change their package to reflect their new location, in this case to com.packt.jdeveloper.cookbook.shared.view.util.

How it works…

The public interfaces of both ADFUtils and JSFUtils define static methods, so you can call them directly without any class instantiations. The following are some of the methods that are commonly used.

Locating an iterator binding

To locate an iterator in the bindings, use the ADFUtils.findIterator() method. The method accepts the bound iterator's identifier and returns an oracle.adf.model.binding.DCIteratorBinding. The following is an example:

DCIteratorBinding it = ADFUtils.findIterator("IteratorID");

Locating an operation binding

To locate an operation in the bindings, use the ADFUtils.findOperation() method. This method accepts the bound operation's identifier and returns an oracle.binding.OperationBinding.

OperationBinding oper = ADFUtils.findOperation("OperationID");

Locating an attribute binding

Use ADFUtils.findControlBinding() to retrieve an attribute from the bindings. This method accepts the bound attribute's identifier and returns an oracle.binding.AttributeBinding.

AttributeBinding attrib = ADFUtils.findControlBinding("AttributeId");

Getting and setting an attribute binding value

To get or set a bound attribute's value, use the ADFUtils.getBoundAttributeValue() and ADFUtils.setBoundAttributeValue() methods respectively. Both of these methods accept the identifier of the attribute binding as an argument. The getBoundAttributeValue() method returns the bound attribute's data value as a java.lang.Object. The setBoundAttributeValue() method accepts a java.lang.Object and uses it to set the bound attribute's value.

// get some bound attribute data
String someData = (String)ADFUtils.getBoundAttributeValue("AttributeId");
// set some bound attribute data
ADFUtils.setBoundAttributeValue("AttributeId", someData);

Getting the binding container

You can get the oracle.adf.model.binding.DCBindingContainer binding container by calling the ADFUtils.getDCBindingContainer() method.

DCBindingContainer bindings = ADFUtils.getDCBindingContainer();

Adding Faces messages

Use the JSFUtils.addFacesInformationMessage() and JSFUtils.addFacesErrorMessage() methods to display Faces information and error messages respectively. These methods accept the message to display as a String argument.

JSFUtils.addFacesInformationMessage("Information message");
JSFUtils.addFacesErrorMessage ("Error message");

Finding a component in the root view

To locate a UI component in the root view based on the component's identifier, use the JSFUtils.findComponentInRoot() method. This method returns a javax.faces.component.UIComponent matching the specified component identifier.

UIComponent component = JSFUtils.findComponentInRoot("ComponentID");

Getting and setting managed bean values

Use the JSFUtils.getManagedBeanValue() and JSFUtils.setManagedBeanValue() methods to get and set a managed bean value respectively. These methods both accept the managed bean name. The JSFUtils.getManagedBeanValue() method returns the managed bean value as a java.lang.Object. The JSFUtils.setManagedBeanValue() method accepts a java.lang.Object and uses it to set the managed bean value.

Object filePath = JSFUtils.getManagedBeanValue ("bindings.FilePath.inputValue");
JSFUtils.setManagedBeanValue("bindings.FilePath.inputValue", null);
 

Using page templates


In this recipe, we will go over the steps required to create a JSF page template that you can use to create JSF pages throughout your application. It is very likely that for a large enterprise-scale application you will need to construct and use a number of different templates, each serving a specific purpose. Using templates to construct the actual application JSF pages will ensure that pages throughout the application are consistent, and provide a familiar look and feel to the end user. You can follow the steps presented in this recipe to construct your page templates and adapt them as needed to fit your own requirements.

Getting ready

We will be adding the JSF template 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. 1. Start by right-clicking on the ViewController project in the SharedComponents workspace and selecting New….

  2. 2. On the New Gallery dialog select JSF/Facelets from the list of Categories and ADF Page Template from the Items on the right.

  3. 3. Click OK to proceed. This will display the Create ADF Page Template dialog.

  4. 4. Enter the name of the template on the Page Template Name. Note that as you change the template name, the template File Name also changes to reflect the template name. For this recipe, we will simply call the template TemplateDef1.

  5. 5. Now, click on the Browse… button and select the directory where the template will be stored.

  6. 6. On the Choose Directory dialog navigate to the public_html/WEB-INF directory and click on the Create new subdirectory icon to create a new directory called templates.

  7. 7. For the Document Type, select JSP XML.

  8. 8. We will not be using any of the pre-defined templates, so uncheck the Use a Quick Start Layout checkbox.

  9. 9. Also, since we will not be associating any data bindings to the template, uncheck the Create Associated ADFm Page Definition checkbox.

  10. 10. Next, you will be adding the template facets. You do this by selecting the Facet Definitions tab and clicking on the New icon button. Enter the following facets:

    Facet

    Description

    mainContent

    This facet will be used for the page's main content.

    menuBar

    This facet will be used to define a menu at the top of the page.

    topBar

    This facet will be used to define a toolbar under the page's menu.

    popupContent

    This facet will be used to define the page's pop-ups.

  11. 11. Now click OK to proceed with the creation of the ADF page template.

  12. 12. Once the template is created, it is opened in the JDeveloper editor. If you followed the previous steps, the template should look similar to the following code snippet:

    <af:pageTemplateDef var="attrs">
    <af:xmlContent>
    <component xmlns ="http://xmlns.oracle.com/adf/faces/rich/component">
    <display-name>TemplateDef1</display-name>
    <facet>
    <description>The page's main content</description>
    <facet-name>mainContent</facet-name>
    </facet>
    <facet>
    <description>The page's menu</description>
    <facet-name>menuBar</facet-name>
    </facet>
    <facet>
    <description>The page's top toolbar</description>
    <facet-name>topBar</facet-name>
    </facet>
    <facet>
    <description>The page's popups</description>
    <facet-name>popupContent</facet-name>
    </facet>
    </component>
    </af:xmlContent>
    </af:pageTemplateDef>
    

    As you can see, at this point, the template contains only its definition in an af:xmlContent tag with no layout information whatsoever. We will proceed by adding the template's layout content.

  13. 13. From the Layout components in the Component Palette, grab a Form component and drop it into the template.

  14. 14. From the Layout container, grab a Panel Stretch Layout and drop it into the Form component. Remove the top, bottom, start, and end facets.

  15. 15. From the Layout container, grab a Panel Splitter component and drop it on the center facet of the Panel Stretch Layout. Using the Property Inspector change the Panel Splitter Orientation to vertical. Also adjust the SplitterPosition to around 100.

  16. 16. Add your application logo by dragging and dropping an Image component from the General Controls onto the first facet of the Panel Splitter. For this recipe, we have created a public_html\images directory and we copied a logo.jpg logo image there. We then specified /images/logo.jpg as image Source for the Image component.

  17. 17. Let's proceed by adding the main page's layout content. Drop a Decorative Box from the Layout components onto the second facet of the Panel Splitter. We will not be using the top facet of Decorative Box, so remove it.

  18. 18. OK, we are almost there! Drag a Panel Stretch Layout from the Layout components and drop it onto the center facet of the Decorative Box. Remove the start and end facets, since we will not be using them.

  19. 19. Drag a Facet Ref component from the Layout components and drop it onto the center facet of the Panel Stretch Layout. On the Insert Facet dialog, select the mainContent facet that you added during the template creation.

  20. 20. Finally, add the following code to the Panel Stretch Layout topBar facet:

    <f:facet name="top">
    <af:panelGroupLayout id="pt_pgl5" layout="vertical">
    <af:facetRef facetName="popupContent"/>
    <af:menuBar id="pt_mb1">
    <af:facetRef facetName="menuBar"/>
    </af:menuBar>
    <af:panelGroupLayout id="pt_pgl2" layout="horizontal">
    <af:toolbar id="pt_t2">
    <af:facetRef facetName="topBar"/>
    </af:toolbar>
    </af:panelGroupLayout>
    </af:panelGroupLayout>
    </f:facet>
    

How it works…

When the template is created, there is no layout information in it, so we have to add it ourselves. We do this by using a variety of layout components to arrange the contained UI. Also, notice the usage of the af:facetRef component. It is being used to reference a template facet in the specific place within the layout content. The facet is then available to you when you create a JSF page from the template. This will become obvious when we generate a JSF page from the template. Note that each Facet can only be added once to the template.

So, how do you use the JSF page template? Since we have created the template in a SharedComponents project, we will first need to deploy the project to an ADF Library JAR. Then we will be able to use it from other consuming projects. This was explained in the Breaking up the application in multiple workspaces recipe, earlier in this chapter. When you do so, the template will be visible to all consuming projects, as shown in the following screenshot:

Once the ADF Library JAR containing the template is added to the consuming project, you can see and select the template when you create a new JSF page in the Create JSF Page dialog. The template introduced in this recipe is shown in the following screenshot:

The XML source code that is generated for a JSF page created from this template will look similar to the following code snippet:

<f:view>
<af:document id="d1" title="Test">
<af:pageTemplate viewId="/WEB-INF/templates/TemplateDef1.jspx" id="pt1">
<f:facet name="mainContent"/>
<f:facet name="menuBar"/>
<f:facet name="topBar"/>
<f:facet name="bottomBar"/>
<f:facet name="popupContent"/>
</af:pageTemplate>
</af:document>
</f:view>

You can see in the listing that the page references the template via the af:pageTemplate tag. The template facets that you have defined are available so you can enter the page-specific UI content. After adding an af:menuBar to the menuBar facet and some af:commandToolbarButton components to the topBar facet, the JSF page could look similar to the following code:

<f:view>
<af:document id="d1" title="Test">
<af:pageTemplate viewId="/WEB-INF/templates/TemplateDef1.jspx" id="pt1">
<f:facet name="mainContent"/>
<f:facet name="menuBar">
<af:menuBar id="mb1">
<af:menu text="File" id="m1">
<af:commandMenuItem text="Save" id="cmi1" icon="/images/filesave.png"/>
<af:commandMenuItem text="Action" id="cmi2" icon="/images/action.png"/>
<af:commandMenuItem text="Mail" id="cmi3" icon="/images/envelope.png"/>
<af:commandMenuItem text="Print" id="cmi4" icon="/images/print.png"/>
</af:menu>
</af:menuBar>
</f:facet>
<f:facet name="topBar">
<af:group id="g1">
<af:commandToolbarButton id="ctb1" shortDesc="Save" icon="/images/filesave.png"/>
<af:commandToolbarButton id="ctb2" shortDesc="Action" icon="/images/action.png"/>
<af:commandToolbarButton id="ctb3" shortDesc="Mail" icon="/images/envelope.png"/>
<af:commandToolbarButton id="ctb4" shortDesc="Print" icon="/images/print.png"/>
</af:group>
</f:facet>
<f:facet name="popupContent"/>
</af:pageTemplate>
</af:document>
</f:view>

Running the page in JDeveloper will produce the following:

There's more…

Although adding a Form component to a template is not recommended practice, this is not a problem for the template created in this recipe, since we will not be using it for the creation of page fragments. Using a template that contains a Form component to create page fragments will result in a problem when a consuming page already contains a Form component itself. The template developed in this recipe will not be used for page fragments. It was developed specifically to be used along with the generic backing bean actions framework explained in the Using a generic backing bean actions framework recipe in this chapter.

 

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. 1. Right-click on the shared ViewController project and select New….

  2. 2. On the New Gallery dialog, select Java under the General category and Java Class from the list of items on the right.

  3. 3. On the Create Java Class dialog, enter CommonActions for the class name and com.packt.jdeveloper.cookbook.shared.view.actions for the class package.

  4. 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. 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. 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

About the Author

  • Nick Haralabidis

    Nick Haralabidis has over 20 years experience in the Information Technology industry, and a multifaceted career in such positions as Senior IT Consultant, Senior Software Engineer and Project Manager for a number of U.S. and Greek corporations (Compuware, Chemical Abstracts Service, NewsBank, CheckFree, Intrasoft International, Unisystems, MedNet International and others). His many years of experience have exposed him to a wide range of technologies ranging from Java, J2EE, C++, C, and Tuxedo, to a number of database technologies. For the last four years Nick has been actively involved in large implementations of next generation enterprise applications utilizing Oracle’s JDeveloper, Application Development Framework (ADF) and SOA technologies. He holds a B.S. in Computer Engineering and an M.S. in Computer Science from the University of Bridgeport. When he is not pursuing ADF professionally, he writes on his blogs JDeveloper Frequently Asked Questions (http://jdeveloperfaq.blogspot.com) and ADF Code Bits (http://adfcodebits.blogspot.com). He is active in the Oracle Technology Network (OTN) JDeveloper and ADF forum where he both learns from and helps other forum users.

    Browse publications by this author
Book Title
Unlock this full book FREE 10 day trial
Start Free Trial