Saturday, August 31, 2013

ADF task Flow Activities with Page Def file

Page definition files define the binding objects that populate data at runtime .This file bind the UI component with the data control .Following are the task flow activities use page definition file to bind data control

  • Method call
  • Router
  • Task Flow call 
  • View 

How to create Page def file?
Right click on each activity and select the option "Create Page Definition".Sample page def file for a task flow call activity
<?xml version="1.0" encoding="UTF-8" ?>
<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="12.1.2.66.68"
                id="tfListeners_tfListeners_tfListenerCalledPageDef" Package="view.pageDefs" SkipValidation="true">
  <parameters/>
  <executables>
    <variableIterator id="variables"/>

  </executables>

ADF Task Flow Return Activity

Return Activity is used when bounded task flow completes and send control flow back to caller.Return activity works only with the bounded task flow.Return task flow's reentry is option is set only if the task flow's reentry-outcome-dependent is set.End transaction option is available for the Return activity for transaction commit and rollback.Also we can set the restore save point option to either true or false.

Create a called task flow as below

return_called_view1.jsff
<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Return Activity Calling TF" id="ot1"/>
    <af:button text="button 1" id="b1" action="testOutCome"/>
  </af:panelGroupLayout>

</jsp:root>

return_called_view1.jsff :
<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:outputText value="Called Task Flow" id="ot1"/>
    <af:button text="Calling Retun" id="b1" action="toReturn"/>
  </af:panelGroupLayout>
</jsp:root>

Task flow return activity options are as shown below 
The outcome "goToView2" is the control flow case defined in the calling task flow. Also look at the other options like Reentry,End Transaction and Restore Save Point.

Calling Task flow:
Also set the listeners for the task flow call activity. Below the managed bean for the before and after listener for the task flow call activity.

package test.view;


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

    public void beforeListerner() {
        System.out.println("Before listener called ");

    }

    public void afterListener() {
        System.out.println("After listener called ");
    }
}

The code for the jspx files in the calling task flow
return_view1.jspx 

<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Return activity" id="ot1"/>
    <af:button text="button 1" id="b1" action="tocall"/>
  </af:panelGroupLayout>
</jsp:root>

return_view2.jspx 

<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="To view2" id="ot1"/>
  </af:panelGroupLayout>
</jsp:root>

Drag and drop the calling task flow to a jspx file as a region and run the page. Click through the command buttons to reach the final view in the UI.Check the jdeveloper log to see the after listeners are executed.

ADF Task FLow Call Activity Listeners

Task flow call activity can before and after listeners.These listeners identify the start and end of the bounded task flow.The listener method cannot take parameters.Control flow must return from bounded task flow using control flow rule to execute the after listener.User leaves bounded task flow using browser back button or entering to other URL the after listener won't be called.Need to use task flow finalizers to release resources in this case.
Create a called task flow with task flow return activity
listener_called_view1.jsff:
<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Called Listener" id="ot1"/>
    <af:button text="Return" id="b1" action="toReturn"/>
  </af:panelGroupLayout>

</jsp:root>

Create a calling Task flow 
listener_view1.jsff 

<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="TF Listeners" id="ot1"/>
    <af:button text="button 1" id="b1" action="toCall"/>
  </af:panelGroupLayout>
</jsp:root>

Create a managed bean in request scope as below 
package test.view;


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

    public void beforeListerner() {
        System.out.println("Before listener called ");

    }

    public void afterListener() {
        System.out.println("After listener called ");
    }
}
Drag and drop the calling task flow to the jspx page as a region and run the page. Click on the buttons in the views.Note the listeners are executed and see the messages in the log.

Thursday, August 29, 2013

URL Syntax to Invoke Bounded Task Flow

Sample URL is as below :

Format is 
<server-root>/<app-context>/faces/adf.task-flow?adf.tfId=<task flow definition id>&adf.tfDoc=<document name>&<named parameter>=<named parameter value>
Parameter name should not begin with an underscore ('_') .This is reserved for internal purpose.

ADF Calling Bounded Task Flow Using URL

Task Flow can be called through a URL. Both calling and called Task flows should use pages not page fragments(.jsff).Task flow reference and remote-app-url property combined generate URL of remote task flow URL.
Create  an ADF application and create a bounded task flow in it.

Note the URL invoke property is set to url-invoke-allowed in the task flow.

Code for the remoteCallView.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="remoteCallView.jspx" id="d1">
            <af:form id="f1">
                <af:panelGroupLayout id="pgl1">
                    <af:outputText value="Remote call" id="ot1"/>
                </af:panelGroupLayout>
            </af:form>
        </af:document>
    </f:view>

</jsp:root>
Run the remote task flow 

Create another ADF application and a bounded task flow as below.
For the task flow call activity give the properties as shown. Give a value to Document,ID,and a remote application through a managed bean.Create a managed bean in the request scope as  below 
package test.view;


public class RemoteCall {
   private String remoteURL;

    public void setRemoteURL(String remoteURL) {
        this.remoteURL = remoteURL;
    }

    public String getRemoteURL() {
        remoteURL="http://127.0.0.1:7101/TFAppRemote-ViewController-context-root/faces/adf.task-flow?adf.tfId=remoteCallTesting&adf.tfDoc=/remoteCallTesting.xml";
        return remoteURL;
    }
}

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

For calling bounded task flow using URL we can add a context parameter in web.xml for the URL.We can access the URL using #{initParam.remoteURL}

The url reference in the task flow
Though it shows an error message in the task flow diagram ,it works.

ADF Dynamic Task Flow reference

We can define task flow reference dynamically using a EL expression . Create a bounded task flow as below
Code for dynamic_called_view1.jspx 
<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Dynamic called view1" id="ot1"/>
  </af:panelGroupLayout>
</jsp:root>

Create a calling task flow 

Note the properties for the task flow activity.Here task flow reference is Dynamic and reference is getting from EL expression.Below is the code for the managed bean in pageFlowScope used for dynamic task flow reference.
package test.view;


public class TestDynamicCall {
    private String tFUrl = "";

    public void setTFUrl(String tFUrl) {
        this.tFUrl = tFUrl;
    }

    public String getTFUrl() {

        System.out.println("Inside getTFUrl..");
        if (true)
            return "/WEB-INF/dynamic_calledTF.xml";
        else
            return "/WEB-INF/dynamic_calledTF1.xml";


    }

    public TestDynamicCall() {
        super();
    }
}

Drag and drop the calling task flow to a jspx file as a region.Clicking on the button the flow will  dynamically moved to the called TF.

ADF Task Flow Call Activities

Task Flow call activities are getting used to call a bounded task flow from either bounded task flow or from unbounded task flow.Chaining of class flow  is possible means one task flow can another and that one can call another etc.Bounded task flow can accept input parameters. Calling task flow can pass the parameters to the called task flow. When we drag and drop a bounded task flow to the task flow bounded or unbounded the input parameters of the called task flow will be available in the calling task flow to pass the values.Return parameters for task flow is also possible.

We can add task flow call by following method

  •  Drag and drop a bounded task flow to either bounded or unbounded task flow
  •  Drag a task flow call activity to the task flow and browse to the appropriate bounded task flow

Called task flow :
Create a bounded called task flow as below
See below the input parameter defined for the called task flow 
Code for called_view1.jspx 
<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Called  #{pageFlowScope.inputParameter1}" id="ot1"/>
  </af:panelGroupLayout>
</jsp:root>


Calling Task flow
Create a bounded task flow to call the other task flow.
Create the method call of the above task flow as shown below
Method here refers to a managed bean method in pageFlowScope. Also note the default outcome defined.
The managed bean in pageFlowScope defined is as below
package test.view;

import oracle.adf.view.rich.context.AdfFacesContext;

public class TestBTCall {
    private String testVal;

    public void setTestVal(String testVal) {
        this.testVal = testVal;
    }

    public String getTestVal() {
        return testVal;
    }

    public TestBTCall() {
        super();
    }
    public void setVariable() {
      //  HttpServletRequest req=(HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
      
        
       AdfFacesContext.getCurrentInstance().getPageFlowScope().put("testValue", "Testing");
        System.out.println(AdfFacesContext.getCurrentInstance().getPageFlowScope().get("testValue"));
    }

}

Here the bean set the pageFlowScope variable "testValue".Code for calling_view1.jspx is as below 
<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Calling_view1" id="ot1"/>
    <af:button text="button 1" id="b1" action="toTFCall"/>
  </af:panelGroupLayout>
</jsp:root>

Task flow call activities details are as shown 

The input parameters are getting from the called task flow by default.Note here the task flow reference is static.
Running the task flow:
Drag and drop the calling task flow to a region of a test.jspx page. Run the jspx file. Click on the button in calling_view1.jspx. See the output "Called Testing" displayed.

Code snippet for task flow calling :

<task-flow-call id="taskFlowCalled">
      <task-flow-reference>
        <document>/taskFlowCalled.xml</document>
        <id>taskFlowCalled</id>
      </task-flow-reference>
      <input-parameter id="__3">
        <name>inputParameter1</name>
        <value>#{pageFlowScope.testValue}</value>
      </input-parameter>
    </task-flow-call>

Monday, August 26, 2013

ADF Task Flow Method Call Activities With Parameters and Return type

Method call activities allow to call a custom method.It invokes the method before the application render the page.This approach is better than invokeAction in the page def file.You may need to use invokeAction for the following cases

  • Method needs to execute more than one phase of page's lifecycle 
  • Reuse the page and page def file with the method in it 
  • Not using adf controller 
Create a managed bean in the request scope 

package test.view;


public class MethodCall {
    public MethodCall() {
        super();
    }
  
    public String testMyReturn(String a) {
        System.out.println(" Arg ="+a);
        return "Test Arg="+a;
    }
}
Create a bounded task flow with the method call 
Method call activity has the following 
  • Method using EL 
  • Optional Parameters with class and value 
  • Optional return type of the method stores in a variable.
methCall_view.jspx 

<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="#{pageFlowScope.testReturn}" id="ot1"/>
  </af:panelGroupLayout>
</jsp:root>

Drag and drop the task flow as a region in testMethCall.jspx and Run the page.

ADF Task Flow Router Activities

Router activity is used to route the activities based on run-time evaluation of EL.Create a bounded task flow as below

Router activity has 
  • Default outcome 
  • Can define cases at any point of development/design 


router_view1.jspx
<?xml version='1.0' encoding='UTF-8'?>
<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:outputText value="Router view1" id="ot1"/>
    <af:button text="button 1" id="b1" action="toRouter"/>
  </af:panelGroupLayout>

</jsp:root>

Create a managed bean in the pageFlowScope 

package test.view;


public class RouterTest {
 
    public boolean router=false;
    public RouterTest() {
        super();
    }
   
    public void setRouter(boolean router) {
        this.router = router;
    }

    public boolean isRouter() {
        return router;
    }

 
}

The source code changes in bounded task flow xml for router activity
<router id="router1">
      <case id="__6">
        <expression>#{pageFlowScope.Router.router}</expression>
        <outcome>routeView2</outcome>
      </case>
      <default-outcome>routView3</default-outcome>
    </router>

ADF Task Flow URL View Activity

Using URL activity we can redirect view port to any URL addressable resources like

  • Bounded task flow 
  • View activities in the unbounded task flow 
  • External resources 

Create a bounded task flow below

URL activity has 
  • Option to provide URL based on EL 
  • Add optional parameter with name,value and a converter


Create a managed bean in the request scope
package test.view;


public class TestUrl {
 private String goUrl="http://www.google.com";
   
    public void setGoUrl(String goUrl) {
        this.goUrl = goUrl;
    }

    public String getGoUrl() {
        return goUrl;
    }

}
Source code for url_view1.jspx 

<?xml version='1.0' encoding='UTF-8'?>
<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="testURL"/>
  </af:panelGroupLayout>
</jsp:root>
Drag and drop the task flow as a region in the restUrl.jspx .Run the page and click on the button will redirect to the external URL.

Friday, August 23, 2013

Specifying HTTP redirect for ADF View Activity


  • ADF controller issues and HTTP redirect response to a view activity request
  • #{binding} cannot be used as the concept working on redirection
  • HTTP redirect is not possible for book markable view 
Make the view activity's redirection property =true.

Book Marking ADF View Activities

Book Marking is possible only for the Unbounded TaskFlow view activities.For this we need to make the page as bookmarkable. Run time you can identify the view activity as book mark-able by the method ViewBookMarkable().URL parameters can be created to a view activity designated as book markable.URL parameter can be created using EL expressions .There is an option to provide an optional method which will get execute before rendering the view activity.Also there is an option to provide converter to each URL parameter for conversion and validating the input parameters.

Create a bounded task flow
Create a managed bean on PageFlowScope.
package test.view;


public class BookMarkable {
    private String idTest="Test1";
    private String valueTest="Test2";
    private String IdConverter;

    public void setIdConverter(String IdConverter) {
        System.out.println("setIdConverter");
           
        this.IdConverter = IdConverter;
    }

    public String getIdConverter() {
        System.out.println("getIdConverter");
        return IdConverter;
    }

    public void setIdTest(String idTest) {
        this.idTest = idTest;
    }

    public String getIdTest() {
        return idTest;
    }

    public void setValueTest(String valueTest) {
        this.valueTest = valueTest;
    }

    public String getValueTest() {
        return valueTest;
    }
 
    public BookMarkable() {
        super();
    }
  
    public void  someMethod() {
        System.out.println("Som method executed ....");
       
    }

}
Code for book_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"/>
    <f:view>
        <af:document title="book_view1.jspx" id="d1">
            <af:form id="f1">
                <af:panelGroupLayout id="pgl1">
                    <af:outputText value="#{pageFlowScope.BookMarkable.idTest}" id="ot1"/>
                    <af:outputText value="#{pageFlowScope.BookMarkable.valueTest}" id="ot2"/>
                </af:panelGroupLayout>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

Define the bookmark properties after selecting the view activity from the task flow 

Creating the converter 
Create a class implementing .adf.controller.UrlParameterConverter

package test.view;

import oracle.adf.controller.UrlParameterConverter;

public class BokMarkURLConverter implements UrlParameterConverter {
    public BokMarkURLConverter() {
        super();
    }

    @Override
    public Object getAsObject(String string) {
        System.out.println("String ="+string);
        // TODO Implement this method
        return null;
    }

    @Override
    public String getAsString(Object object) {
        System.out.println("Object ="+object);
        // TODO Implement this method
        return null;
    }
}

Method getAsObject() and getAsString() is used for validation and conversion. You can create a separate classes for each URL parameters.

Run the page.
Access the page with the url parameters as below and you can see the parameters printed in the screen