5 Replies Latest reply on Oct 7, 2009 10:41 AM by Viacheslav Garmash

    rich:dataTable sorting makes direct HttpServletRequest under

    Viacheslav Garmash Newbie

      Hi there!

      I discovered interesting issue but probably it is a feature. I found that even inside portlet (JBoss Portal) with configured JBoss Portlet Bridge sorting links are sending reqular HTTP requests to the application. In other words sorting links (and probably filtering ones too) are not being wrapped into portlet links. As the result table re-rendering is done though direct call to application instead of going though portal.

      For most cases it is sufficient but there are couple cases when it can cause troubles. In my case I found impossible to use EL function that filters access to certain command links by calling request.isUserInRole from the page. This is because under Jboss Portal only PortletRequest instance will work. HttpServletRequest will always return false.

      To confirm that rich:dataTable use different type of request for initial rendering and sorting you can use simple code snippet:

       <rich:dataTable value=#{myBean.list} var="r">
       <rich:column sortBy="#{r.name}">
       <f:facet name="header">Name</f:facet>
       <h:outputText value="#{r.name}" />
       </rich:column>
       <rich:column>
       <f:facet name="header">Request</f:facet>
       <h:outputText value="#{request.class}" />
       </rich:column>
      </rich:dataTable>
      


      For that you of course will need to define some managedBean with getList() getter that will return list of objects.
      In my case test table looks like this after initial rendering:
      [img]http://www.vgarmash.narod.ru/images/errors/initialTable.png[/img]
      And like this after sorting:
      [img]http://www.vgarmash.narod.ru/images/errors/afterSorting.png[/img]

      I found this issue when I tried to use EL function to call request.isUserInRole. Finction specified in Facelets config like this (this is 3rd variant, 1st one used PortletRequest type for second attribute):
       <function>
       <function-name>isUserInRole</function-name>
       <function-class>com.sensei.auth.functions.SecurityCheckFunctions</function-class>
       <function-signature>boolean isUserInRole(java.lang.String, java.lang.Object)</function-signature>
       </function>

      Java class for tat function:
      public class SecurityCheckFunctions {
      
       private static final Logger logger = Logger.getLogger(SecurityCheckFunctions.class);
      
       public static boolean isUserInRole(String roleName, Object requestObject) {
       boolean userInRole = false;
       if(requestObject instanceof PortletRequest) {
       PortletRequest request = (PortletRequest) requestObject;
       logger.debug("request is PortletRequest");
       userInRole = request.isUserInRole(roleName);
       } else if(requestObject instanceof HttpServletRequest) {
       HttpServletRequest request = (HttpServletRequest)requestObject;
       logger.debug("request is HttpServletRequest");
       userInRole = request.isUserInRole(roleName);
       }
      
       logger.debug("test isUserInRole("+roleName+") = "+userInRole);
       return userInRole;
       }
      }
      

      Usage example:
      <h:commandLink ... rendered="#{!res.published and nutri:isUserInRole('Nutrition Administrator', request)}"/>


      Currently this EL function works only during initial page rendering. If I click sorting on any column, my function always return false because type of request is not PortletRequest.

      My question is: is described rich:dataTable behavoir is valid or it should be fixed as a bug?