6 Replies Latest reply on Aug 1, 2008 10:41 AM by ssilvert

    problems with ExtendedDataModel

    wgworek

      Hi!

      In my rich:dataTable I'm using my own implementation of ExtendedDataModel for proper pagination. On client side everything is OK but during tests some methods are called that are not called when testing with normal browser.

       @Override
       public int getRowIndex()
       {
       throw new UnsupportedOperationException();
       }
      
       @Override
       public void setRowIndex(int rowIndex)
       {
       throw new UnsupportedOperationException();
       }
      
       @Override
       public Object getWrappedData()
       {
       throw new UnsupportedOperationException();
       }
      
       @Override
       public void setWrappedData(Object data)
       {
       throw new UnsupportedOperationException();
       }
      
       @Override
       public Object getRowKey()
       {
       throw new UnsupportedOperationException();
       }
      


      When using ExtendedDataModel these methods are never called (rich:dataTable is aware of this class). Somehow with JSFUnit getRowKey() and setRowKey() are invoked. When I comment out the
      throw new ...
      all tests passes. It's quite strange behaviour.

      Does anybody had this problem before?

      Stack trace below:
      java.lang.UnsupportedOperationException
      at ui.core.base.BaseExtendedDataModel.setRowIndex(BaseExtendedDataModel.java:140)
      at org.richfaces.model.ModifiableModel.setRowIndex(ModifiableModel.java:95)
      at org.ajax4jsf.component.UIDataAdaptor.setRowIndex(UIDataAdaptor.java:290)
      at org.jboss.jsfunit.jsfsession.ClientIDs.addUIData(ClientIDs.java:120)
      at org.jboss.jsfunit.jsfsession.ClientIDs.addAllIDs(ClientIDs.java:75)
      at org.jboss.jsfunit.jsfsession.ClientIDs.addAllIDs(ClientIDs.java:83)
      at org.jboss.jsfunit.jsfsession.ClientIDs.addAllIDs(ClientIDs.java:83)
      at org.jboss.jsfunit.jsfsession.ClientIDs.addAllIDs(ClientIDs.java:83)
      at org.jboss.jsfunit.jsfsession.ClientIDs.<init>(ClientIDs.java:62)
      at org.jboss.jsfunit.jsfsession.JSFServerSession.pageCreated(JSFServerSession.java:181)
      at org.jboss.jsfunit.jsfsession.JSFServerSession.<init>(JSFServerSession.java:54)
      at org.jboss.jsfunit.jsfsession.JSFSession.<init>(JSFSession.java:83)
      at dvs3.ui.test.util.DVSWebUITestCase.goTo(DVSWebUITestCase.java:60)
      at dvs3.ui.test.util.DVSWebUITestCase.goTo(DVSWebUITestCase.java:45)
      at dvs3.ui.test.user.UserListTest.testProperPageRendered(UserListTest.java:53)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at org.apache.cactus.internal.AbstractCactusTestCase.runBareServer(AbstractCactusTestCase.java:153)
      at org.apache.cactus.internal.server.AbstractWebTestCaller.doTest(AbstractWebTestCaller.java:119)
      at org.apache.cactus.internal.server.AbstractWebTestController.handleRequest_aroundBody0(AbstractWebTestController.java:93)
      at org.apache.cactus.internal.server.AbstractWebTestController.handleRequest_aroundBody1$advice(AbstractWebTestController.java:224)
      at org.apache.cactus.internal.server.AbstractWebTestController.handleRequest(AbstractWebTestController.java)
      at org.apache.cactus.server.ServletTestRedirector.doPost_aroundBody2(ServletTestRedirector.java:101)
      at org.apache.cactus.server.ServletTestRedirector.doPost_aroundBody3$advice(ServletTestRedirector.java:224)
      at org.apache.cactus.server.ServletTestRedirector.doPost(ServletTestRedirector.java)
      at org.apache.cactus.server.ServletTestRedirector.doGet_aroundBody0(ServletTestRedirector.java:72)
      at org.apache.cactus.server.ServletTestRedirector.doGet_aroundBody1$advice(ServletTestRedirector.java:224)
      at org.apache.cactus.server.ServletTestRedirector.doGet(ServletTestRedirector.java)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.jboss.jsfunit.framework.JSFUnitFilter.doFilter(JSFUnitFilter.java:122)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
      at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
      at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Thread.java:595)
      


        • 1. Re: problems with ExtendedDataModel
          wgworek

          After quick investigation problems lays in org.jboss.jsfunit.jsfsession.ClientIDs class in method:

           private void addUIData(UIData component, FacesContext facesContext)
           {
           String parentClientID = component.getClientId(facesContext);
           // TODO: find out if headers and footers are found
           int rowsToDisplay = component.getRows();
           if (rowsToDisplay == 0) rowsToDisplay = component.getRowCount();
           for (int i=0; i < rowsToDisplay; i++)
           {
           // PROBLEM IN THE setRowIndex()
           component.setRowIndex(i);
           addAncestors(parentClientID, component.getClientId(facesContext));
           for (Iterator facetsAndChildren = component.getFacetsAndChildren(); facetsAndChildren.hasNext();)
           {
           UIComponent facetOrChild = (UIComponent)facetsAndChildren.next();
           addAncestors(component, facetOrChild, facesContext);
           addAllIDs(facetOrChild, facesContext);
           }
           }
           // PROBLEM HERE AS WELL
           component.setRowIndex(-1);
           }
          


          Using component.setRowIndex() is quite bad when using ExtendedDataModel. Of course quick fix is to comment out throwing exceptions but it's not proper solution.

          There should be a check if javax.faces.component.UIData is actually a org.ajax4jsf.component.UIDataAdaptor and using setRowKey().



          • 2. Re: problems with ExtendedDataModel
            ssilvert

            Having implemented your own ExtendedDataModel, you probably know more about this than I do. But here is how I see things at the moment:

            ClientIDs has to iterate through the data and gather the ID's. It can't assume or not assume a particular extended implementation of UIData. The JSFUnit core package should only know about the JSF API.

            No extended implementation of UIData should throw UnsupportedOperationException for setRowIndex(). The implementation must follow the contract.

            Any insight?

            Stan

            • 3. Re: problems with ExtendedDataModel
              wgworek

              So when someone is using ExtendedDataModel and using rich:dataDataTable will have this issue (if his method is throwing an exception).

              I guess I just have to comment out throwing of exceptions. For now I cannot think of any other ideas that are not breaking JSFUnit core and introducing dependency on RichFaces.

              Ok, I must follow the contract and live with that :).

              Thanks for a reply.

              • 4. Re: problems with ExtendedDataModel

                I ran into this same issue. The UnsupportedOperationExceptions are there because wgworek is probably following the example code for an EDM on the RichFaces website. The comments in the example code say those operations are "rudiments of old JSF staff".

                You simply need to massage your implementation of the EDM. The framework will call setRowIndex on your EDM followed by getRowKey in order to get the key for a given row in the table. You must make sure that your implementation of setRowIndex will also set the row key (for that index).

                Here is how I implemented it:

                 public void setRowIndex(int rowIndex) {
                
                 // this method must set the row index AND row key
                 if((getCachedList() == null) || (rowIndex < 0) ||
                 (rowIndex >= getCachedList().size())) {
                 // invalid row
                 currentRowKey = null;
                 currentRowIndex = -1;
                 } else {
                 currentRowKey = getId(getCachedList().get(rowIndex));
                 currentRowIndex = rowIndex;
                 }
                 }
                

                The poorly named getId() method will return the key for the specified index.

                That said, is all of this OBE with the new version of JSFUnit since the framework uses xpath with the IDs?

                justin.

                • 5. Re: problems with ExtendedDataModel
                  wgworek

                  jinpsu, very good shot. I have my implementation of EDM based of example from RichFaces forum. You are so correct ;).

                  Don't bother with getId(), I have the same method in my code :). Thank you very much.

                  Problem solved :)

                  • 6. Re: problems with ExtendedDataModel
                    ssilvert

                     

                    "jinpsu" wrote:

                    That said, is all of this OBE with the new version of JSFUnit since the framework uses xpath with the IDs?

                    justin.

                    The new version is using xpath on the client side, but the server side still needs to gather the ID's using the ClientIDs class. So this won't go away any time soon.

                    Stan