src/core/net/sf/basedb/util/overview/loader/AutoChildNodeLoader.java

Code
Comments
Other
Rev Date Author Line
4740 05 Feb 09 nicklas 1 /**
4740 05 Feb 09 nicklas 2   $Id$
4740 05 Feb 09 nicklas 3
4740 05 Feb 09 nicklas 4   Copyright (C) 2008 Nicklas Nordborg
4740 05 Feb 09 nicklas 5
4740 05 Feb 09 nicklas 6   This file is part of BASE - BioArray Software Environment.
4740 05 Feb 09 nicklas 7   Available at http://base.thep.lu.se/
4740 05 Feb 09 nicklas 8
4740 05 Feb 09 nicklas 9   BASE is free software; you can redistribute it and/or
4740 05 Feb 09 nicklas 10   modify it under the terms of the GNU General Public License
4740 05 Feb 09 nicklas 11   as published by the Free Software Foundation; either version 3
4740 05 Feb 09 nicklas 12   of the License, or (at your option) any later version.
4740 05 Feb 09 nicklas 13
4740 05 Feb 09 nicklas 14   BASE is distributed in the hope that it will be useful,
4740 05 Feb 09 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
4740 05 Feb 09 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4740 05 Feb 09 nicklas 17   GNU General Public License for more details.
4740 05 Feb 09 nicklas 18
4740 05 Feb 09 nicklas 19   You should have received a copy of the GNU General Public License
4740 05 Feb 09 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
4740 05 Feb 09 nicklas 21 */
4740 05 Feb 09 nicklas 22 package net.sf.basedb.util.overview.loader;
4740 05 Feb 09 nicklas 23
6046 17 Apr 12 nicklas 24 import java.util.LinkedList;
6046 17 Apr 12 nicklas 25 import java.util.List;
6046 17 Apr 12 nicklas 26
4740 05 Feb 09 nicklas 27 import net.sf.basedb.core.DbControl;
4740 05 Feb 09 nicklas 28 import net.sf.basedb.util.overview.OverviewContext;
4740 05 Feb 09 nicklas 29 import net.sf.basedb.util.overview.Node;
4740 05 Feb 09 nicklas 30
4740 05 Feb 09 nicklas 31 /**
4740 05 Feb 09 nicklas 32   Node loader implementation that automatically loads child nodes.
4740 05 Feb 09 nicklas 33   When any of the <code>create...</code> methods are called the actual
4740 05 Feb 09 nicklas 34   node loading is delegated to a parent node loader. If this loader returns
4740 05 Feb 09 nicklas 35   a non-null node, {@link #loadChildNodes(DbControl, OverviewContext, Node)}
4740 05 Feb 09 nicklas 36   is automatically invoked on it.
4740 05 Feb 09 nicklas 37   <p>
4740 05 Feb 09 nicklas 38   The automatic loading can of course only be done one step down, since
4740 05 Feb 09 nicklas 39   the new children probably needs a different parent node loader. It is 
4740 05 Feb 09 nicklas 40   possible to make the loading fully recursive by if the {@link
4740 05 Feb 09 nicklas 41   NodeLoaderFactory} returned from {@link OverviewContext#getNodeLoaderFactory()}
4740 05 Feb 09 nicklas 42   wrap all node loaders it create by an instance of this class.
4740 05 Feb 09 nicklas 43
4740 05 Feb 09 nicklas 44   @author Nicklas
4740 05 Feb 09 nicklas 45   @version 2.10
4740 05 Feb 09 nicklas 46   @base.modified $Date$
4740 05 Feb 09 nicklas 47 */
4740 05 Feb 09 nicklas 48 public class AutoChildNodeLoader<I>
4740 05 Feb 09 nicklas 49   implements NodeLoader<I>
4740 05 Feb 09 nicklas 50 {
4740 05 Feb 09 nicklas 51
4740 05 Feb 09 nicklas 52   private final NodeLoader<I> parent;
4740 05 Feb 09 nicklas 53   public AutoChildNodeLoader(NodeLoader<I> parent)
4740 05 Feb 09 nicklas 54   {
4740 05 Feb 09 nicklas 55     this.parent = parent;
4740 05 Feb 09 nicklas 56   }
4740 05 Feb 09 nicklas 57   /*
4740 05 Feb 09 nicklas 58     From the NodeLoader interface
4740 05 Feb 09 nicklas 59     -----------------------------
4740 05 Feb 09 nicklas 60   */
4740 05 Feb 09 nicklas 61   /**
6043 03 Apr 12 nicklas 62     Call the same method on the 'parent' node loader. If one or more
6043 03 Apr 12 nicklas 63     child nodes are added to the parent node, the 
4740 05 Feb 09 nicklas 64     {@link #loadChildNodes(DbControl, OverviewContext, Node)} is called
6043 03 Apr 12 nicklas 65     for each of the new nodes.
4740 05 Feb 09 nicklas 66     @return The node that the parent node loader creates (may be null)
4740 05 Feb 09 nicklas 67   */
4740 05 Feb 09 nicklas 68   @Override
4740 05 Feb 09 nicklas 69   public Node createForwardNode(DbControl dc, OverviewContext context, Node parentNode)
4740 05 Feb 09 nicklas 70   {
4740 05 Feb 09 nicklas 71     Node result = parent.createForwardNode(dc, context, parentNode);
6046 17 Apr 12 nicklas 72     List<Node> newChildren = parentNode.getNewChildren();
6043 03 Apr 12 nicklas 73     if (result != null) 
6043 03 Apr 12 nicklas 74     {
6043 03 Apr 12 nicklas 75       loadChildNodes(dc, context, result);
6043 03 Apr 12 nicklas 76     }
6046 17 Apr 12 nicklas 77     else if (newChildren != null)
6043 03 Apr 12 nicklas 78     {
6046 17 Apr 12 nicklas 79       for (Node n : newChildren)
6043 03 Apr 12 nicklas 80       {
6043 03 Apr 12 nicklas 81         loadChildNodes(dc, context, n);
6043 03 Apr 12 nicklas 82       }
6043 03 Apr 12 nicklas 83     }
4740 05 Feb 09 nicklas 84     return result;
4740 05 Feb 09 nicklas 85   }
4740 05 Feb 09 nicklas 86
4740 05 Feb 09 nicklas 87   /**
6043 03 Apr 12 nicklas 88     Call the same method on the 'parent' node loader. If one or more
6043 03 Apr 12 nicklas 89     child nodes are added to the parent node, the 
4740 05 Feb 09 nicklas 90     {@link #loadChildNodes(DbControl, OverviewContext, Node)} is called
6043 03 Apr 12 nicklas 91     for each of the new nodes.
4740 05 Feb 09 nicklas 92     @return The node that the parent node loader creates (may be null)
4740 05 Feb 09 nicklas 93   */
4740 05 Feb 09 nicklas 94   @Override
4740 05 Feb 09 nicklas 95   public Node createPropertyNode(DbControl dc, OverviewContext context, Node parentNode)
4740 05 Feb 09 nicklas 96   {
4740 05 Feb 09 nicklas 97     Node result = parent.createPropertyNode(dc, context, parentNode);
6046 17 Apr 12 nicklas 98     List<Node> newChildren = parentNode.getNewChildren();
6043 03 Apr 12 nicklas 99     if (result != null) 
6043 03 Apr 12 nicklas 100     {
6043 03 Apr 12 nicklas 101       loadChildNodes(dc, context, result);
6043 03 Apr 12 nicklas 102     }
6046 17 Apr 12 nicklas 103     else if (newChildren != null)
6043 03 Apr 12 nicklas 104     {
6046 17 Apr 12 nicklas 105       for (Node n : newChildren)
6043 03 Apr 12 nicklas 106       {
6043 03 Apr 12 nicklas 107         loadChildNodes(dc, context, n);
6043 03 Apr 12 nicklas 108       }
6043 03 Apr 12 nicklas 109     }
4740 05 Feb 09 nicklas 110     return result;
4740 05 Feb 09 nicklas 111   }
4740 05 Feb 09 nicklas 112
4740 05 Feb 09 nicklas 113   /**
6043 03 Apr 12 nicklas 114     Call the same method on the 'parent' node loader. If one or more
6043 03 Apr 12 nicklas 115     child nodes are added to the parent node, the 
4740 05 Feb 09 nicklas 116     {@link #loadChildNodes(DbControl, OverviewContext, Node)} is called
6043 03 Apr 12 nicklas 117     for each of the new nodes.
4740 05 Feb 09 nicklas 118     @return The node that the parent node loader creates (may be null)
4740 05 Feb 09 nicklas 119   */
4740 05 Feb 09 nicklas 120   @Override
4740 05 Feb 09 nicklas 121   public Node createReverseNode(DbControl dc, OverviewContext context, Node childNode)
4740 05 Feb 09 nicklas 122   {
4740 05 Feb 09 nicklas 123     Node result = parent.createReverseNode(dc, context, childNode);
6046 17 Apr 12 nicklas 124     List<Node> newChildren = childNode.getNewChildren();
6043 03 Apr 12 nicklas 125     if (result != null)
6043 03 Apr 12 nicklas 126     {
6043 03 Apr 12 nicklas 127       loadChildNodes(dc, context, result);
6043 03 Apr 12 nicklas 128     }
6046 17 Apr 12 nicklas 129     else if (newChildren != null)
6043 03 Apr 12 nicklas 130     {
6046 17 Apr 12 nicklas 131       for (Node n : newChildren)
6043 03 Apr 12 nicklas 132       {
6043 03 Apr 12 nicklas 133         loadChildNodes(dc, context, n);
6043 03 Apr 12 nicklas 134       }
6043 03 Apr 12 nicklas 135     }
4740 05 Feb 09 nicklas 136     return result;
4740 05 Feb 09 nicklas 137   }
4740 05 Feb 09 nicklas 138
4740 05 Feb 09 nicklas 139   /**
4740 05 Feb 09 nicklas 140     Call the same method on the 'parent' node loader. If a node is created
4740 05 Feb 09 nicklas 141     {@link #loadChildNodes(DbControl, OverviewContext, Node)} is called
4740 05 Feb 09 nicklas 142     on the new node.
4740 05 Feb 09 nicklas 143     @return The node that the parent node loader creates (may be null)
4740 05 Feb 09 nicklas 144   */
4740 05 Feb 09 nicklas 145   @Override
4740 05 Feb 09 nicklas 146   public Node createRootNode(DbControl dc, OverviewContext context, I item)
4740 05 Feb 09 nicklas 147   {
4740 05 Feb 09 nicklas 148     Node result = parent.createRootNode(dc, context, item);
4740 05 Feb 09 nicklas 149     if (result != null) loadChildNodes(dc, context, result);
4740 05 Feb 09 nicklas 150     return result;
4740 05 Feb 09 nicklas 151   }
4740 05 Feb 09 nicklas 152
4740 05 Feb 09 nicklas 153   /**
4740 05 Feb 09 nicklas 154     Call the same method on the 'parent' node loader.
4740 05 Feb 09 nicklas 155     @return The result of the parent call
4740 05 Feb 09 nicklas 156   */
6875 20 Apr 15 nicklas 157   @SuppressWarnings({ "unchecked", "rawtypes" })
4740 05 Feb 09 nicklas 158   @Override
4740 05 Feb 09 nicklas 159   public boolean loadChildNodes(DbControl dc, OverviewContext context, Node node)
4740 05 Feb 09 nicklas 160   {
6046 17 Apr 12 nicklas 161     if (node.isChildrenLoaded()) return false;
6046 17 Apr 12 nicklas 162     boolean nodesLoaded = parent.loadChildNodes(dc, context, node);
6046 17 Apr 12 nicklas 163     
6046 17 Apr 12 nicklas 164     if (nodesLoaded)
6046 17 Apr 12 nicklas 165     {
6046 17 Apr 12 nicklas 166       // Check if all child nodes have had a chance to load it's children
6046 17 Apr 12 nicklas 167       NodeLoaderFactory factory = context.getNodeLoaderFactory();
6046 17 Apr 12 nicklas 168       
6046 17 Apr 12 nicklas 169       List<Node> nodesToCheck = new LinkedList<Node>(node.getChildren());
6046 17 Apr 12 nicklas 170       while (nodesToCheck.size() > 0)
6046 17 Apr 12 nicklas 171       {
6046 17 Apr 12 nicklas 172         Node child = nodesToCheck.remove(0);
6046 17 Apr 12 nicklas 173         
6046 17 Apr 12 nicklas 174         if (child.getNodeType() == Node.Type.FOLDER)
6046 17 Apr 12 nicklas 175         {
6078 03 Aug 12 nicklas 176           List<Node> grandChildren = child.getChildren();
6078 03 Aug 12 nicklas 177           if (grandChildren != null && grandChildren.size() > 0) nodesToCheck.addAll(grandChildren);
6046 17 Apr 12 nicklas 178         }
6046 17 Apr 12 nicklas 179         else if (!child.isChildrenLoaded())
6046 17 Apr 12 nicklas 180         {
6046 17 Apr 12 nicklas 181           NodeLoader loader = factory.createNodeLoader(child.getItemType());
6046 17 Apr 12 nicklas 182           loader.loadChildNodes(dc, context, child);
6046 17 Apr 12 nicklas 183         }
6046 17 Apr 12 nicklas 184       }
6046 17 Apr 12 nicklas 185     }
6046 17 Apr 12 nicklas 186     node.setChildrenLoaded();
6046 17 Apr 12 nicklas 187     return nodesLoaded;
4740 05 Feb 09 nicklas 188   }
4740 05 Feb 09 nicklas 189   // --------------------------------
4740 05 Feb 09 nicklas 190
4740 05 Feb 09 nicklas 191   @Override
4740 05 Feb 09 nicklas 192   public String toString()
4740 05 Feb 09 nicklas 193   {
4740 05 Feb 09 nicklas 194     return super.toString() + "-->" + parent.toString();
4740 05 Feb 09 nicklas 195   }
4740 05 Feb 09 nicklas 196   
4740 05 Feb 09 nicklas 197 }