Saturday, September 15, 2012

Exception Handling In Adf (Part 1.1)

Hi All,

Although in my  first Exception Handling post I have explained the exception handling approach in the model layer however here I also would like  to add some more approach in same model layer (binding layer).

We can handle Exception Handling in Model layer as following ways

1-For Single Application and handle as global for model layer(Binding layer) :
(If you have only on DataBinding.cpx file )
Create the Class which extend DCErrorHandlerImpl  and register with DataBinding.cpx file.It means all the page def file which is associated with this DataBinding.cpx  file if throws any exception then Extends Class is going to catch the exception .
So this approach is work whole in model layer regardless what ever  page def is associated with the DataBinding.cpx .

2-Only for individual page def file (Binding layer):
Second Approach is going to handle the exception only for  one page where we register our custom class as a ControllerClass .

3-For N number of application and handle as global for all  model layer(Binding layer) :
(If you have only DataBinding.cpx file or more than one ) . (Top most application has Error Handler)
Suppose if you  have a big application which contains N number of projects.Therefore each individual project have their own DataBinding.cpx file.If you implement the first approach you need to create N number file for each individual Class file which extends DCErrorHandlerImlp class.So over come this type of issue Oracle Adf provide one more type of Model layer Exception handling.Where you need to extends one ADF life cycle class,One JSF life cycle class and need to register the custom JSF life cycle class into faces-config.xml.
So in this case if exception thrown in any application but from model layer(binding layer) then  custom class will going to catch the exception .

After reading above points ,I am sure it will give the clear ideas of Exception Handling Approach in Model Layer.

If your top most application has error handler register then you do not required to inject Error handler class using above approach.

Let me explain above point into details

1-For Single Application and handle as global for model layer : Since my last exception handling post I have already explain this approach .

2-Only for individual page def file : You can handle exception in model layer for only one single page .For implementing this approach do following step

i-Create the class and extends with FacesPageLifecycle class
ii- override following method 
public void reportErrors(PageLifecycleContext pageLifecycleContext){};
iii-Then register this newly created class into page def file in ControllerClass  file .
iv-This method always being called when any exception thrown from same page.

3-For N number of application and handle as global for all model layer (Binding Layer):  This approach will help full if you dealing with a large application which contains n number of project.And you do not want each individual application owner to implement the exception handling.

Let me explain my use case where we have implemented this approach ,

We have a  very large application so  we have divided our large application into  simple module .and after that we have created on main application where we add this application as jar or war.It mean through this main application we will access our module.

Hence we have implemented this approach.

So for this we have created one new application where we have written all exception handling related code.And after that we have created the adf jar file which we consumed  into our main application.

Step are following .
1-Create the class and extends with DCErrorHandlerImpl
2-Override the public void reportException(DCBindingContainer bc, Exception ex) .


package com.prateek.blog.view.exception;

import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCErrorHandlerImpl;

import oracle.jbo.JboException;

public class CustomExceptionHandler extends DCErrorHandlerImpl {
    public CustomExceptionHandler() {
        super(true);
    }

    @Override
    public void reportException(DCBindingContainer dCBindingContainer,
                                Exception exception) {

        if (exception instanceof JboException) {
            //By default all exception which are coming from Model layer all are instance of JboException
            //here just i am try to skip the exception to report to super class which is DCErrorHandlerInpl
            //we can write our own logic
            // if the exception came of model then it always go through this if condition
        } else {
            super.reportException(dCBindingContainer, exception);
        }

    }

    private void disableAppendCodes(Exception ex) {
        if (ex instanceof JboException) {
            JboException jboEx = (JboException)ex;
            jboEx.setAppendCodes(false);
            Object[] detailExceptions = jboEx.getDetails();
            if ((detailExceptions != null) && (detailExceptions.length > 0)) {
                for (int z = 0, numEx = detailExceptions.length; z < numEx;
                     z++) {
                    disableAppendCodes((Exception)detailExceptions[z]);
                }
            }
        }
    }

    @Override
    public DCErrorMessage getDetailedDisplayMessage(BindingContext bindingContext,
                                                    RegionBinding regionBinding,
                                                    Exception exception) {
        return super.getDetailedDisplayMessage(bindingContext, regionBinding,
                                               exception);
    }

    @Override
    public String getDisplayMessage(BindingContext bindingContext,
                                    Exception exception) {
        return super.getDisplayMessage(bindingContext, exception);
    }

    @Override
    protected boolean skipException(Exception exception) {
        return super.skipException(exception);
    }

}

*This code same as my last post.User need to customize base on their requirements.

3- Then need to create custom page life cycle class that extends  FacesPageLifecycle
4-Over ride the Prepare model method  where we need to register newly create customer exception handler class into the setErrorHandler method
public void prepareModel(LifecycleContext ctx)
{
if (!(ctx.getBindingContext().getErrorHandler() instanceof ModelExceptionHandlerClass)) { ctx.getBindingContext().setErrorHandler(new ModelExceptionHandlerClass(true));
}
super.prepareModel(ctx);
 }
here ModelExceptionHandlerClass class my custom exception handler class.

5-Then need to create custom listener class where need to register newly created life cycle class .
6-For this need to extends ADFPhaseListener class .
7-Override  protected PageLifecycle createPageLifecycle(){}

@Override protected PageLifecycle createPageLifecycle() { return new FacesPageLifecycleBean(); }

8-Need to register above class into faces-config.xml file under life cycle property.

Code of the above implementation is following
https://docs.google.com/open?id=0B8cP4jZuxLlXTnRIMkxaWURhazg

This post explain  different type of approach for handling exception in model layer(binding layer).

 Thanks
Prateek Shaw. 


1 comment: