Thursday, October 31, 2013

Handling exceptions in the ADF taskflow

-         Through exception handling we can designate an Activity as exception handler
-          For the flow from the exception handling activity uses the standard exception handling activity
-          You can use router as exception handling activity and reaching the exception from here it will can route to various control flow cases based on exception.
-          A task flow can have only one exception handling activity
-          If no exception handling mechanism provided the exception propagated to the top level tf till the webcontainer
-          ADF Model also provide exception handling mechanism. An exception thrown by any type of binding is caught by the ADF Model which calls the reportException() stores the exception in the binding container

-          Later page renders error displays

Create a task flow below 


For the testMeth1 activity attch the method as 

#{pageFlowScope.handleException.exception}

View1.jspx

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <af:panelGroupLayout id="pgl1">
    <af:button text="button 1" id="b1" action="toMeth"/>
  </af:panelGroupLayout>
</jsp:root>
testMeth1
#{pageFlowScope.handleException.exception}

The managed bean handleException

package view.test;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import oracle.jbo.JboException;

public class TestException {
    public TestException() {
        super();
    }

    public void exception() {
        throw new JboException("test here");
    }

    public void exceptionMessage() {
        System.out.println("Here");
        try {
            System.out.println("Inside Handeler");
            FacesMessage message = new FacesMessage("This is custom Message for Jbo Exception-Exception Handeler");
            message.setSeverity(FacesMessage.SEVERITY_WARN);
            FacesContext fc = FacesContext.getCurrentInstance();
            fc.addMessage(null, message);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void badCall() {
          
       }

    public String badActionHere() {
System.out.println("Here...");
        return null;
    }
}

Create a page to test by drag and drop the page as region and run.Click on the button and you see the custom exception message.



Reenterng Bounded Task Flow

 task-flow-reentry  Option is used to handle cases with user re-enter to the task flow using back button.Task flow uses re-entry not allowed or reentry-outcome-dependent options for task-flow-re-entry.For reentry settings , redirect activity with in task flow should set true.



  • reentry-allowed - Reentry allowed on any view activity within bounded task flow 
  • reentry-not-allowed - User can go back to the screen but clicking on any button with in the view throws InvalidTaskFlowEntry exception 
  • reeenty-outcone-dependent - User can navigate to the a task flow using browser button solely on how user originally exited the tf.

 
reeentry-not-allowed 

Create a taskflow 
Reentry_view1.jspx
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <!--<jsp:directive.page contentType="text/html;charset=UTF-8" />
-->
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1">
      <af:form id="f1">
        <af:panelGroupLayout id="pgl1">
          <af:button text="button 1" id="b1" action="toRet"/>
        </af:panelGroupLayout>
      </af:form>
    </af:document>
  </f:view>
</jsp:root>

Not that Redirect property=true for this view.
Create the main page in the adfc-config.xml 

Main.jspx
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <f:view>
        <af:document title="main.jspx" id="d1">
            <af:form id="f1">
                <af:panelGroupLayout id="pgl1">
                    <af:button text="button 1" id="b1" action="toTF"/>
                </af:panelGroupLayout>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

Run the main.jspx . Navigate the UIs and try the browser back button
<Oct 6, 2013 6:08:42 PM IST> <Error> <oracle.adfinternal.view.faces.context.RichExceptionHandler> <BEA-000000> <ADF_FACES-30200:For more information, please see the server's error log for an entry beginning with: The UIViewRoot is null. Fatal exception during PhaseId: RESTORE_VIEW 1.
oracle.adf.controller.InvalidTaskFlowReentryException: ADFC-06016: Task flow reentry is not allowed: '/WEB-INF/tfReentry.xml#tfReentry'.
            at oracle.adfinternal.controller.state.ControllerState.reentryNotAllowed(ControllerState.java:1019)
            at oracle.adfinternal.controller.state.ControllerState.reenterTaskFlow(ControllerState.java:992)
            at oracle.adfinternal.controller.state.ControllerState.recoverState(ControllerState.java:925)
            at oracle.adfinternal.controller.state.ControllerState.synchronizeStatePart1(ControllerState.java:369)
            at oracle.adfinternal.controller.application.SyncNavigationStateListener.beforePhase(SyncNavigationStateListener.java:263)
            at oracle.adfinternal.controller.lifecycle.ADFLifecycleImpl$PagePhaseListenerWrapper.beforePhase(ADFLifecycleImpl.java:557)
            at oracle.adfinternal.controller.lifecycle.LifecycleImpl.internalDispatchBeforeEvent(LifecycleImpl.java:100)
            at oracle.adfinternal.controller.lifecycle.LifecycleImpl.dispatchBeforePagePhaseEvent(LifecycleImpl.java:147)
            at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener$PhaseInvokerImpl.dispatchBeforePagePhaseEvent(ADFPhaseListener.java:290)
            at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener.beforePhase(ADFPhaseListener.java:76)

reentry-outcome-dependent
Change the re-entry option for the tf return based on the task flow activity outcome the re-entry option changes.
Managed bean values upon taskf flow reentry
Value of managed bean reset to the value of the managed bean before the end user existed the btf.Value of btf before the re-entry is lost .To change this set the re-direct property of the tf.

Thursday, October 3, 2013

ADF TaskFlow Transaction Basics

Transaction is a collection of works either committed or rollback.Create a calling and called task flow to go through some of the transaction basics of task flow

Calling Task flow :


Called Task flow : 


From the behavior section of the called task flow you can see the following options


  •  No Controller transaction is the default option means the called task flow does not participate any transaction management.
  • Always begin New Transaction - Transaction is created when enter to the task flow and completes the task flow when exists the task flow 
  • Always Use Existing transaction - Called task flow participates the existing transaction 
  • User Existing transaction if possible - Participate the existing transaction if available or start a new transaction if not available 
  • restore-save-option


Use restore-save-option =true if you want to discard the changes the end user makes with in a called bounded task flow when the called bounded task flow exits.This option apply only if the bounded task flow is entered by joining the existing transaction and a save point created on entry



No save point on task flow entry if selected prevent the creation of ADF model save point on task flow entry if taskflow participate in 'Always Use existing transaction ' or 'User existing transaction if Possible' . In this case overhead associated with a save point is not created for the transaction.

End the transaction from task flow return activity by selecting the End transaction property to commit or rollback.

Shared Data control behavior and transaction

Share data controls with calling task flow have the options Shared and Isolated

Transaction setting
Shared Data Control scope
Isolated Data Control scope
No controller txn
DataControlFrame shared without open txn
New DataControlFrame is created without an open transaction
Always begin new txn
Begin new if one is not open
Always begin new one
Always Use existing txn
Throws exception if txn is already open
Invalid.The checkbox cannot be deselected
Use Existing txn if possible
Begin a new txn if one is not already open
Always begin a new txn