Monday, January 5, 2015

Oracle BPM: Display User BPM Tasks Inside ADF Application (Post2)

In my previous post we see how you can display user BPM worklist inside ADF application, but there is one question now, how the bpm worklist know the user which suppose to display his tasks?

You should generate object of IWorkflowContext  using login user information (username and password). To do this follow these steps:

1- In ViewController project add 2 libraries (oracle.bpm.bpm-services.client.jar and oracle.bpm.bpm-services.interface.jar) you can find these jars in (C:\Oracle\Middleware\Oracle_SOA1\soa\modules\oracle.bpm.client_11.1.1)

2- In you ADF application make new class "BPMContextClass.java"


 ////////// BPMContextClass.java ////////////

import java.util.HashMap;
import java.util.Map;
import oracle.bpel.services.bpm.common.IBPMContext;
import oracle.bpel.services.workflow.client.IWorkflowServiceClient;
import oracle.bpel.services.workflow.client.IWorkflowServiceClientConstants;
import oracle.bpel.services.workflow.client.WorkflowServiceClientFactory;
import oracle.bpm.client.BPMServiceClientFactory;
import oracle.bpm.services.client.IBPMServiceClient;

public class BPMContextClass
{
  private static String url = "t3://localhost:7001"; // BPM serverIp:port

  public static BPMServiceClientFactory getBPMServiceClientFactory()
  {
    Map properties = new HashMap();
    properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.CLIENT_TYPE, WorkflowServiceClientFactory.REMOTE_CLIENT);
    properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL, url);
    properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    return BPMServiceClientFactory.getInstance(properties, null, null);
  }

  public static IBPMContext getIBPMContext(String username, String password) throws Exception
  {
    return getBPMServiceClientFactory().getBPMUserAuthenticationService().authenticate(username, password.toCharArray(), null);
  }

  public static IWorkflowServiceClient getIWorkflowServiceClient()
  {
    return getBPMServiceClientFactory().getWorkflowServiceClient();
  }

  public static IBPMServiceClient getBPMServiceClient()
  {
    return getBPMServiceClientFactory().getBPMServiceClient();
  }
}

/////////End BPMContextClass.java///////

3- Follow the previous post to make page display user worklist (e.x. userTasks.jspx).

4- From faces-config.xml make new global navigation rule and set  userTasks.jspx "From Outcome" to "userTasks"


5- Make new login page (login.jspx) as shown


6- In the login button action write this code

  public String loginAction()
  {
    FacesContext ctx = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest)ctx.getExternalContext().getRequest();
    String usernameValue = null;
    try
    {
      usernameValue = usernameInputText.getValue().toString();
      String passwordValue = passwordInputText.getValue().toString();
      Subject subject = Authentication.login(new URLCallbackHandler(usernameValue, passwordValue));
      weblogic.servlet.security.ServletAuthentication.runAs(subject, request);
      IWorkflowContext workflowContext = initBPMContext(usernameValue, passwordValue);
      setManagedBeanValue("sessionScope.workflowContext", workflowContext);
      IBPMContext ibpmContext = BPMContextClass.getIBPMContext(usernameValue, passwordValue);
      setManagedBeanValue("sessionScope.ibpmContext", ibpmContext);
    }
    catch (Exception e)
    {
      // TODO: Add catch code
      e.printStackTrace();
      return null;
    }
 
    return "userTasks";
  }

8- In the login backbean write this code (this code will be used by login button action "loginAction()")

  public IWorkflowContext initBPMContext(String userName, String password) throws WorkflowException
  {
    IWorkflowServiceClient wfSvcClient = WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT);
    ITaskQueryService querySvc = wfSvcClient.getTaskQueryService();
    IWorkflowContext ctx = querySvc.authenticate(userName, password.toCharArray(), null);
    return ctx;
  }

  public void setManagedBeanValue(String beanName, Object newValue)
  {
    StringBuffer buff = new StringBuffer("#{");
    buff.append(beanName);
    buff.append("}");
    setExpressionValue(buff.toString(), newValue);
  }

  public void setExpressionValue(String expression, Object newValue)
  {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    Application app = facesContext.getApplication();
    ExpressionFactory elFactory = app.getExpressionFactory();
    ELContext elContext = facesContext.getELContext();
    ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
    Class bindClass = valueExp.getType(elContext);
    if (bindClass.isPrimitive() || bindClass.isInstance(newValue))
    {
      valueExp.setValue(elContext, newValue);
    }
  }



7- deploy the application to SOA server and after login you will find user worklist.



You can download the sample application from here.