src/core/net/sf/basedb/util/overview/GenericOverview.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;
4740 05 Feb 09 nicklas 23
4740 05 Feb 09 nicklas 24 import java.util.HashMap;
4740 05 Feb 09 nicklas 25 import java.util.LinkedList;
4740 05 Feb 09 nicklas 26 import java.util.List;
4740 05 Feb 09 nicklas 27 import java.util.Map;
4740 05 Feb 09 nicklas 28
4740 05 Feb 09 nicklas 29 import net.sf.basedb.core.BasicItem;
4740 05 Feb 09 nicklas 30 import net.sf.basedb.core.DbControl;
4740 05 Feb 09 nicklas 31 import net.sf.basedb.core.Include;
4740 05 Feb 09 nicklas 32 import net.sf.basedb.core.ItemQuery;
4740 05 Feb 09 nicklas 33 import net.sf.basedb.core.Project;
4740 05 Feb 09 nicklas 34 import net.sf.basedb.core.query.Hql;
4740 05 Feb 09 nicklas 35 import net.sf.basedb.core.query.Order;
4740 05 Feb 09 nicklas 36 import net.sf.basedb.core.query.Orders;
5132 14 Oct 09 nicklas 37 import net.sf.basedb.core.snapshot.SnapshotManager;
4740 05 Feb 09 nicklas 38 import net.sf.basedb.util.overview.cache.NodeCache;
4740 05 Feb 09 nicklas 39 import net.sf.basedb.util.overview.loader.NodeLoader;
4740 05 Feb 09 nicklas 40 import net.sf.basedb.util.overview.loader.BasicItemNodeLoaderFactory;
4740 05 Feb 09 nicklas 41 import net.sf.basedb.util.overview.loader.NodeLoaderFactory;
4740 05 Feb 09 nicklas 42 import net.sf.basedb.util.overview.validator.BasicItemNodeValidatorFactory;
4740 05 Feb 09 nicklas 43 import net.sf.basedb.util.overview.validator.NodeValidatorFactory;
4740 05 Feb 09 nicklas 44
4740 05 Feb 09 nicklas 45 /**
4768 18 Feb 09 nicklas 46   Implementation for holding a generic overview of items. The
4768 18 Feb 09 nicklas 47   overview can be rooted on all main items that have a {@link NodeLoader}
4768 18 Feb 09 nicklas 48   implementation that supports it.
4768 18 Feb 09 nicklas 49   <p>
4768 18 Feb 09 nicklas 50   This class is currently hardcoded to use a {@link BasicItemNodeLoaderFactory}
4768 18 Feb 09 nicklas 51   and {@link BasicItemNodeValidatorFactory} as factories for the node
4768 18 Feb 09 nicklas 52   loaders and validators. This may change in future releases. Use {@link 
4768 18 Feb 09 nicklas 53   #getNodeLoaderFactory()} and {@link #getNodeValidatorFactory()} to get
4768 18 Feb 09 nicklas 54   access to the factories.
4768 18 Feb 09 nicklas 55   <p>
4768 18 Feb 09 nicklas 56   The root item of the overview is specified in the constructor, as is
4768 18 Feb 09 nicklas 57   a project that will be used for validating against project defaults. 
4768 18 Feb 09 nicklas 58   We recommend that the currently active project is used.
4768 18 Feb 09 nicklas 59   <p>
4768 18 Feb 09 nicklas 60   The overview has been designed to support lazy loading. To begin with 
4768 18 Feb 09 nicklas 61   the overview will only contain the root item. Use {@link #expand(DbControl, Node, boolean)}
4768 18 Feb 09 nicklas 62   to expand a node. If the <code>recursive</code> parameter is true the loading
4768 18 Feb 09 nicklas 63   will continue until the "end" is reached, otherwise only the immediate children
4768 18 Feb 09 nicklas 64   will be loaded. Note! The lazy loading functionality has not yet been tested
4768 18 Feb 09 nicklas 65   (as of BASE 2.10) and may not work in all cases due to bugs in the code.  
4768 18 Feb 09 nicklas 66   To create an overview and load the entire tree in one go, use:
4768 18 Feb 09 nicklas 67   <pre class="code">
4768 18 Feb 09 nicklas 68 DbControl dc = ...
4768 18 Feb 09 nicklas 69 BasicItem item = ...
4768 18 Feb 09 nicklas 70 Project project = ...
4768 18 Feb 09 nicklas 71 GenericOverview go = new GenericOverview(dc, item, project);
4768 18 Feb 09 nicklas 72 go.expand(go.getRootNode().getId(), dc, true);
4768 18 Feb 09 nicklas 73 go.updateFailureCountOnNodes();
4768 18 Feb 09 nicklas 74 </pre>
4740 05 Feb 09 nicklas 75
4740 05 Feb 09 nicklas 76   @author Nicklas
4740 05 Feb 09 nicklas 77   @version 2.10
4740 05 Feb 09 nicklas 78   @base.modified $Date$
4768 18 Feb 09 nicklas 79 */
4740 05 Feb 09 nicklas 80 public class GenericOverview
4740 05 Feb 09 nicklas 81   implements OverviewContext
4740 05 Feb 09 nicklas 82 {
6444 09 Apr 14 nicklas 83   private static final org.slf4j.Logger log = 
6444 09 Apr 14 nicklas 84     org.slf4j.LoggerFactory.getLogger(GenericOverview.class);
4740 05 Feb 09 nicklas 85   private static final boolean debug = log.isDebugEnabled();
4740 05 Feb 09 nicklas 86
4740 05 Feb 09 nicklas 87
4745 10 Feb 09 nicklas 88   private final ValidationOptions validationOptions;
4740 05 Feb 09 nicklas 89   private final BasicItemNodeLoaderFactory nodeLoaderFactory;
4740 05 Feb 09 nicklas 90   private final BasicItemNodeValidatorFactory nodeValidatorFactory;
4740 05 Feb 09 nicklas 91   private final Project project;
4740 05 Feb 09 nicklas 92   private final BasicItem rootItem;
5185 05 Nov 09 nicklas 93   private SnapshotManager snapshotManager;
4768 18 Feb 09 nicklas 94   private Node rootNode;
4740 05 Feb 09 nicklas 95   private Map<String, Node> allNodes;
4743 09 Feb 09 nicklas 96   private Map<Object, Object> objectCache;
4740 05 Feb 09 nicklas 97   private List<Failure> failures;
5657 16 Jun 11 nicklas 98   private NodeCache<Object> nodeCache;
4740 05 Feb 09 nicklas 99
4768 18 Feb 09 nicklas 100   /**
4768 18 Feb 09 nicklas 101     Create a new generic overview. 
4768 18 Feb 09 nicklas 102     
4768 18 Feb 09 nicklas 103     @param dc A DbControl to use for database access
4768 18 Feb 09 nicklas 104     @param rootItem The root item of the overview
4768 18 Feb 09 nicklas 105     @param project A project to use for validation of project default 
4768 18 Feb 09 nicklas 106       (we recommend that the currently active project is used)
4768 18 Feb 09 nicklas 107   */
4745 10 Feb 09 nicklas 108   public GenericOverview(DbControl dc, BasicItem rootItem, Project project)
4740 05 Feb 09 nicklas 109   {
4740 05 Feb 09 nicklas 110     this.nodeLoaderFactory = new BasicItemNodeLoaderFactory();
4740 05 Feb 09 nicklas 111     this.nodeValidatorFactory = new BasicItemNodeValidatorFactory();
4745 10 Feb 09 nicklas 112     this.validationOptions = new ValidationOptions(
4745 10 Feb 09 nicklas 113       OverviewUtil.getValidationPresets(dc.getSessionControl()).getDefault());
4740 05 Feb 09 nicklas 114     this.rootItem = rootItem;
4740 05 Feb 09 nicklas 115     this.project = project;
4768 18 Feb 09 nicklas 116     reset(dc);
4740 05 Feb 09 nicklas 117   }
4740 05 Feb 09 nicklas 118
4768 18 Feb 09 nicklas 119   /**
4768 18 Feb 09 nicklas 120     Get the current node loader factory. NOTE! This is currently (BASE 2.10)
4768 18 Feb 09 nicklas 121     hardcoded to be a {@link BasicItemNodeLoaderFactory} but may change in 
4768 18 Feb 09 nicklas 122     (=be configurable) in future releases.
4768 18 Feb 09 nicklas 123   */
4740 05 Feb 09 nicklas 124   @Override
4740 05 Feb 09 nicklas 125   public NodeLoaderFactory<BasicItem, Object> getNodeLoaderFactory()
4740 05 Feb 09 nicklas 126   {
4740 05 Feb 09 nicklas 127     return nodeLoaderFactory;
4740 05 Feb 09 nicklas 128   }
4740 05 Feb 09 nicklas 129   
4745 10 Feb 09 nicklas 130   /**
4768 18 Feb 09 nicklas 131     Get the current node validator factory. NOTE! This is currently (BASE 2.10)
4768 18 Feb 09 nicklas 132     hardcoded to be a {@link BasicItemNodeValidatorFactory} but may change in 
4768 18 Feb 09 nicklas 133     (=be configurable) in future releases.
4745 10 Feb 09 nicklas 134   */
4768 18 Feb 09 nicklas 135   @Override
6875 20 Apr 15 nicklas 136   public NodeValidatorFactory<BasicItem, Object> getNodeValidatorFactory()
4745 10 Feb 09 nicklas 137   {
4768 18 Feb 09 nicklas 138     return nodeValidatorFactory;
4745 10 Feb 09 nicklas 139   }
4745 10 Feb 09 nicklas 140
4745 10 Feb 09 nicklas 141   /**
5132 14 Oct 09 nicklas 142     Get the current snapshot manager.
5132 14 Oct 09 nicklas 143     @since 2.14
5132 14 Oct 09 nicklas 144   */
5132 14 Oct 09 nicklas 145   @Override
5132 14 Oct 09 nicklas 146   public SnapshotManager getSnapshotManager()
5132 14 Oct 09 nicklas 147   {
5132 14 Oct 09 nicklas 148     return snapshotManager;
5132 14 Oct 09 nicklas 149   }
5132 14 Oct 09 nicklas 150
5132 14 Oct 09 nicklas 151   /**
4768 18 Feb 09 nicklas 152     Get the project of this overview is using for validating against
4768 18 Feb 09 nicklas 153     project defaults (may be null).
4745 10 Feb 09 nicklas 154   */
4768 18 Feb 09 nicklas 155   @Override
4768 18 Feb 09 nicklas 156   public Project getProject()
4745 10 Feb 09 nicklas 157   {
4768 18 Feb 09 nicklas 158     return project;
4768 18 Feb 09 nicklas 159   }
4768 18 Feb 09 nicklas 160
4768 18 Feb 09 nicklas 161   /**
4768 18 Feb 09 nicklas 162     Retreive an object stored in the overview cache.
4768 18 Feb 09 nicklas 163     @param cacheKey The key to use for cache lookup
4768 18 Feb 09 nicklas 164     @return The object, or null if no object has been cached with the
4768 18 Feb 09 nicklas 165       given key
4768 18 Feb 09 nicklas 166   */
4768 18 Feb 09 nicklas 167   @Override
4768 18 Feb 09 nicklas 168   public Object getCachedObject(Object cacheKey) 
4768 18 Feb 09 nicklas 169   {
4768 18 Feb 09 nicklas 170     return objectCache.get(cacheKey);
4768 18 Feb 09 nicklas 171   }
4768 18 Feb 09 nicklas 172
4768 18 Feb 09 nicklas 173   /**
4768 18 Feb 09 nicklas 174     Store an auxilliary object in the overview cache. This is a service
4768 18 Feb 09 nicklas 175     provided by the overview implementation that can be used by node
4768 18 Feb 09 nicklas 176     loaders and/or validators to store information that may be needed
4768 18 Feb 09 nicklas 177     again in the future and is  expensive to retreive (eg. from the database). 
4768 18 Feb 09 nicklas 178     This is for example used to store annotation types that have been marked 
4768 18 Feb 09 nicklas 179     as "Required by MIAME", parents to annotatable items and more.
4768 18 Feb 09 nicklas 180     @param cacheKey The key to store the value under
4768 18 Feb 09 nicklas 181     @param value The value to store in the cache, or null to
4768 18 Feb 09 nicklas 182       remove the entry
4768 18 Feb 09 nicklas 183   */
4768 18 Feb 09 nicklas 184   @Override
4768 18 Feb 09 nicklas 185   public void setCachedObject(Object cacheKey, Object value) 
4768 18 Feb 09 nicklas 186   {
4768 18 Feb 09 nicklas 187     if (value == null)
4745 10 Feb 09 nicklas 188     {
4768 18 Feb 09 nicklas 189       objectCache.remove(cacheKey);
4745 10 Feb 09 nicklas 190     }
4768 18 Feb 09 nicklas 191     else
4768 18 Feb 09 nicklas 192     {
4768 18 Feb 09 nicklas 193       objectCache.put(cacheKey, value);
4768 18 Feb 09 nicklas 194     }
4745 10 Feb 09 nicklas 195   }
4745 10 Feb 09 nicklas 196
5384 13 Aug 10 nicklas 197   /**
5384 13 Aug 10 nicklas 198     This overview implementation doesn't currently support node caching.
5384 13 Aug 10 nicklas 199   */
4768 18 Feb 09 nicklas 200   @Override
4768 18 Feb 09 nicklas 201   public NodeCache<Object> getNodeCache()
4768 18 Feb 09 nicklas 202   {
5657 16 Jun 11 nicklas 203     return nodeCache;
4768 18 Feb 09 nicklas 204   }
4768 18 Feb 09 nicklas 205   
4768 18 Feb 09 nicklas 206   /**
4768 18 Feb 09 nicklas 207     Register a failure of a validation rule.
4768 18 Feb 09 nicklas 208     @param validator The validation rule that fails
4768 18 Feb 09 nicklas 209     @param node The node that was validated
4768 18 Feb 09 nicklas 210     @param message An optional message, if null the message from
4768 18 Feb 09 nicklas 211       {@link Validator#getFailureSummary()} is used
4768 18 Feb 09 nicklas 212     @param fixes Optional fixes that may be used to correct the problem
4768 18 Feb 09 nicklas 213   */
4768 18 Feb 09 nicklas 214   @Override
4740 05 Feb 09 nicklas 215   public Failure createFailure(Validator validator, Node node, String message, Fix... fixes)
4740 05 Feb 09 nicklas 216   {
4740 05 Feb 09 nicklas 217     Failure f = new Failure(validator, node, message, fixes);
4740 05 Feb 09 nicklas 218     failures.add(f);
4740 05 Feb 09 nicklas 219     if (debug) log.debug(f.getMessage() + " on node " + node.getName());
4740 05 Feb 09 nicklas 220     return f;
4740 05 Feb 09 nicklas 221   }
4740 05 Feb 09 nicklas 222
4768 18 Feb 09 nicklas 223   /**
4768 18 Feb 09 nicklas 224     Initialise a query with "global options" and optionally a sort
4768 18 Feb 09 nicklas 225     order. Note! The "global options" currently includes setting
4768 18 Feb 09 nicklas 226     {@link ItemQuery#include(java.util.Collection)} to {@link Include#ALL},
4768 18 Feb 09 nicklas 227     but this may change/be configurable in the future.
4768 18 Feb 09 nicklas 228     
4768 18 Feb 09 nicklas 229     @param query The query that should be initialised
4768 18 Feb 09 nicklas 230     @param sortby An array with Order objects (may be null)
4768 18 Feb 09 nicklas 231     @return The same query object
4768 18 Feb 09 nicklas 232   */
4768 18 Feb 09 nicklas 233   @Override
4768 18 Feb 09 nicklas 234   public <I extends BasicItem> ItemQuery<I> initQuery(ItemQuery<I> query, Order... sortby)
4740 05 Feb 09 nicklas 235   {
4768 18 Feb 09 nicklas 236     query.include(Include.ALL);
4768 18 Feb 09 nicklas 237     if (sortby != null)
4768 18 Feb 09 nicklas 238     {
4768 18 Feb 09 nicklas 239       for (Order o : sortby)
4768 18 Feb 09 nicklas 240       {
4768 18 Feb 09 nicklas 241         if (o != null) query.order(o);
4768 18 Feb 09 nicklas 242       }
4768 18 Feb 09 nicklas 243     }
4768 18 Feb 09 nicklas 244     return query;
4740 05 Feb 09 nicklas 245   }
4768 18 Feb 09 nicklas 246
4740 05 Feb 09 nicklas 247   /**
4768 18 Feb 09 nicklas 248     Same as {@link #initQuery(ItemQuery, Order...)} but easier to use when
4768 18 Feb 09 nicklas 249     sorting the items in ascending order by a single column.
4768 18 Feb 09 nicklas 250     @param query The query that should be initialised
4768 18 Feb 09 nicklas 251     @param sortby The property name to sort by (may be null)
4768 18 Feb 09 nicklas 252     @return The same query object
4740 05 Feb 09 nicklas 253   */
4768 18 Feb 09 nicklas 254   @Override
4768 18 Feb 09 nicklas 255   public <I extends BasicItem> ItemQuery<I> initQuery(ItemQuery<I> query, String sortby)
4740 05 Feb 09 nicklas 256   {
4768 18 Feb 09 nicklas 257     Order o = sortby == null ? null : Orders.asc(Hql.property(sortby));
4768 18 Feb 09 nicklas 258     return initQuery(query, o);
4740 05 Feb 09 nicklas 259   }
4768 18 Feb 09 nicklas 260   
4740 05 Feb 09 nicklas 261   /**
4740 05 Feb 09 nicklas 262     Get the root item of this overview.
4740 05 Feb 09 nicklas 263   */
4740 05 Feb 09 nicklas 264   public BasicItem getRootItem()
4740 05 Feb 09 nicklas 265   {
4740 05 Feb 09 nicklas 266     return rootItem;
4740 05 Feb 09 nicklas 267   }
4740 05 Feb 09 nicklas 268   
4740 05 Feb 09 nicklas 269   /**
4740 05 Feb 09 nicklas 270     Get the root node.
4740 05 Feb 09 nicklas 271   */
4740 05 Feb 09 nicklas 272   public Node getRootNode()
4740 05 Feb 09 nicklas 273   {
4740 05 Feb 09 nicklas 274     return rootNode;
4740 05 Feb 09 nicklas 275   }
4768 18 Feb 09 nicklas 276   
4740 05 Feb 09 nicklas 277   /**
4768 18 Feb 09 nicklas 278     Load children of a node. If the children has already been loaded
4768 18 Feb 09 nicklas 279     ({@link Node#isChildrenLoaded()} == true) this method does nothing.
4768 18 Feb 09 nicklas 280     
4768 18 Feb 09 nicklas 281     @param dc The DbControl to use for database access
4768 18 Feb 09 nicklas 282     @param node The node to expand
4768 18 Feb 09 nicklas 283     @param recursive TRUE if children should be loaded recursively, FALSE to
4768 18 Feb 09 nicklas 284       only load the immediate children
4740 05 Feb 09 nicklas 285   */
4768 18 Feb 09 nicklas 286   public void expand(DbControl dc, Node node, boolean recursive)
4740 05 Feb 09 nicklas 287   {
4768 18 Feb 09 nicklas 288     if (node == null) return;
4740 05 Feb 09 nicklas 289     if (!node.isChildrenLoaded())
4740 05 Feb 09 nicklas 290     {
4740 05 Feb 09 nicklas 291       if (debug) log.debug("Expanding: " + node + (recursive ? " (recursive)" : ""));
4740 05 Feb 09 nicklas 292       nodeLoaderFactory.setAutoLoadChildren(recursive);
5185 05 Nov 09 nicklas 293       snapshotManager = new SnapshotManager();
6875 20 Apr 15 nicklas 294       NodeLoader<? extends BasicItem> loader = nodeLoaderFactory.createNodeLoader(node.getItemType());
4740 05 Feb 09 nicklas 295       loader.loadChildNodes(dc, this, node);
4740 05 Feb 09 nicklas 296       cacheChildNodes(node);
4740 05 Feb 09 nicklas 297     }
4740 05 Feb 09 nicklas 298     else
4740 05 Feb 09 nicklas 299     {
4740 05 Feb 09 nicklas 300       if (debug) log.debug("Already expanded: " + node);
4740 05 Feb 09 nicklas 301     }
4740 05 Feb 09 nicklas 302     nodeLoaderFactory.setAutoLoadChildren(false);
4740 05 Feb 09 nicklas 303   }
4740 05 Feb 09 nicklas 304
4768 18 Feb 09 nicklas 305   
4768 18 Feb 09 nicklas 306   /**
4768 18 Feb 09 nicklas 307     Get the validation options currently in use.
4768 18 Feb 09 nicklas 308   */
5076 25 Aug 09 nicklas 309   @Override
4768 18 Feb 09 nicklas 310   public ValidationOptions getValidationOptions()
4740 05 Feb 09 nicklas 311   {
4768 18 Feb 09 nicklas 312     return validationOptions;
4768 18 Feb 09 nicklas 313   }
4768 18 Feb 09 nicklas 314
4768 18 Feb 09 nicklas 315   /**
4768 18 Feb 09 nicklas 316     Updates the failure count (warnings and errors) on all nodes.
4768 18 Feb 09 nicklas 317     This method should be called if the validation options has 
4768 18 Feb 09 nicklas 318     changed. If the struture or information of the experiment has
4768 18 Feb 09 nicklas 319     changed use the {@link #reset(DbControl)} method instead.
4768 18 Feb 09 nicklas 320   */
4768 18 Feb 09 nicklas 321   public void updateFailureCountOnNodes()
4768 18 Feb 09 nicklas 322   {
4768 18 Feb 09 nicklas 323     rootNode.clearFailures();
4768 18 Feb 09 nicklas 324     if (failures == null) return;
4768 18 Feb 09 nicklas 325     for (Failure f : failures)
4740 05 Feb 09 nicklas 326     {
4768 18 Feb 09 nicklas 327       Severity s = validationOptions.getSeverity(f.getValidator());
4768 18 Feb 09 nicklas 328       Node n = f.getNode();
4768 18 Feb 09 nicklas 329       if (s == Severity.ERROR)
4740 05 Feb 09 nicklas 330       {
4768 18 Feb 09 nicklas 331         n.addErrors(1);
4740 05 Feb 09 nicklas 332       }
4768 18 Feb 09 nicklas 333       else if (s == Severity.WARNING)
4768 18 Feb 09 nicklas 334       {
4768 18 Feb 09 nicklas 335         n.addWarnings(1);
4768 18 Feb 09 nicklas 336       }
4740 05 Feb 09 nicklas 337     }
4740 05 Feb 09 nicklas 338   }
4768 18 Feb 09 nicklas 339   
4768 18 Feb 09 nicklas 340   /**
4768 18 Feb 09 nicklas 341     Reset the overview and re-create the root node. 
4768 18 Feb 09 nicklas 342     @param dc A DbControl to use for database access.
4768 18 Feb 09 nicklas 343   */
4768 18 Feb 09 nicklas 344   public void reset(DbControl dc)
4768 18 Feb 09 nicklas 345   {
4768 18 Feb 09 nicklas 346     this.allNodes = new HashMap<String, Node>();
7304 02 Mar 17 nicklas 347     //this.nodeCache = new NodeCache<Object>();
4768 18 Feb 09 nicklas 348     this.objectCache = new HashMap<Object, Object>();
4768 18 Feb 09 nicklas 349     this.failures = new LinkedList<Failure>();
5185 05 Nov 09 nicklas 350     this.snapshotManager = new SnapshotManager();
4768 18 Feb 09 nicklas 351     this.rootNode = createRootNode(dc, rootItem);
4768 18 Feb 09 nicklas 352     allNodes.put(rootNode.getId(), rootNode);
4768 18 Feb 09 nicklas 353   }
4740 05 Feb 09 nicklas 354
4768 18 Feb 09 nicklas 355   /**
4768 18 Feb 09 nicklas 356     Get a list containing all validation failures.
4768 18 Feb 09 nicklas 357     @return A list (may be null)
4768 18 Feb 09 nicklas 358   */
4768 18 Feb 09 nicklas 359   public List<Failure> getFailures()
4740 05 Feb 09 nicklas 360   {
4768 18 Feb 09 nicklas 361     return failures;
4740 05 Feb 09 nicklas 362   }
4740 05 Feb 09 nicklas 363   
4768 18 Feb 09 nicklas 364   /**
4768 18 Feb 09 nicklas 365     Get the node with the given ID.
4768 18 Feb 09 nicklas 366     @param nodeId The ID of the node
4768 18 Feb 09 nicklas 367     @return A node or null if no node with the ID exists
4768 18 Feb 09 nicklas 368   */
4768 18 Feb 09 nicklas 369   public Node getNode(String nodeId)
4768 18 Feb 09 nicklas 370   {
4768 18 Feb 09 nicklas 371     return allNodes.get(nodeId);
4768 18 Feb 09 nicklas 372   }
4768 18 Feb 09 nicklas 373   
6875 20 Apr 15 nicklas 374   @SuppressWarnings({ "unchecked", "rawtypes" })
4768 18 Feb 09 nicklas 375   private Node createRootNode(DbControl dc, BasicItem root)
4768 18 Feb 09 nicklas 376   {
4768 18 Feb 09 nicklas 377     if (debug) log.debug("Creating root node for item: " + root);
4768 18 Feb 09 nicklas 378     NodeLoader loader = nodeLoaderFactory.createNodeLoader(root.getType());
4768 18 Feb 09 nicklas 379     Node node = loader.createRootNode(dc, this, root);
4768 18 Feb 09 nicklas 380     return node;
4768 18 Feb 09 nicklas 381   }
4768 18 Feb 09 nicklas 382   
4740 05 Feb 09 nicklas 383   private void cacheChildNodes(Node node)
4740 05 Feb 09 nicklas 384   {
4740 05 Feb 09 nicklas 385     if (node.getChildren() != null)
4740 05 Feb 09 nicklas 386     {
4740 05 Feb 09 nicklas 387       for (Node child : node.getChildren())
4740 05 Feb 09 nicklas 388       {
4740 05 Feb 09 nicklas 389         allNodes.put(child.getId(), child);
4740 05 Feb 09 nicklas 390         cacheChildNodes(child);
4740 05 Feb 09 nicklas 391       }
4740 05 Feb 09 nicklas 392     }
4740 05 Feb 09 nicklas 393   }
4740 05 Feb 09 nicklas 394
4740 05 Feb 09 nicklas 395 }