5 Replies Latest reply on Sep 24, 2007 5:32 AM by Maksim Kaszynski

    rich:tree and rich:recursiveTreeNodesAdaptor can't delete al

    Haohua xie Newbie

      I am using rich:tree and rich:recursiveTreeNodesAdaptor to manage a data struct.
      Every thing work fine except that after i delete the last subnode of a node and refresh my tree data , the tree can't be displayed and a exception happens. If the deleted node is not the last subnode, it works fine .
      I use JBoss 4.2.1 GA, JSF 1.2 RIchfaces 3.1

      here is my tree code

       <rich:tree switchType="ajax"
       adviseNodeOpened="#{sectorTreeMB.adviseNodeOpened}"
       adviseNodeSelected="#{sectorTreeMB.adviseNodeSelected}">
       <rich:recursiveTreeNodesAdaptor roots="#{sectorTreeMB.rootNodes}"
       var="parent" nodes="#{parent.childNodes}">
       <rich:treeNode>
       <a4j:commandLink value="#{parent.sector.name}"
       requestDelay="500" actionListener="#{sectorTreeMB.onShowNode}"
       styleClass="link_no_underline">
       <f:attribute name="node" value="#{parent}" />
       </a4j:commandLink>
       </rich:treeNode>
       </rich:recursiveTreeNodesAdaptor>
       </rich:tree>
      


      My Delete Action
       synchronized public void onDeleteCurrentNode(ActionEvent event) {
       FacesContext fc = FacesContext.getCurrentInstance();
       FacesMessage message;
       try {
       String sectorName = currentNode.getSector().getName();
       sectorWriteLogic.remove(currentNode.getSector().getId());
       currentNode = null;
       reloadRootNodes();
       message = new FacesMessage(FacesMessage.SEVERITY_INFO, "??["
       + sectorName + "]?????", null);
       fc.addMessage(event.getComponent().getClientId(fc), message);
      
       } catch (RatingLogicException e) {
       logger.error(e.getMessage(), e);
       message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "????????",
       e.getMessage());
       fc.addMessage(event.getComponent().getClientId(fc), message);
       }
       }
      


      here is the stack track
      java.lang.IllegalStateException: No tree element available or row key not set!
       at org.richfaces.model.StackingTreeModel.getCurrentModel(StackingTreeModel.java:79)
       at org.richfaces.model.VisualStackingTreeModel.getComponent(VisualStackingTreeModel.java:37)
       at org.richfaces.component.UITree.getNodeFacet(UITree.java:241)
       at org.richfaces.component.UITree.dataChildren(UITree.java:415)
       at org.ajax4jsf.component.UIDataAdaptor.restoreChildState(UIDataAdaptor.java:857)
       at org.ajax4jsf.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:325)
       at org.ajax4jsf.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:299)
       at org.richfaces.renderkit.TreeRendererBase.encodeSelectionStateInput(TreeRendererBase.java:481)
       at org.richfaces.renderkit.html.TreeRenderer.doEncodeEnd(TreeRenderer.java:214)
       at org.richfaces.renderkit.html.TreeRenderer.doEncodeEnd(TreeRenderer.java:237)
       at org.ajax4jsf.renderkit.RendererBase.encodeEnd(RendererBase.java:135)
       at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:836)
       at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:286)
       at org.ajax4jsf.renderkit.RendererBase.renderChildren(RendererBase.java:262)
       at org.richfaces.renderkit.html.PanelRenderer.doEncodeChildren(PanelRenderer.java:199)
       at org.richfaces.renderkit.html.PanelRenderer.doEncodeChildren(PanelRenderer.java:194)
       at org.ajax4jsf.renderkit.RendererBase.encodeChildren(RendererBase.java:121)
       at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:812)
       at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
       at org.ajax4jsf.renderkit.RendererBase.renderChildren(RendererBase.java:262)
       at org.ajax4jsf.renderkit.html.AjaxOutputPanelRenderer.encodeChildren(AjaxOutputPanelRenderer.java:79)
       at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:812)
       at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
       at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:143)
       at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
       at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
       at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
       at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
       at org.ajax4jsf.renderkit.AjaxContainerRenderer.encodeAjax(AjaxContainerRenderer.java:122)
       at org.ajax4jsf.component.AjaxViewRoot.encodeAjax(AjaxViewRoot.java:555)
       at org.ajax4jsf.component.AjaxViewRoot$4.invokeRoot(AjaxViewRoot.java:386)
       at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnRegionOrRoot(JsfOneOneInvoker.java:56)
       at org.ajax4jsf.context.AjaxContextImpl.invokeOnRegionOrRoot(AjaxContextImpl.java:173)
       at org.ajax4jsf.component.AjaxViewRoot.encodeChildren(AjaxViewRoot.java:403)
       at javax.faces.component.UIComponent.encodeAll(UIComponent.java:886)
       at com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:245)
       at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:176)
       at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
       at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216)
       at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
       at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
       at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
       at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
       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.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:525)
       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:157)
       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)
      


      Any one can help me ?
      Is this a bug?


        • 1. Re: rich:tree  delete all current selected node
          Haohua xie Newbie

          I debug into the code and find that i can't delete the last subnode only because i have to select the last subnode before delete. and after delete the node data, the tree can't set the current node .

          I think the problem comes from org.richfaces.component.UITree.getNodeFacet() and org.richfaces.model.StackingTreeModel.getCurrentModel()

          protected StackingTreeModel getCurrentModel() {
           if (this.rowKey == null) {
           return this;
           }
          
           if (isRowAvailable()) {
           return ((StackEntry) stackEntries.getLast()).model;
           }
          
           throw new IllegalStateException(
           "No tree element available or row key not set!");
           }

          when no row data available , so StackingTreeModel try to throw a exception
          but in org.richfaces.component.UITree.getNodeFacet() thinks if no row data available StackingTreeModel show return null.
          I think this is the problem

           public UITreeNode getNodeFacet() {
           String facetName = this.getNodeFace();
           if (facetName != null) {
           if (getChildCount() > 0) {
           Iterator iterator = getChildren().iterator();
           while (iterator.hasNext()) {
           Object object = iterator.next();
           if (object instanceof UITreeNode) {
           UITreeNode treeNode = (UITreeNode) object;
          
           if (!treeNode.isRendered()) {
           continue;
           }
          
           if (facetName.equals(treeNode.getType())) {
           return treeNode;
           }
           }
           }
           }
           } else {
           UIComponent component = null;
          
           ExtendedDataModel dataModel = getExtendedDataModel();
           if (dataModel instanceof TreeModelVisualComponentProvider) {
           TreeModelVisualComponentProvider componentProvider = (TreeModelVisualComponentProvider) dataModel;
           component = componentProvider.getComponent();
           }
          
           if (component == null) {
           component = this;
           }
          
           if (component.isRendered() && component.getChildCount() > 0) {
           Iterator iterator = component.getChildren().iterator();
           while (iterator.hasNext()) {
           UIComponent child = (UIComponent) iterator.next();
          
           if (child instanceof UITreeNode) {
           UITreeNode treeNode = (UITreeNode) child;
          
           if (!treeNode.isRendered()) {
           continue;
           }
          
           if (treeNode.getType() != null) {
           continue;
           }
          
           return treeNode;
           }
           }
           }
           }
          
          


          i think to catch the IllegalStateException in getNodeFacet() or to return null instead of throw an exception will resolve the problem

          Is this a bug , or i should submit it to bug list



          • 4. Re: rich:tree and rich:recursiveTreeNodesAdaptor can't delet
            Haohua xie Newbie

            Thanks for the quick response. I find my work-around. I just redirect to the current page after the deletion and the tree work fine now

            • 5. Re: rich:tree and rich:recursiveTreeNodesAdaptor can't delet
              Maksim Kaszynski Apprentice

              Fixed. Check the latest snaphots.