Skip Headers
Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g (10.1.3.1.0)

Part Number B25947-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

25.8 Customizing Business Components Error Messages


Note:

The examples in this section refer to the CustomizedErrorMessages project in the AdvancedExamples workspace. See the note at the beginning of this chapter for download instructions.

25.8.1 How to Customize Base ADF Business Components Error Messages

You can customize any of the built-in ADF Business Components error messages by providing an alternative message string for the error code in a custom message bundle. Assume you do not like the built-in error message:

JBO-27014: Attribute Name is Product is required

If you have requested the Oracle ADF source code from Oracle Worldwide Support, you can look in the CSMessageBundle.java file in the oracle.jbo package to see that this error message is related to the combination of the following lines in that message bundle file:

public class CSMessageBundle extends CheckedListResourceBundle {
  // etc.
  public static final String EXC_VAL_ATTR_MANDATORY            = "27014";
  // etc. 
  private static final Object[][] sMessageStrings = {
    // etc.
    {EXC_VAL_ATTR_MANDATORY, "Attribute {2} in {1} is required"},
    // etc.
  }
}

The numbered tokens {2} and {1} are error message placeholders. In this example the {l} is replaced at runtime with the name of the entity object and the {2} with the name of the attribute.

To create a custom message bundle file, do the following:

  1. Open the Business Components > Options page in the Project Properties dialog for the project containing your business components.

    Notice the Custom Message Bundles to use in this Project list at the bottom of the dialog.

  2. Click New.

  3. Enter a name and package for the custom message bundle in the Create MessageBundle class dialog and click OK.


    Note:

    If the fully-qualified name of your custom message bundle file does not appear in the Custom Message Bundles to use in this Project list, click the Remove button, then click the Add button to add the new message bundle file created. When the custom message bundle file is correctly registered, it's fully-qualified class name should appear in the list.

  4. Click OK to dismiss the Project Properties dialog and open the new custom message bundle class in the source editor.

  5. Edit the two-dimensional String array in the custom message bundle class to contain any customized messages you'd like to use.

    Example 25-11 illustrates a custom message bundle class that overrides the error message string for the JBO-27014 error considered above.

    Example 25-11 Custom ADF Business Components Message Bundle

    package devguide.advanced.customerrs;
    import java.util.ListResourceBundle;
    public class CustomMessageBundle extends ListResourceBundle {
      private static final Object[][] sMessageStrings 
        = new String[][] {
           {"27014","You must provide a value for {2}"}
         };
      protected Object[][] getContents() {
        return sMessageStrings;
      }
    }
    

25.8.2 What Happens When You Customize Base ADF Business Components Error Messages

After adding this message to your custom message bundle file, if you test the application using the Business Components Browser and try to blank out the value of a mandatory attribute, you'll now see your custom error message instead of the default one:

JBO-27014: You must provide a value for Name

You can add as many messages to the message bundle as you want. Any message whose error code key matches one of the built-in error message codes will be used at runtime instead of the default one in the oracle.jbo.CSMessageBundle message bundle.

25.8.3 How to Customize Error Messages for Database Constraint Violations

If you enforce constraints in the database, you might want to provide a custom error message in your ADF application to display to the end user when one of those constraints is violated. For example, imagine that you added a constraint called NAME_CANNOT_BEGIN_WITH_X to the SRDemo application's PRODUCTS table using the following DDL statement:

alter table products add (
  constraint name_cannot_begin_with_x
      check (upper(substr(name,1,1)) != 'X')
);

To define a custom error message in your application, just add a message to a custom message bundle with the constraint name as the message key. For example, assuming that you use the same CustomMessageBundle.java class created in the previous section, Example 25-12 shows what it would look like to define a message with the key NAME_CANNOT_BEGIN_WITH_X which matches the name of the database constraint name defined above.

Example 25-12 Customizing Error Message for Database Constraint Violation

package devguide.advanced.customerrs;
import java.util.ListResourceBundle;
public class CustomMessageBundle extends ListResourceBundle {
  private static final Object[][] sMessageStrings 
    = new String[][] {
       {"27014","You must provide a value for {2}"},
       {"NAME_CANNOT_BEGIN_WITH_X",
        "The name cannot begin with the letter x!"}
     };
  protected Object[][] getContents() {
    return sMessageStrings;
  }
}

25.8.4 How to Implement a Custom Constraint Error Handling Routine

If the default facility for assigning a custom message to a database constraint violation does not meet your needs, you can implement your own custom constraint error handling routine. Doing this requires creating a custom framework extension class for the ADF transaction class, which you then configure your application module to use at runtime.

25.8.4.1 Creating a Custom Database Transaction Framework Extension Class

To write a custom framework extension class for the ADF transaction, create a class like the CustomDBTransactionImpl shown in Example 25-13. This example overrides the transaction object's postChanges() method to wrap the call to super.postChanges() with a try/catch block in order to perform custom processing on any DMLConstraintException errors that might be thrown. In this simple example, the only custom processing being performed is a call to ex.setExceptions(null) to clear out any nested detail exceptions that the DMLConstraintException might have. Instead of this, you could perform any other kind of custom exception processing required by your application, including throwing a custom exception, provided your custom exception extends JboException directly or indirectly.

Example 25-13 Custom Database Transaction Framework Extension Class

package devguide.advanced.customerrs;
import oracle.jbo.DMLConstraintException;
import oracle.jbo.JboException;
import oracle.jbo.common.StringManager;
import oracle.jbo.server.DBTransactionImpl2;
import oracle.jbo.server.TransactionEvent;
public class CustomDBTransactionImpl  extends DBTransactionImpl2 {
  public void postChanges(TransactionEvent te) {
    try {
      super.postChanges(te);
    }
    /*
     * Catch the DML constraint exception
     * and perform custom error handling here
     */
    catch (DMLConstraintException ex) { 
      ex.setExceptions(null);
      throw ex;
    }
  }
}

25.8.4.2 Configuring an Application Module to Use a Custom Database Transaction Class

In order for your application module to use a custom database transaction class at runtime, you must:

  1. Provide a custom implementation of the DatatabaseTransactionFactory class that overrides the create() method to return an instance of the customized transaction class.

  2. Configure the value of the TransactionFactory property to be the fully-qualified name of this custom transaction factory class.

Example 25-14 shows a custom database transaction factory class that does this. It returns a new instance of the CustomDBTransactionImpl class when the framework calls the create() method on the database transaction factory.

Example 25-14 Custom Database Transaction Factory Class

package devguide.advanced.customerrs;
import oracle.jbo.server.DBTransactionImpl2;
import oracle.jbo.server.DatabaseTransactionFactory;
public class CustomDatabaseTransactionFactory
       extends DatabaseTransactionFactory {
  public CustomDatabaseTransactionFactory() {
  }
  /**
   * Return an instance of our custom ToyStoreDBTransactionImpl class
   * instead of the default implementation.
   *
   * @return instance of custom CustomDBTransactionImpl implementation.
   */
  public DBTransactionImpl2 create() {
    return new CustomDBTransactionImpl();
  }    
}

To complete the job, use the Properties tab of the Configuration Editor to assign the value devguide.advanced.customerrs.CustomDatabaseTransactionFactory to the TransactionFactory property. When you run the application using this configuration, your custom transaction class will be used.