src/core/net/sf/basedb/util/overview/loader/BasicItemNodeLoaderFactory.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
7513 02 Nov 18 nicklas 24 import java.lang.reflect.InvocationTargetException;
4740 05 Feb 09 nicklas 25 import java.util.HashMap;
4740 05 Feb 09 nicklas 26 import java.util.Map;
4740 05 Feb 09 nicklas 27
4740 05 Feb 09 nicklas 28 import net.sf.basedb.core.BaseException;
4740 05 Feb 09 nicklas 29 import net.sf.basedb.core.BasicItem;
4740 05 Feb 09 nicklas 30 import net.sf.basedb.core.BioSource;
4740 05 Feb 09 nicklas 31 import net.sf.basedb.core.Experiment;
4740 05 Feb 09 nicklas 32 import net.sf.basedb.core.Item;
4740 05 Feb 09 nicklas 33 import net.sf.basedb.core.ItemNotFoundException;
4740 05 Feb 09 nicklas 34 import net.sf.basedb.util.ClassUtil;
4740 05 Feb 09 nicklas 35 import net.sf.basedb.util.overview.OverviewContext;
4740 05 Feb 09 nicklas 36
4740 05 Feb 09 nicklas 37 /**
4740 05 Feb 09 nicklas 38   Node loader factory implementation for {@link BasicItem} node loaders.
4740 05 Feb 09 nicklas 39   The key used in {@link #createNodeLoader(Object)} should normally be 
4740 05 Feb 09 nicklas 40   an {@link Item} object.
4740 05 Feb 09 nicklas 41   
4740 05 Feb 09 nicklas 42   @author Nicklas
4740 05 Feb 09 nicklas 43   @version 2.10
4740 05 Feb 09 nicklas 44   @base.modified $Date$
4740 05 Feb 09 nicklas 45 */
4740 05 Feb 09 nicklas 46 public class BasicItemNodeLoaderFactory
4740 05 Feb 09 nicklas 47   implements NodeLoaderFactory<BasicItem, Object>
4740 05 Feb 09 nicklas 48 {
6444 09 Apr 14 nicklas 49   private static final org.slf4j.Logger log = 
6444 09 Apr 14 nicklas 50     org.slf4j.LoggerFactory.getLogger(BasicItemNodeLoaderFactory.class);
4740 05 Feb 09 nicklas 51   private static final boolean debug = log.isDebugEnabled();
4740 05 Feb 09 nicklas 52   
4740 05 Feb 09 nicklas 53   private final Map<Object, Class<? extends NodeLoader<? extends BasicItem>>> loaders;
4740 05 Feb 09 nicklas 54   private boolean autoLoadChildren;
4740 05 Feb 09 nicklas 55   private boolean useNullLoader;
4740 05 Feb 09 nicklas 56   
4740 05 Feb 09 nicklas 57   /**
4740 05 Feb 09 nicklas 58     Creates a new factory.
4740 05 Feb 09 nicklas 59   */
4740 05 Feb 09 nicklas 60   public BasicItemNodeLoaderFactory()
4740 05 Feb 09 nicklas 61   {
4740 05 Feb 09 nicklas 62     loaders = new HashMap<Object, Class<? extends NodeLoader<? extends BasicItem>>>();
4740 05 Feb 09 nicklas 63     this.autoLoadChildren = false;
4740 05 Feb 09 nicklas 64     this.useNullLoader = true;
4740 05 Feb 09 nicklas 65     registerDefaultNodeLoaders();
4740 05 Feb 09 nicklas 66   }
4740 05 Feb 09 nicklas 67   
4740 05 Feb 09 nicklas 68   /*
4740 05 Feb 09 nicklas 69     From the NodeLoaderFactory interface
4740 05 Feb 09 nicklas 70     ------------------------------------
4740 05 Feb 09 nicklas 71   */
4740 05 Feb 09 nicklas 72   /**
4740 05 Feb 09 nicklas 73     Create a new node loader for loading nodes for the specified item
4740 05 Feb 09 nicklas 74     type. If no loader has been registered for the given item type,
4740 05 Feb 09 nicklas 75     a {@link NullNodeLoader} is returned or an exception is thrown
4740 05 Feb 09 nicklas 76     depending on the {@link #useNullLoaderIfNotFound()} option.
4740 05 Feb 09 nicklas 77     
4740 05 Feb 09 nicklas 78     @param key An {@link Item} object
4740 05 Feb 09 nicklas 79     @throws ItemNotFoundException If no node loader is found and the 
4740 05 Feb 09 nicklas 80       {@link #useNullLoaderIfNotFound()} setting is false
4740 05 Feb 09 nicklas 81     @return A node loader object
4740 05 Feb 09 nicklas 82   */
4740 05 Feb 09 nicklas 83   @Override
4740 05 Feb 09 nicklas 84   public NodeLoader<? extends BasicItem> createNodeLoader(Object key)
4740 05 Feb 09 nicklas 85   {
4740 05 Feb 09 nicklas 86     if (debug) log.debug("Create: NodeLoader[key=" + key + "]");
4740 05 Feb 09 nicklas 87     NodeLoader<? extends BasicItem> loader = null;
4740 05 Feb 09 nicklas 88     Class<? extends NodeLoader<? extends BasicItem>> loaderClass = loaders.get(key);
4740 05 Feb 09 nicklas 89     if (loaderClass == null)
4740 05 Feb 09 nicklas 90     {
4740 05 Feb 09 nicklas 91       if (debug) log.debug("Not found: NodeLoader[key=" + key + "]");
4740 05 Feb 09 nicklas 92       if (useNullLoader)
4740 05 Feb 09 nicklas 93       {
4740 05 Feb 09 nicklas 94         loader = new NullNodeLoader<BasicItem>();
4740 05 Feb 09 nicklas 95       }
4740 05 Feb 09 nicklas 96       else
4740 05 Feb 09 nicklas 97       {
4740 05 Feb 09 nicklas 98         throw new ItemNotFoundException("Node loader for key: " + key);
4740 05 Feb 09 nicklas 99       }
4740 05 Feb 09 nicklas 100     }
4740 05 Feb 09 nicklas 101     else
4740 05 Feb 09 nicklas 102     {
4740 05 Feb 09 nicklas 103       if (debug) log.debug("Instantiating: " + loaderClass);
4740 05 Feb 09 nicklas 104       try
4740 05 Feb 09 nicklas 105       {
7513 02 Nov 18 nicklas 106         loader = loaderClass.getDeclaredConstructor().newInstance();
4740 05 Feb 09 nicklas 107       }
7513 02 Nov 18 nicklas 108       catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex)
4740 05 Feb 09 nicklas 109       {
4740 05 Feb 09 nicklas 110         throw new BaseException("Can't create node loader: " + loaderClass, ex);
4740 05 Feb 09 nicklas 111       }
4740 05 Feb 09 nicklas 112     }
6046 17 Apr 12 nicklas 113     // Wrap in extension loader
6875 20 Apr 15 nicklas 114     loader = new ExtensionChildNodeLoader<>(loader);
6046 17 Apr 12 nicklas 115     // ...and recursive child loader if auto-loading is enabled
6875 20 Apr 15 nicklas 116     if (isAutoLoadingChildren()) loader = new AutoChildNodeLoader<>(loader);
6046 17 Apr 12 nicklas 117     
4740 05 Feb 09 nicklas 118     if (debug) log.debug("Node loader created: " + loader);
4740 05 Feb 09 nicklas 119     return loader;
4740 05 Feb 09 nicklas 120   }
4740 05 Feb 09 nicklas 121   // --------------------------------------
4740 05 Feb 09 nicklas 122   
4740 05 Feb 09 nicklas 123   /**
4740 05 Feb 09 nicklas 124     Register a node loader implementation. The implementation must have a
4740 05 Feb 09 nicklas 125     public no-argument constructor. The given class is checked with
7461 14 Mar 18 nicklas 126     {@link ClassUtil#checkAndLoadClass(ClassLoader, String, boolean, Class, Class...)}
4740 05 Feb 09 nicklas 127     
4740 05 Feb 09 nicklas 128     @param key The item type the node loader handles
4740 05 Feb 09 nicklas 129     @param loaderClass The class name of a class that implements {@link NodeLoader},
4740 05 Feb 09 nicklas 130       or null to unregister a node loader
4740 05 Feb 09 nicklas 131     @throws NoSuchMethodException If the given class has no public no-argument
4740 05 Feb 09 nicklas 132       constructor
4740 05 Feb 09 nicklas 133     @throws ClassCastException If the given class doesn't implement the
4740 05 Feb 09 nicklas 134       {@link NodeLoader} interface
4740 05 Feb 09 nicklas 135   */
4740 05 Feb 09 nicklas 136   public void registerNodeLoader(Object key, Class<? extends NodeLoader<? extends BasicItem>> loaderClass)
4740 05 Feb 09 nicklas 137     throws NoSuchMethodException, ClassCastException
4740 05 Feb 09 nicklas 138   {
4740 05 Feb 09 nicklas 139     if (loaderClass != null) ClassUtil.checkClass(loaderClass, true, NodeLoader.class);
4740 05 Feb 09 nicklas 140     registerCheckedNodeLoader(key, loaderClass);
4740 05 Feb 09 nicklas 141   }
4740 05 Feb 09 nicklas 142   
4740 05 Feb 09 nicklas 143   /**
4740 05 Feb 09 nicklas 144     Register a node loader implementation that you are sure fulfills the
4740 05 Feb 09 nicklas 145     requirements. Eg. it must have a public no-argument constructor and
4740 05 Feb 09 nicklas 146     implement the {@link NodeLoader} interface.
4740 05 Feb 09 nicklas 147     @see #registerNodeLoader(Object, Class)
4740 05 Feb 09 nicklas 148   */
4740 05 Feb 09 nicklas 149   protected void registerCheckedNodeLoader(Object key, Class<? extends NodeLoader<? extends BasicItem>> loaderClass)
4740 05 Feb 09 nicklas 150   {
4740 05 Feb 09 nicklas 151     if (loaderClass == null)
4740 05 Feb 09 nicklas 152     {
4740 05 Feb 09 nicklas 153       loaders.remove(key);
4740 05 Feb 09 nicklas 154     }
4740 05 Feb 09 nicklas 155     else
4740 05 Feb 09 nicklas 156     {
4740 05 Feb 09 nicklas 157       loaders.put(key, loaderClass);
4740 05 Feb 09 nicklas 158     }
4740 05 Feb 09 nicklas 159   }
4740 05 Feb 09 nicklas 160   
4740 05 Feb 09 nicklas 161   /**
4740 05 Feb 09 nicklas 162     Set a flag that determines if the factory should create 
4740 05 Feb 09 nicklas 163     node loaders that automatically loads child nodes or not.
4740 05 Feb 09 nicklas 164     If this flag has been set this factory will wrap the
4740 05 Feb 09 nicklas 165     node loaders with a {@link AutoChildNodeLoader}.
4740 05 Feb 09 nicklas 166     <p>
4740 05 Feb 09 nicklas 167     
4740 05 Feb 09 nicklas 168     This will generate a recursive pattern if the used node loader:
4740 05 Feb 09 nicklas 169     <ul>
4740 05 Feb 09 nicklas 170     <li>Uses this factory to create child node loaders. Eg. it should use
4740 05 Feb 09 nicklas 171       the node loader factory provided by {@link OverviewContext#getNodeLoaderFactory()}.
4740 05 Feb 09 nicklas 172       The node loader should NOT instantiate child new loaders by itself.
4740 05 Feb 09 nicklas 173     <li>Uses an implementation that recurses into folder-type nodes, for example
4740 05 Feb 09 nicklas 174       by extending {@link AbstractNodeLoader}.
4740 05 Feb 09 nicklas 175     </ul>
4740 05 Feb 09 nicklas 176     
4740 05 Feb 09 nicklas 177     @param autoLoadChildren TRUE to create node loaders that automatically
4740 05 Feb 09 nicklas 178       loads children, FALSE otherwise
4740 05 Feb 09 nicklas 179   */
4740 05 Feb 09 nicklas 180   public void setAutoLoadChildren(boolean autoLoadChildren)
4740 05 Feb 09 nicklas 181   {
4740 05 Feb 09 nicklas 182     this.autoLoadChildren = autoLoadChildren;
4740 05 Feb 09 nicklas 183   }
4740 05 Feb 09 nicklas 184   
4740 05 Feb 09 nicklas 185   /**
4740 05 Feb 09 nicklas 186     Get the auto load children setting.
4740 05 Feb 09 nicklas 187     @return TRUE if child nodes are automatically loaded, FALSE if not
4740 05 Feb 09 nicklas 188   */
4740 05 Feb 09 nicklas 189   public boolean isAutoLoadingChildren()
4740 05 Feb 09 nicklas 190   {
4740 05 Feb 09 nicklas 191     return autoLoadChildren;
4740 05 Feb 09 nicklas 192   }
4740 05 Feb 09 nicklas 193   
4740 05 Feb 09 nicklas 194   /**
4740 05 Feb 09 nicklas 195     Get the null loader setting.
4740 05 Feb 09 nicklas 196     @see #setUseNullLoaderIfNotFound(boolean)
4740 05 Feb 09 nicklas 197   */
4740 05 Feb 09 nicklas 198   public boolean useNullLoaderIfNotFound()
4740 05 Feb 09 nicklas 199   {
4740 05 Feb 09 nicklas 200     return useNullLoader;
4740 05 Feb 09 nicklas 201   }
4740 05 Feb 09 nicklas 202   
4740 05 Feb 09 nicklas 203   /**
4740 05 Feb 09 nicklas 204     Set a flag that determines if a {@link NullNodeLoader} should be used
4740 05 Feb 09 nicklas 205     or if an {@link ItemNotFoundException} should be thrown
4740 05 Feb 09 nicklas 206     if no registered node loader is found for a specific key.
4740 05 Feb 09 nicklas 207     @param useNullLoader TRUE to use a NullNodeLoader, FALSE to throw
4740 05 Feb 09 nicklas 208       an exception
4740 05 Feb 09 nicklas 209    */
4740 05 Feb 09 nicklas 210   public void setUseNullLoaderIfNotFound(boolean useNullLoader)
4740 05 Feb 09 nicklas 211   {
4740 05 Feb 09 nicklas 212     this.useNullLoader = useNullLoader;
4740 05 Feb 09 nicklas 213   }
4740 05 Feb 09 nicklas 214   
4740 05 Feb 09 nicklas 215   /**
4740 05 Feb 09 nicklas 216     Registers default item node loaders from {@link BioSource}
4740 05 Feb 09 nicklas 217     to {@link Experiment}, etc.
4740 05 Feb 09 nicklas 218   */
4740 05 Feb 09 nicklas 219   protected void registerDefaultNodeLoaders()
4740 05 Feb 09 nicklas 220   {
4740 05 Feb 09 nicklas 221     registerCheckedNodeLoader(Item.BIOSOURCE, BioSourceLoader.class);
4740 05 Feb 09 nicklas 222     registerCheckedNodeLoader(Item.SAMPLE, SampleLoader.class);
4740 05 Feb 09 nicklas 223     registerCheckedNodeLoader(Item.EXTRACT, ExtractLoader.class);
4740 05 Feb 09 nicklas 224     registerCheckedNodeLoader(Item.ARRAYDESIGN, ArrayDesignLoader.class);
4740 05 Feb 09 nicklas 225     registerCheckedNodeLoader(Item.ARRAYBATCH, ArrayBatchLoader.class);
4740 05 Feb 09 nicklas 226     registerCheckedNodeLoader(Item.ARRAYSLIDE, ArraySlideLoader.class);
5651 08 Jun 11 nicklas 227     registerCheckedNodeLoader(Item.PHYSICALBIOASSAY, PhysicalBioAssayLoader.class);
5652 10 Jun 11 nicklas 228     registerCheckedNodeLoader(Item.DERIVEDBIOASSAY, DerivedBioAssayLoader.class);
4740 05 Feb 09 nicklas 229     registerCheckedNodeLoader(Item.RAWBIOASSAY, RawBioAssayLoader.class);
6959 01 Oct 15 nicklas 230     registerCheckedNodeLoader(Item.ROOTRAWBIOASSAY, RootRawBioAssayLoader.class);
4740 05 Feb 09 nicklas 231     registerCheckedNodeLoader(Item.EXPERIMENT, ExperimentLoader.class);
6041 02 Apr 12 nicklas 232     registerCheckedNodeLoader(Item.BIOPLATE, BioPlateLoader.class);
6044 03 Apr 12 nicklas 233     registerCheckedNodeLoader(Item.BIOWELL, BioWellLoader.class);
6755 20 Feb 15 nicklas 234     registerCheckedNodeLoader(Item.ITEMLIST, ItemListLoader.class);
6210 06 Dec 12 nicklas 235     registerCheckedNodeLoader(Item.BIOPLATEEVENT, BioPlateEventLoader.class);
4740 05 Feb 09 nicklas 236     
4740 05 Feb 09 nicklas 237     // Property node loaders
4740 05 Feb 09 nicklas 238     registerCheckedNodeLoader(Item.PROTOCOL, ProtocolLoader.class);
5651 08 Jun 11 nicklas 239     registerCheckedNodeLoader(Item.TAG, TagLoader.class);
4740 05 Feb 09 nicklas 240     registerCheckedNodeLoader("PROTOCOL.PARAMETER", ProtocolParameterLoader.class);
4740 05 Feb 09 nicklas 241     registerCheckedNodeLoader("EXPERIMENTAL.FACTOR", ExperimentalFactorLoader.class);
4740 05 Feb 09 nicklas 242     registerCheckedNodeLoader(Item.SOFTWARE, SoftwareLoader.class);
4740 05 Feb 09 nicklas 243     registerCheckedNodeLoader(Item.HARDWARE, HardwareLoader.class);
7004 09 Nov 15 nicklas 244     registerCheckedNodeLoader(Item.KIT, KitLoader.class);
4740 05 Feb 09 nicklas 245     registerCheckedNodeLoader(Item.ANNOTATION, AnnotationLoader.class);
4740 05 Feb 09 nicklas 246     registerCheckedNodeLoader(Item.PLATFORM, PlatformLoader.class);
4740 05 Feb 09 nicklas 247     registerCheckedNodeLoader(Item.FILESETMEMBER, DataFileLoader.class);
5500 18 Nov 10 nicklas 248     registerCheckedNodeLoader(Item.ANYTOANY, AnyToAnyLoader.class);
7861 21 Oct 20 nicklas 249     registerCheckedNodeLoader(Item.FILE, FileLoader.class);
6046 17 Apr 12 nicklas 250     
4740 05 Feb 09 nicklas 251   }
4740 05 Feb 09 nicklas 252
4740 05 Feb 09 nicklas 253 }