9 Replies Latest reply: Sep 13, 2013 2:18 AM by 819794 RSS

    How to access BPM 11g payload or process varibles in ADF task flow

    M Peterson
      I am trying to view/edit data in a UI tied to a database using a foreign key, requestId. The foreign key comes from a BPM process where it is passed into the task flow, from a human task. The foreign key comes from process variables or payload values. I know I can simply load the payload in BPM with data from the tables, but I'm looking for a better solution to leverage ADF Business components to view and edit the data directly in the UI.

      The BPM process uses a web service to kick off the process. The web services takes a primary key as a parameter to reference a column in the database table. The database is pre-populated with content and a primary key reference. The first activity is a user activity. I want the task flow behind the user activity to accept this primary key and use it to locate the desired row in the database so views associated with database bounded ADF Business Components can work to present the data in the UI.

      I've tried two approaches to the problem. The first uses the operation setCurrentRowWithKeyValue. The other modifies the SQL where clause, used by the ADFbc Iterator, to only return a row for the given requestId. Both approaches fail to work because I don't know how to access the BPM payload or data variables coming into the task flow. Here's the snipet of code I used to try to set the row using setCurrentRowWithKey value:

      public String setRequestId() {

      FacesContext context = FacesContext.getCurrentInstance();
      Object requestObj = context.getApplication().evaluateExpressionGet(
      context, "#{bindings.RequestId.inputValue}", Number.class);
      if (requestObj== null)
      return null;
      Number requestId;
      requestId = (Number)requestObj;

      DCIteratorBinding itr = (DCIteratorBinding)

      getBindings().get ("PatfRequestHdrView1");

      itr.setCurrentRowWithKeyValue(requestId.toString() );

      return null;

      I haven't gotten very far with the second approach, modified SQL where clause, since I don't know Groovy. I think I need something like:

      adf.object.viewObj.RequestId. But there isn't a viewObject associated with BPM data, so I'm sure this particular expression won't work.

      Any help you can give me is very appreciated.

      Regards,
      Mark
        • 1. Re: How to access BPM 11g payload or process varibles in ADF task flow
          725165
          Mark,

          You said you're not sure how to access payload data, but it looks like the code you have below should theoretically work. Does requestObj contain a value or is it always null? If you open up your .jspx file in JDeveloper and go to the bindings tab is there a "RequestId" attribute binding that refers to the task payload?

          Are you invoking this method from the jspx via EL expression referencing some managed bean in the task flow?

          It's hard to determine what isn't working or why based on what you've said so far.

          You can always fire up the SOA server in debug mode and attach a remote debugger in JDeveloper - that helps a ton when debugging managed beans in UI projects.
          • 2. Re: How to access BPM 11g payload or process varibles in ADF task flow
            M Peterson
            I tried to execute the code from different places. From the task flow initializer, which doesn't seem to do anything, and from a method activity in the task flow. This caused an execution error. I'll have to go back and recreate the error to show you.
            • 3. Re: How to access BPM 11g payload or process varibles in ADF task flow
              725165
              I think if you're trying to execute this directly in the task flow itself, and not a specific .jspx file within the task flow then you're going to run into problems accessing the binding layer using the syntax you provided. Generally speaking, the bindings are specific to an individual page and not the taskflow as a whole. When you auto-generate a task form for a human task, or drop the payload from the data control of a human task definition onto a blank jspx page JDeveloper automatically creates page bindings for the page that reference the data control (look at the page bindings .xml file).

              Does the code you're trying to execute need to run before any page is displayed in the task flow, or does it need to interact with components on the page somehow?

              If it needs to interact with a page, you're better off creating a managed bean with the appropriate scope (request or pageFlowScope likely) in the task flow so that it will automatically instantiate your class and then you can access it via EL expressions on the jspx page.

              To access the page level bindings at the task flow level, click on an activity (page/method call, whatever) in your bounded task flow and go to the property editor. Open the expression builder on a field that allows it, and drill into the ADF bindings node. You'll see here bindings for each page, drill down to the appropriate one to access your attribute. It'll look something like #{data.taskDetails1PageDef.attributeName} . I haven't used this approach personally, so I'm not 100% sure when that data gets initialized - on initialization of the task flow or the page itself.
              • 4. Re: How to access BPM 11g payload or process varibles in ADF task flow
                M Peterson
                The first thing I want the task flow to do is display a page with a form showing the values from the database. This is why I tried to call the method first. If I add the setCurrentRowWithKey to the form as a button, I can get the form to load the data, but it's a two step process, requiring the user to click a button. The method approach throws the following exceptioin

                oracle.adf.controller.activity.ActivityLogicException: ADFC-02013: The ADF Controller cannot find metadata for activity '/WEB-INF/ApproveTravel_TaskFlow.xml#ApproveTravel_TaskFlow@setTravelRecord'.
                     at oracle.adfinternal.controller.util.Utils.createAndLogActivityLogicException(Utils.java:230)
                     at oracle.adfinternal.controller.engine.ControlFlowEngine.doRouting(ControlFlowEngine.java:927)
                     at oracle.adfinternal.controller.engine.ControlFlowEngine.doRouting(ControlFlowEngine.java:777)
                     at oracle.adfinternal.controller.engine.ControlFlowEngine.routeFromActivity(ControlFlowEngine.java:551)
                     at oracle.adfinternal.controller.engine.ControlFlowEngine.performControlFlow(ControlFlowEngine.java:147)
                     at oracle.adfinternal.controller.application.NavigationHandlerImpl.handleAdfcNavigation(NavigationHandlerImpl.java:109)
                     at oracle.adfinternal.controller.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:78)
                     at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:130)
                     at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
                     at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
                     at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:756)
                     at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:698)
                     at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:285)
                     at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:177)
                     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
                     at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
                     at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
                     at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
                     at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
                     at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
                     at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:191)
                     at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
                     at oracle.adf.share.http.ServletADFFilter.doFilter(ServletADFFilter.java:62)
                     at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
                     at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:97)
                     at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:420)
                     at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
                     at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:420)
                     at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:2
                • 5. Re: How to access BPM 11g payload or process varibles in ADF task flow
                  M Peterson
                  I fixed the error, "ADFC-02013: The ADF Controller cannot find metadata for activity" error. I needed to define the "forced outcome" value. And now I'm getting null values for the travelReqId binding; #{bindings.travelReqId.inputValue}. This occurs from the method call used to set the setCurrentRowWithKeyValue:

                  See code snipet:

                  public String setRequestId() {
                  FacesContext context = FacesContext.getCurrentInstance();
                  Object requestObj = context.getApplication().evaluateExpressionGet(
                  context, "#{bindings.travelReqId.inputValue}", Number.class);
                  if (requestObj== null){
                  System.out.println("*****************************");
                  System.out.println("requestId is null");
                  System.out.println("*****************************");
                  return null;
                  }
                  • 6. Re: How to access BPM 11g payload or process varibles in ADF task flow
                    725165
                    I think it's resolving to null because the EL expression you're using isn't valid yet at that point in the task flow. The "bindings" implicit object is only valid when accessed from within a jspx I believe. You could try the EL using the "data" implicit object and the pageDef for the appropriate task details page I mentioned earlier, although I'm not sure that will be initialized at this point either.

                    I'm working on some sample code you should be able to use to extract the data from the payload using the human workflow services API - this won't tie you to the page bindings so you should be able to use it anywhere in the taskflow.
                    • 7. Re: How to access BPM 11g payload or process varibles in ADF task flow
                      725165
                      Try this code in your method:

                      FacesContext context = FacesContext.getCurrentInstance();
                      String ctx = (String) context.getApplication().evaluateExpressionGet(context, "#{pageFlowScope.bpmWorklistContext}", String.class);
                      String tskId = (String)context.getApplication().evaluateExpressionGet(context, "#{pageFlowScope.bpmWorklistTaskId}", String.class);
                      IWorkflowServiceClient workflowSvcClient = WorkflowService.getWorkflowServiceClient();
                      ITaskQueryService wfQueryService = workflowSvcClient.getTaskQueryService();
                      IWorkflowContext wfContext = wfQueryService.getWorkflowContext(ctx);
                      Task myTask = wfQueryService.getTaskDetailsById(wfContext, tskId);
                      XMLElement xmlPayload = (XMLElement) myTask.getPayloadAsElement();
                      //get the payload as a simple string, useful for debugging
                      java.io.StringWriter writer = new java.io.StringWriter();
                      xmlPayload.print(writer);
                      String payloadAsString = writer.toString();
                      //extract values from payload - use methods in Oracle's XDK

                      See this post also:

                      Programmatically reading Task details
                      • 8. Re: How to access BPM 11g payload or process varibles in ADF task flow
                        M Peterson
                        Works like a champ!

                        Thank you Mike!
                        • 9. Re: How to access BPM 11g payload or process varibles in ADF task flow
                          819794

                          Hi,

                                       I am also having same Scenario as you faced. In my case, From BPM Human Task, one parameter value will be passed to Next page. Now based on the parameter value I need to filter DB table to show value in Next page. Currently Parameter is displayed in Payload in DataControl. I need to get Parameter value from Payload and execute query before Opening a page.

                           

                          I am creating TaskFlow for each Human Task. So onload of taskFlow before opening page I need to do above operation.. Can you please explain how you achived?

                           

                           

                           

                          Thanks with Regards,

                          Praveen.