3 Replies Latest reply on Jul 26, 2010 5:08 AM by nbelaevski

    Can't get UIComponent id when overriding ViewHandlerWrapper

    leofigs

      I want to check security rules for visual components allowing me to hide them.  I am using RichFaces 3.3.3, Mojarra 2.0.3 and Spring 3.0.3.

       

       

      I got the following code somewhere in the web:

       

       

      public class SecuredViewHandler extends ViewHandlerWrapper {
           
           private static Logger logger = Logger.getLogger(SecuredViewHandler.class);
           
           private ViewHandler defaultViewHandler;
           
           public SecuredViewHandler(){ };
           public SecuredViewHandler(ViewHandler defaultViewHandler){ 
                super();
                this.defaultViewHandler = defaultViewHandler;
           };
           
           @Override
           public void renderView(FacesContext context, UIViewRoot viewToRender)
                     throws IOException, FacesException {
                     viewToRender.visitTree(VisitContext.createVisitContext(context), 
                          new VisitCallback(){
                          public VisitResult visit(VisitContext context, UIComponent target){
                               //Authorization Logic
                               logger.debug("Im visiting an component with id : " + target.getId());
                               //End Auth Logic
                               return VisitResult.ACCEPT;
                          }
                });
                defaultViewHandler.renderView(context, viewToRender);
           }
           @Override
           public ViewHandler getWrapped() {
                return defaultViewHandler;
           }
      }
      
      

       

       

      But the output is:

       

       

      14:04:09,688 DEBUG SecuredViewHandler:38 - Im visiting an component with id : _viewRoot
      14:04:10,300 DEBUG SecuredViewHandler:38 - Im visiting an component with id : _viewRoot
      (+ 40 times)
      

       

      I suppose it is RichFaces related because the UIViewRoot that outputs the id is of type : org.ajax4jsf.component.AjaxViewRoot

       

      I need the real component id, the one defined on the page. Am i doing something wrong here? Is this a JSF problem?

       

      Thanks.

        • 1. Re: Can't get UIComponent id when overriding ViewHandlerWrapper
          nbelaevski

          Hi Leonardo,

           

          RichFaces 3.x provides its own version of view root that has ID hard-coded instead of auto-generated one. Other components will return correct IDs assigned by application developer.

          • 2. Re: Can't get UIComponent id when overriding ViewHandlerWrapper
            leofigs

            Ok. But the visitor is supposed to visit the whole tree, and it is returning 40+ (_viewRoot) components.

             

            It does appear that the component visited is changing as expected acording with the following debug output:

             

             

            11:28:21,458 DEBUG SecuredViewHandler:40 - Im visiting an component with id : _viewRoot and toString: org.ajax4jsf.component.AjaxViewRoot@56e88e24
            11:28:21,932 DEBUG SecuredViewHandler:40 - Im visiting an component with id : _viewRoot and toString: org.ajax4jsf.component.AjaxViewRoot@2a24ed78
            11:28:21,958 DEBUG SecuredViewHandler:40 - Im visiting an component with id : _viewRoot and toString: org.ajax4jsf.component.AjaxViewRoot@a0ccc96
            11:28:21,981 DEBUG SecuredViewHandler:40 - Im visiting an component with id : _viewRoot and toString: org.ajax4jsf.component.AjaxViewRoot@4f0ab3f2
            11:28:22,009 DEBUG SecuredViewHandler:40 - Im visiting an component with id : _viewRoot and toString: org.ajax4jsf.component.AjaxViewRoot@72c21d01
            11:28:22,028 DEBUG SecuredViewHandler:40 - Im visiting an component with id : _viewRoot and toString: org.ajax4jsf.component.AjaxViewRoot@6c618821
            (.....)
            
            

             

             

            This is a code snippet of the jsp. There is no rich:* component in this page, and it is a very small login page:

             

             

            <table style="margin:15em auto 0; width:300px">
                       <tr>
                            <td><h:outputLabel value="Login: " for="loginField"/></td>
                           <td><h:inputText value="#{loginBean.login}" required="true" 
                           requiredMessage="Informe o login." id="loginField">
                           </h:inputText></td>
                           <td><h:message for="loginField"></h:message></td>
                      </tr>
                       <tr>
                            <td><h:outputLabel value="Senha: " for="passwordField"/></td>
                           <td><h:inputSecret value="#{loginBean.password}" required="true" requiredMessage="Informe a senha." id="passwordField">
                           </h:inputSecret></td>
                           <td><h:message for="passwordField"></h:message></td>
                      </tr>
            

             

             

            The page is rendering as expected.

             

            I thought i might be doing the wrong thing getting the target id but the components does not have any child as getChildCount() return 0 for all of them. The viewroot should have child components, right? And i suppose there shouldn't be as many _viewRoot as my visitor returns in the component tree...

            • 3. Re: Can't get UIComponent id when overriding ViewHandlerWrapper
              nbelaevski

              Leonardo,

               

              JSP views are empty at this stage. They are built and rendered in the same invocation of renderView() method - this is the difference with Facelets. I suggest you to use listener for PreRenderViewEvent instead. Also I couldn't reproduce 40+ view roots printed - is there a repeated invocation of renderView() method happening?