Book Image

Oracle JDeveloper 11gR2 Cookbook

By : Nick Haralabidis
Book Image

Oracle JDeveloper 11gR2 Cookbook

By: Nick Haralabidis

Overview of 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.
Table of Contents (19 chapters)
Oracle JDeveloper 11gR2 Cookbook
Credits
Foreword
About the Author
About the Reviewers
www.PacktPub.com
Preface

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