Monday, April 2, 2018

Accessing AMImpl client interface method in Using expression in ViewObject

In this section, we walk through about accessing an AppModule java method using Groovy expression

Pre-Requisite

JDeveloper 12.1.3

HR Schema

Country Entity & View Object (create Entity/ViewObject and its Java class )

Process

Double click on the AppModuleImpl.java class >> Write a method that return some integer. We are going to call this method from a View Object through Groovy Expression


Expose the method by double Click on the AppModuleImpl.xml >> Click Java >> Click the pencil icon >> Move the method to the selected list >> Click Ok



Now Open a View Object >> Click Attribute >> Click + icon to create new attribute



Input a name and change type to BigInteger as shown below



Select the created field >> Click Details >> Enable expression >> Click the expression icon as shown below






Input the groovy expression as shown below. Click Ok


This expression calls the method in the AppModuleImpl.java and assign it to the column ‘someNumber’

Syntax: ad.object.applicationModule.<MethodName>





Now Click the Source tab of the Country View Object >> Find the View Aattribute name ‘someNumber’ >> Select the element TransientExpression >> After select , a property window appear n the right hand side >> Change the TrustedMode to true in the property window



Click Save All
Test AppModule
Right click the AppModule.xml >> Click Run
Double click on the CountryEOView1 and check the method return value get populated in the column someNumber

Tuesday, November 7, 2017

Exception Handling in ADF in all the layer-ADF BC,View Layer,Taskflow level

ADF Exception handling can be done at below three places:

  1. Extending DCErrorHandlerImpl
  2. Extending Controller level ExceptionHandler
  3. Taskflow Exception Handler
Lets Discuss in brief:

    1. Extending DCErrorHandlerImpl- for model
Custom ExceptionHandler Class for model

package xx.view.exp.model;

import javax.faces.application.FacesMessage;
import oracle.adf.model.binding.DCErrorHandlerImpl;
import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.jbo.JboException;

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

  public XxModelExpHandler(boolean b)
  {
    super(b);
  }

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

  @Override
  public void reportException(DCBindingContainer formBnd, Exception ex)
  {
    if (ex instanceof XxCustomException)
    {
//get message to be displayed from resource bundle or hardcode the message when throwing exception
        String msg = XxUtils.getMessageString((XxCustomException) ex);
        JboException jex=new JboException(msg);
        super.reportException(formBnd,jex);
    }

    else
    {
      super.reportException(formBnd, ex);
    }
  }

}

Databindings.cpx

Specify your custom handler as ErrorHandlerClass in databindings.cpx:


<Application xmlns="http://xmlns.oracle.com/adfm/application"
             version="11.1.1.59.23" id="DataBindings" SeparateXMLFiles="false"
             Package="xx.view" ClientType="Generic"
             ErrorHandlerClass="xx.view.exp.model.XxModelExpHandler">




2.  Extending Controller level ExceptionHandler
Any exception in controller will first come here and if re-thrown will be handled at taskflow level(explained before).

Declaring custom exception handler class

You need to create a folder named services under Application Resources -> Descriptors -> ADF META-INF. Under the folder create a file named oracle.adf.view.rich.context.ExceptionHandler and inside the file just mention the name of your custom exception handler.



Custom Exception Class

We are creating a custom exception class which will be thrown in our code whenever we want to show a faces message for any validation, failure, etc.


public class XxCustomException
  extends JboException
{
  private String resourceBundleKey;
  private String error_type;
  private String client_id;
  private MessageToken[] tokens;
  
//setters and getters with required constructors
}

Custom ExceptionHandler Class

import oracle.adf.view.rich.context.ExceptionHandler;
public class XxControllerExpHandler
  extends ExceptionHandler
{
  public void handleException(FacesContext facesContext,
                              Throwable throwable, PhaseId phaseId)
    throws Throwable
  {

boolean isCustomExp  = false;
    for (int i = 0; i < 10; i++)
    {
      if (throwable instanceof XxCustomException)
      {
        isCustomExp = true;
        break;
      }
      if (throwable != null)
      {
        throwable = throwable.getCause();
      }
   }

    if (isCustomExp)
    {
      if (throwable!= null)
      {


// The below method will show a Faces Message. If client id of xxCustomException is not null then it will show a faces message on that component. It will try to get the message from resource bundle based on resourceBundleKey attribute. Error_type will decide if it is info, warning, severe

        XxUtils.showMessage((XxCustomException)throwable);
      }
    }
    else
    {
//this will be handled at taskflow level
      throw z;
     }
 }


3.  Taskflow Exception Handler
        Here We will discuss on session timeout and exception handling for at taskflow level by creating an Exception Handler

Task Flow changes
Create a router in your taskflow:


Add a condition which points to a method in backing bean. 
The method returns true if session expires and user is redirected to home/login page as needed.
And if method returns false, the user is redirected to default outcome - errorPage.

Mark the router as exception handler 



BEAN changes
Add the following method in your bean:

  public boolean isSessionExpired()
  {
    Exception e =
      ControllerContext.getInstance().getCurrentViewPort().getExceptionData();
    if (e != null && (e instanceof ViewExpiredException))
    {


// session  timeout case
      return true;
    }


// IF SOA is down or some other fault in SOA process

    else if (e != null &&
             (e instanceof ConnectException || e instanceof javax.xml.ws.WebServiceException ||
              e instanceof javax.xml.ws.soap.SOAPFaultException || e.toString().contains("Failed to access the WSDL")))
      putParameterinPageFlowScope("errorMessage",
                                  "Currently the system is in maintenance mode. Please try after sometime.");
    else
      putParameterinPageFlowScope("errorMessage",
                                  "Some unexpected error has occurred. Please try after sometime.");
    if (e != null)
    {
      StringWriter errors = new StringWriter();
      e.printStackTrace(new PrintWriter(errors));
      if(errors != null)
         putParameterinPageFlowScope("detailedException",errors.toString());
    }
    return false;
  }

Note:

In case where there is an exception other than ViewExpiredException(session timeout), write two parameters in request or pageFlowScope as written above:

·          Put Parameter in PageFlowScope("errorMessage", "Currently the system is in maintenance mode. Please try after sometime.");
·          Put Parameter in PageFlowScope ("detailedException",errors.toString());




Error Page
  
 <af:outputFormatted value="#{pageFlowScope.errorMessage}"/>
  <af:outputFormatted value="#{pageFlowScope.detailedException}" visible="false"/>

Note:

visible="false" makes sure the detailed exception is there in source of the page and user doesn`t see it.
You can see the same in page source.

You can add more conditions and messages in your bean method based on your scenarios like Content Server related exceptions, oim client,Bpm related etc.

 For any issue in implementation please comments.

Thanks



Saturday, February 25, 2017

Programmatically Component Creation in ADF

Programmatically component creation and applying skining and validation on component programmatically.
          

  1. Create fusion ADF application and in view controller create page    
  2. Find a parent component to create child under it as any layout (panel form, panel group, af:form etc)
  3. Suppose you have a page with a panel form layout, now you have to create child components in this form layout at runtime   
  4. Dropped a button on page , on this button action i will create an inputText                                    programmatically and assign validator method reference to it.
  5. Create mananege bean class.
  6. Bind the form component value with manage bean .


     <af:panelFormLayout id="pfl1" binding="#{pageFlowScope.ProgramComponent.panelForm}">
                    <f:facet name="footer"/>
                </af:panelFormLayout>
    binding with panelForm:


                  























         add component method which help in adding component under the parent layout.


     

creating object of component and setting properties and calling add component .





create one helper method to resolve Validator 





and now add the validator into the input component 

ui.setValidator( resolveValidator("{pageFlowScope.ProgramComponent.inputValidator}"));















Thanks to ashish