Passing on a session variable to the BC layer in ADF

2

In one of our projects we ran into this next problem. We had a ViewObject with attributes representing several columns from two tables. Depending on whether or not the value of one of the attributes was modified, we needed to be able to store a user id in an auditing table using a trigger that reads this user id from a table that gets updated. This little article tells you how we did it.

In our application module, we defined a variable representing the user id that needs to be stored and a getter and setter for this variable:

private Long userId;
public Long getUserId()
{
  return userId;
}
public void setUserId(Long userId)
{
  this.userId = userId;
}

The setUserId method then was published via the Client Interface of the app module. Next, we extended the JhsDataAction with our own action and made sure the setUserId method is called everytime data changes need to be stored in the BC layer:

public void processUpdateModel(DataActionContext daContext) {
  AppModule app = getAppModule(daContext);
  app.setUserId(((UserInfo)daContext.getHttpServletRequest().getSession().getAttribute("userinfo")).getId());
  super.processUpdateModel(daContext);
}

Finally, the user id needs to be stored in the proper row of the ViewObject. Since our application allows to either update a single row, or multiple rows, we need to filter for those two situations. We have tried several ways to distinguish between single row and multiple row updates, but the only way we found was to check for the request URI. Not a very good way, I know, so if you know a better way, please let me know!
So, the processUpdateModel method given above was extended this way. First, we check the request URI to see if it ends with a particular string. If so, we know for sure it’s single row update mode and we set the user id for the current row if the status attribute was updated. If the request URI doesn’t end with the expected string it must be multiple row update mode and we iterate over the current range and check each string for a modified status. Here’s the code:

public void processUpdateModel(DataActionContext daContext) {
  AppModule app = getAppModule(daContext);
  app.setUserId(((UserInfo)daContext.getHttpServletRequest().getSession().getAttribute("userinfo")).getId());
  MyViewImpl view = (MyViewImpl)smn.findViewObject("MyView");
  if (daContext.getHttpServletRequest().getRequestURI().endsWith("MyView.do"))  {
    String status = daContext.getHttpServletRequest().getParameter("Status");
    MyViewRowImpl row = (MyViewRowImpl)daContext.getBindingContainer().findIteratorBinding("MyIterator").getCurrentRow();
    if (!status.equals(row.getStatus())) {
      row.setAttribute("UserId", app.getUserId());
    }
  } else {
    for (int i = 0; i < view.getRangeSize(); i++)  {
      MyViewRowImpl row = (MyViewRowImpl)view.getRowAtRangeIndex(i);
      if (row != null) {
        String status = daContext.getHttpServletRequest().getParameter("MyView["+i+"].Status");
        if (!status.equals(row.getStatus())) {
          row.setAttribute("UserId", app.getUserId());
        }
      }
    }
  }
  super.processUpdateModel(daContext);
}

Now, the reason we set the UserId in the app module is to be sure we can access it in other methods as well. One drawback of this implementation is, that we need to set the UserId everytime we trigger an action that needs the user id. This is the case since we only use custom DataActions in a few situations and we use the default JhsDataAction for over 90% of our application. Fortunately, in our case, there are only a few actions that do this.

Share.

About Author

2 Comments