8 Replies Latest reply on Oct 15, 2007 1:29 PM by marius.oancea

    left tree - explorer like application

    marius.oancea

      I have to create a application that manages about 1 milion entries. The entries are organised hierarchical in a tree. Tree is made in such a way that not very many entries are displayed at a time.

      The tree is displayed in the left side of all application pages (with some exception).

      I have a dilemma here: should I store the tree state in conversation context ? or in session context? I know the advice is to not store much info in session context but on the other side, my tree has to be displayed nearly all the time.

      Is there a seam example with a tree in the left side somewhere?

      If the entities are stored in the session how do I solve "LazyInitializationException" ?

        • 1. Re: left tree - explorer like application

          I tried making a windows-explorer tree using a richfaces:tree... At first I tried storing my tree state in conversation context, but then I had bugs because the richfaces tree would not always pass the correct conversation context when clicking on nodes. So then I stored my tree state in the session... but then I got LazyInitializationExceptions. So then I tried using the unseamly approach of using a session-scoped entityManager. But then I had various of other bugs with the tree, and it was really slow... so then I got rid of it and decided to display my tree structure using regular html links. No bugs, and much faster. This was with richfaces 3.0.1 though... I saw that they made improvements in 3.1.0 (like recursiveTreeNodeAdapter) but my experience with with the 3.0.1 was so buggy and slow I don't want to try it again.

          • 2. Re: left tree - explorer like application
            marius.oancea

            Anyone tried ICEFaces tree?

            • 3. Re: left tree - explorer like application
              christian.bauer

              http://fisheye.jboss.com/browse/~raw,r=1.1/JBoss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/package.html

              http://fisheye.jboss.com/browse/JBoss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset

               public TreeNode getTree() {
               if (directoryTree == null) {
               directoryTree = new WikiTreeNodeAdapter(getInstance(), getNodeDAO().getComparatorDisplayPosition(), 2l);
               directoryTree.loadChildren();
               }
               }
              


               <h:form id="dirTree" rendered="false">
               <ui:include src="includes/statusIndicator.xhtml"/>
              
               #{directoryHome.instance.name}:
               <rich:tree value="#{directoryHome.tree}" var="nodeWrapper"
               switchType="ajax" status="dirTree\:status"
               nodeFace="#{wiki:getType(nodeWrapper.wrappedNode)}">
              
               <rich:treeNode type="Directory">
               <f:facet name="icon">
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/icon.dir.gif" width="18" height="20"/>
               </f:facet>
               <f:facet name="iconLeaf">
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/icon.dir.gif" width="18" height="20"/>
               </f:facet>
               <h:outputText value="#{nodeWrapper.wrappedNode.name}"/> (#{nodeWrapper.level})
               </rich:treeNode>
              
               <rich:treeNode type="Document">
               <f:facet name="icon">
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/icon.doc.gif" width="18" height="20"
               rendered="#{nodeWrapper.wrappedNode != nodeWrapper.wrappedParent.wrappedNode.defaultDocument}"/>
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/icon.doc.default.gif" width="18" height="20"
               rendered="#{nodeWrapper.wrappedNode == nodeWrapper.wrappedParent.wrappedNode.defaultDocument}"/>
               </f:facet>
               <f:facet name="iconLeaf">
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/icon.doc.gif" width="18" height="20"
               rendered="#{nodeWrapper.wrappedNode != nodeWrapper.wrappedParent.wrappedNode.defaultDocument}"/>
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/icon.doc.default.gif" width="18" height="20"
               rendered="#{nodeWrapper.wrappedNode == nodeWrapper.wrappedParent.wrappedNode.defaultDocument}"/>
               </f:facet>
               <h:outputText value="#{nodeWrapper.wrappedNode.name}"/> (#{nodeWrapper.level})
               </rich:treeNode>
              
               <rich:treeNode type="File">
               <f:facet name="icon">
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/#{fileMetaMap[nodeWrapper.wrappedNode.contentType].displayIcon}"
               width="18" height="20"
               rendered="#{!empty fileMetaMap[nodeWrapper.wrappedNode.contentType]}"/>
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/#{fileMetaMap['generic'].displayIcon}"
               width="18" height="20"
               rendered="#{empty fileMetaMap[nodeWrapper.wrappedNode.contentType]}"/>
               </f:facet>
               <f:facet name="iconLeaf">
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/#{fileMetaMap[nodeWrapper.wrappedNode.contentType].displayIcon}"
               width="18" height="20"
               rendered="#{!empty fileMetaMap[nodeWrapper.wrappedNode.contentType]}"/>
               <h:graphicImage value="/themes/#{wikiPreferences.themeName}/img/#{fileMetaMap['generic'].displayIcon}"
               width="18" height="20"
               rendered="#{empty fileMetaMap[nodeWrapper.wrappedNode.contentType]}"/>
               </f:facet>
               <h:outputText value="#{nodeWrapper.wrappedNode.name}"/> (#{nodeWrapper.level})
               </rich:treeNode>
              
               </rich:tree>
               </h:form>
              


              This is high performance read-mostly tree framework with dynamic pre-fetch size for on-demand loading of an arbitrary depth of childrens-children (in a single, very efficient, SQL query).

              The UI part is not used right now but you should be able to figure out how it fits together if you look at the source and spend maybe 3 days on it.

              Don't even start thinking about whatever magic Javascript buttons from whatever broken JSF library you click on before you sort out the basics. I am still looking for help implementing moving of tree nodes.



              • 4. Re: left tree - explorer like application
                marius.oancea

                Thanx, The example looks very similar with tree/tree2 from myfaces.

                • 5. Re: left tree - explorer like application
                  dustismo

                  I have an extremely similar situation in my app. I have a large tree structure that is displayed on every page. The tree can have arbitrary numbers of nodes so lazy loading is must.

                  I needed to be able to do drag-n-drop to move nodes and folders. I first tried icefaces but had to give up because of their drag and drop support was pitiful (it had no way to add javascript hooks for things like confirm dialogs --i.e. 'are you sure you want to move this node?'). Then I tried Richfaces, god was that a nightmare. Their tree datastructure is truly bazaar and I found the performance to be horrendous. I basically wasted 4 months on icefaces and richfaces (though it's possible that their implementations have gotten better in recent versions).

                  Then I tried ext.js and just passed my treenodes via json from a servlet. This solution has been perfect. Tree response is very fast, and I can control the drag and drop operations any way I want (plus their dnd implementation is designed to handle many many nodes).

                  my 2 cents..

                  dustin

                  • 6. Re: left tree - explorer like application
                    marius.oancea

                    dustismo, where do you save the tree state in your application?

                    If i save in session i'm wondering about scalability issues.

                    • 7. Re: left tree - explorer like application
                      dustismo

                      I save the tree state in the session as its accessed on every page. My node objects are fairly light and I remove the nodes in closed folders (so the memory is freed) so I'm not that concerned about it being a scaling issue. If a user had tens of thousands of nodes viewable at the same time the page would be unusable slow to load.

                      -Dustin

                      • 8. Re: left tree - explorer like application
                        marius.oancea

                        I used rich:tree with lazy loading and so on. Finally i decided to not store the tree of objects in the session but only the nodes (rich TreeNodes). The application behaves very well until now.

                        Thanx again Christian, good example here together with wiki example.