Friday, August 03, 2007

How to Pimp ADF BC Exception Handling

When you have been doing things in a particular way for a long time, you sometimes find that in the mean time your way has become the slow way. Not necessarily the wrong way as it works (otherwise you would not have kept doing it all the time, would you?), but you're just not fashionable anymore. Like wearing tight pants in the 60's or wide pants in the 80's. Or using vi instead of a state-of-the-art IDE like JDeveloper or Eclipse for that matter (oh yes, I dare!).

I recently discovered that I became unfashionable by using the setAttributeXXX() and validateEntity() method for implementing business rules in ADF BC instead of using Validators. Not that I didn't know of Validators, I just thought that they would not give me proper control over exception and message handling. Because one of the things I would like to have, is one single message bundle in which I could use a consistent coding of my messages, like APP-00001, APP-00002, etc. Even more important, the other thing I would like to have is that I can translate all messages to Kalaallisut the minute I need to make my application available for the Inuit people of Greenland.

As you might know, up till JDeveloper 10.1.3 ADF BC will create an entity-specific message bundle to store the messages you provide with Validators. So with many entity objects big chance you end up with many message bundles, making that keeping error codes consistent becomes a nightmare. And what about all the separate files you need to translate! You might find yourself no longer to be able to tell the messages for the bundles.

But as Steve Muench was very persistent in trying to convince me using Validators I finally gave in and tried finding a way to tackle my problem, and succeeded! No worries, don't expect rocket science from me. I hate complex or obscure code, as building maintainable Information Systems already is hard enough as it is, and therefore always try to practice Simple Design.

I assume that you have created a layer of framework extension classes as described in section 2.5 of the ADF Developers Guide and that your entity base class is called MyAppEntityImpl. If you have not yet created such a layer, do that first and come back after you finished. Chop chop!

Basically the steps are as follows:
  • Create extension classes that extend the exceptions that ADF BC will throw when validation fails
  • Override the constructor of the super class and pass in the message bundle in the call to super()
  • Override the setAttributeInternal() and validateEntity() methods in the MyAppEntityImpl.java entity base class and make they thrown your exceptions instead of the default ones.
Does that sound simple or what? No? OK, let me show you how I did it.

Attribute-level Validators will throw the AttrValException. So what I did was create a MyAppAttrValException as follows:

package myapp.model.exception;

import oracle.jbo.AttrValException;
import myapp.model.ResourceBundle;

public class AttrValException extends AttrValException
{
public MyAppAttrValException(String errorCode, Object[] params)
{
super(ResourceBundle.class, errorCode, params);
}

/**
* When the message contains a semicolon, return the message
* starting with the position after the semicolon and limit the
* text to the message text from the resource bundle.
*
* @return the stripped message
*/
public String getMessage()
{
String message = super.getMessage();
// strip off product code and error code
int semiColon = message.indexOf(":");
if (semiColon > 0)
{
message = message.substring(semiColon + 2);
}
return message;
}

And this is how I override the setAttributeInternal in the MyAppEntityImpl:

/**
* Overrides the setAttributeInternal of the superclass in order to
* pass in a custom message bundle to MyAppAttrValException subclass
* of the AttrValException. To be able to uniquely identify the
* entries in the message bundle, the error code is extended with the
* fully qualified class name of the Impl.
*/
protected void setAttributeInternal(int index, Object val)
{
try
{
super.setAttributeInternal(index, val);
}
catch (AttrValException e)
{
String errorCode = new StringBuffer(getClass().getName())
.append(".")
.append(e.getErrorCode())
.toString();
throw new MyAppAttrValException(errorCode, e.getErrorParameters());
}
}

In a similar way you can handle entity-instance-level Validators and Method Validator by extending the ValidationException and overriding the validateEntity() method to throw your MyAppValidationException.

As said, the message you provided when creating build-in Validators and Method Validators end up in an entity-specific message bundle. I've been told that this is going to change in JDeveloper 11g, but currently there is no stopping ADF BC from doing that.

So, at a convenient point in time (for example when most of your Validators have been implemented and tested), what you need to do is copying the error messages from the entity-specific message bundles to your custom message bundle.

To prevent duplicates in the keys of the custom message bundle, you should extend the key of each message with the fully qualified class name of the Impl.java file of the entity object where it's coming from. Otherwise duplicates might occur whenever you have two different entity objects, both with an attribute with the same name and a build-in Validator specified for them. The overriden setAttributeInternal() method assumes you did.

The entries in the message bundle would look
then similar to this:

{ "myapp.model.adfbc.businessobject.EmployeeImpl.Salary_Rule_0",
"APP-00001 Employee's Salary may not be below zero" },
...


Well that wasn't rocket science, was it?

16 comments:

John Stegeman said...

well done! Very nice idea and quite helpful.

Jan Kettenis said...

You're welcome!

Anonymous said...

seems to work well when just one attribute's method validator fails. But, when more than one attribute for the same entity has it's own method validator and they each fail validation, the error message now includes something like this: JBO-27024: Failed to validate a row with key oracle.jbo.Key, along with lines for the specific errors. Any easy ways to eliminate this problem?

Jan Kettenis said...

Sorry, I only saw your comment recently (because of the spam).

I tried to find time to find out, but I didn't and it is not likely I will on a short notice. You might try to post this question on the JDeveloper forum.

Anonymous said...

The JBO-27024 is an exception that is used to bundle multiple validation exceptions. The ADF SR Demo (ADF BC) by Steve Muench customizes the default way a "tree" of
bundled ADF exceptions gets translated into JSF error message objects for display in the
JSP page by overriding the reportErrors() method of the ADF FacesPageLifecycle, which ensures that end users don't see the JBO-27024 but only the individual errors (see ADF Developer's Guide section 20.8).
JHeadstart has copied the SR Demo error reporting extension to the JHeadstart ErrorReportingUtils class and made some further customizations (see JHeadstart Developer's Guide section 11.4).

Anonymous said...

If you use JHeadstart it might be easier to apply the method described by Frank Houweling in this Amis blog post.

Anonymous said...

I like a game which needs to use wonderland Gold, when you do not have wonderland online Gold, you must borrow wonderland money from friends, or you buy wonderland Gold. If you get cheap wonderland online Gold, you can continue this game.

curtisgarett said...

An existing database SQL, and Oracle will have a wide range of table constraints, including primary keys, unique keys, foreign keys, not null values and restrictions for verification. In this blog I will show the power of ADF workflow and how it can save much time.
Printer cartridges

تقنية المعلومات said...

very good tutorial i like the style

Anonymous said...

JBO-27024 is an exception that is used to bundle multiple validation exceptions. Menu Stands

muebles en toledo said...

Oh my god, there's so much useful info above!

Unknown said...

good information.. thanks
jual obat ambeien paling manjur dan efektif
jual obat ambeien yg paling manjur dan efektif
jual obat ambeien yang paling manjur dan efektif
jual obat ambeien alami paling manjur dan efektif
jual obat ambeien herbal paling manjur dan efektif
jual obat ambeien paling manjur tanpa operasi
jual obat ambeien alami paling manjur tanpa operasi
jual obat ambeien herbal paling manjur tanpa operasi
jual obat ambeien yg paling manjur tanpa operasi
jual obat ambeien yang paling manjur tanpa operasi

Anonymous said...

good
Mengobati Kemaluan Keluar Nanah
Mengobati Kemaluan yang Ngilu Keluar Nanah
Mengobati penyakit Keluar Nanah
Mengobati penyakit Kemaluan Ngilu Keluar Nanah
Mengobati Kemaluan Keluar Nanah
Kemaluan Nyeri Keluar Nanah
Mengobati Nyeri Keluar Nanah
Mengobati sakit Kemaluan Nyeri Keluar Nanah
Mengobati penyakit Kemaluan Sakit Keluar Nanah
Mengobati Kemaluan Keluar Nanah
Mengobati Sakit Keluar Nanah
Mengobati Kemaluan yang Sakit Keluar Nanah
Obat Ambeien Ambeclear Apotik
Obat Ambeien di Apotik
Obat Ambeyen Apotik
Pengobatan Ambeien Ambeclear di Apotik
Obat Ambeyen Ampuh Ambeclear
Obat Ambeien Ampuh
Obat Ambeien Ambeclear
Obat penyakit Ambeien Ampuh Ambeclear
Obat Ambeyen Aman Ambeclear
Obat Ambeien yg Aman Ambeclear
Pengobatan Ambeien Aman Ambeclear
Obat Ambeien yang Aman Ambeclear
mengobati kelamin keluar nanah
mengobati keluar nanah
mengobati sakit kemaluan keluar nanah
mengobati penyakit kemaluan keluar nanah
Mengobati penyakit Kemaluan Keluar Seperti Nanah
Mengobati Kemaluan Keluar Nanah
Mengobati sakit Kemaluan Keluar Seperti Nanah
Mengobati Kelamin Keluar Seperti Nanah
Mengobati penyakit Kemaluan Keluar Nanah Kental
Mengobati Kelamin Keluar Nanah Kental
obat Kemaluan Keluar Nanah Kental
Mengobati penyakit Kemaluan Keluar Nanah Kental

ArtJogja said...

bikin gantungan kunci akrilik ultah ***********************spesialis gantungan kunci akrilik obyek wisata

Karunia-MU said...

Menyembuhkan wasir tanpa harus operasi terbukti sembuh
Pengobatan wasir sampai sembuh total tanpa operasi
Cara mengobati wasir ampuh aman tanpa efek samping cepat sembuh
Pengobatan wasir ampuh tanpa operasi tanpa efek samping
Cara mengatasi timbul benjolan wasir dianus tanpa operasi
Cara ampuh mengatasi wasir cepat sembuh tuntas
cara mengobati wasir sudah parah stadium 3 tanpa operasi
Obat wasir ampuh terbukti cepat sembuh total
Cara mengatasi timbul benjolan wasir dianus tanpa operasi
cara mengobati wasir yang sudah parah
Cara aman mengobati wasir stadium 3 tanpa operasi
pesan obat wasir tanpa operasi
Cara mengatasi timbul benjolan wasir dianus tanpa operasi
Cara mengobati wasir yang sudah parah tanpa operasi
Cara pesan obat wasir tanpa operasi
Cara mengatasi timbul benjolan wasir dianus tanpa operasi

Karunia-MU said...

obat wasir herbal
obat wasir top
ambeien hilang
obat keputihan
obat penyempit vagina
obat kanker
obat kutil kelamin
obat sipilis
masker payudara
cream payudara montok
herbal obat sehat
Cara pesan herbal
testimoni herbal
Cara mengobati kanker serviks stadium 7
obat perapat vagina
obat wasir tanpa operasi apa obatnya
pengobatan wasir secara alami tanpa
obat wasir tanpa operasi
cara mengobati wasir
cara mengobati wasir
rahasia cantik dengan obat perapat