4740 |
05 Feb 09 |
nicklas |
1 |
/** |
4740 |
05 Feb 09 |
nicklas |
$Id$ |
4740 |
05 Feb 09 |
nicklas |
3 |
|
4740 |
05 Feb 09 |
nicklas |
Copyright (C) 2008 Nicklas Nordborg |
4740 |
05 Feb 09 |
nicklas |
5 |
|
4740 |
05 Feb 09 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
4740 |
05 Feb 09 |
nicklas |
Available at http://base.thep.lu.se/ |
4740 |
05 Feb 09 |
nicklas |
8 |
|
4740 |
05 Feb 09 |
nicklas |
BASE is free software; you can redistribute it and/or |
4740 |
05 Feb 09 |
nicklas |
modify it under the terms of the GNU General Public License |
4740 |
05 Feb 09 |
nicklas |
as published by the Free Software Foundation; either version 3 |
4740 |
05 Feb 09 |
nicklas |
of the License, or (at your option) any later version. |
4740 |
05 Feb 09 |
nicklas |
13 |
|
4740 |
05 Feb 09 |
nicklas |
BASE is distributed in the hope that it will be useful, |
4740 |
05 Feb 09 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
4740 |
05 Feb 09 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4740 |
05 Feb 09 |
nicklas |
GNU General Public License for more details. |
4740 |
05 Feb 09 |
nicklas |
18 |
|
4740 |
05 Feb 09 |
nicklas |
You should have received a copy of the GNU General Public License |
4740 |
05 Feb 09 |
nicklas |
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 |
Node loader factory implementation for {@link BasicItem} node loaders. |
4740 |
05 Feb 09 |
nicklas |
The key used in {@link #createNodeLoader(Object)} should normally be |
4740 |
05 Feb 09 |
nicklas |
an {@link Item} object. |
4740 |
05 Feb 09 |
nicklas |
41 |
|
4740 |
05 Feb 09 |
nicklas |
@author Nicklas |
4740 |
05 Feb 09 |
nicklas |
@version 2.10 |
4740 |
05 Feb 09 |
nicklas |
@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 |
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 |
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 |
Create a new node loader for loading nodes for the specified item |
4740 |
05 Feb 09 |
nicklas |
type. If no loader has been registered for the given item type, |
4740 |
05 Feb 09 |
nicklas |
a {@link NullNodeLoader} is returned or an exception is thrown |
4740 |
05 Feb 09 |
nicklas |
depending on the {@link #useNullLoaderIfNotFound()} option. |
4740 |
05 Feb 09 |
nicklas |
77 |
|
4740 |
05 Feb 09 |
nicklas |
@param key An {@link Item} object |
4740 |
05 Feb 09 |
nicklas |
@throws ItemNotFoundException If no node loader is found and the |
4740 |
05 Feb 09 |
nicklas |
{@link #useNullLoaderIfNotFound()} setting is false |
4740 |
05 Feb 09 |
nicklas |
@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 |
// Wrap in extension loader |
6875 |
20 Apr 15 |
nicklas |
114 |
loader = new ExtensionChildNodeLoader<>(loader); |
6046 |
17 Apr 12 |
nicklas |
// ...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 |
Register a node loader implementation. The implementation must have a |
4740 |
05 Feb 09 |
nicklas |
public no-argument constructor. The given class is checked with |
7461 |
14 Mar 18 |
nicklas |
{@link ClassUtil#checkAndLoadClass(ClassLoader, String, boolean, Class, Class...)} |
4740 |
05 Feb 09 |
nicklas |
127 |
|
4740 |
05 Feb 09 |
nicklas |
@param key The item type the node loader handles |
4740 |
05 Feb 09 |
nicklas |
@param loaderClass The class name of a class that implements {@link NodeLoader}, |
4740 |
05 Feb 09 |
nicklas |
or null to unregister a node loader |
4740 |
05 Feb 09 |
nicklas |
@throws NoSuchMethodException If the given class has no public no-argument |
4740 |
05 Feb 09 |
nicklas |
constructor |
4740 |
05 Feb 09 |
nicklas |
@throws ClassCastException If the given class doesn't implement the |
4740 |
05 Feb 09 |
nicklas |
{@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 |
Register a node loader implementation that you are sure fulfills the |
4740 |
05 Feb 09 |
nicklas |
requirements. Eg. it must have a public no-argument constructor and |
4740 |
05 Feb 09 |
nicklas |
implement the {@link NodeLoader} interface. |
4740 |
05 Feb 09 |
nicklas |
@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 |
Set a flag that determines if the factory should create |
4740 |
05 Feb 09 |
nicklas |
node loaders that automatically loads child nodes or not. |
4740 |
05 Feb 09 |
nicklas |
If this flag has been set this factory will wrap the |
4740 |
05 Feb 09 |
nicklas |
node loaders with a {@link AutoChildNodeLoader}. |
4740 |
05 Feb 09 |
nicklas |
<p> |
4740 |
05 Feb 09 |
nicklas |
167 |
|
4740 |
05 Feb 09 |
nicklas |
This will generate a recursive pattern if the used node loader: |
4740 |
05 Feb 09 |
nicklas |
<ul> |
4740 |
05 Feb 09 |
nicklas |
<li>Uses this factory to create child node loaders. Eg. it should use |
4740 |
05 Feb 09 |
nicklas |
the node loader factory provided by {@link OverviewContext#getNodeLoaderFactory()}. |
4740 |
05 Feb 09 |
nicklas |
The node loader should NOT instantiate child new loaders by itself. |
4740 |
05 Feb 09 |
nicklas |
<li>Uses an implementation that recurses into folder-type nodes, for example |
4740 |
05 Feb 09 |
nicklas |
by extending {@link AbstractNodeLoader}. |
4740 |
05 Feb 09 |
nicklas |
</ul> |
4740 |
05 Feb 09 |
nicklas |
176 |
|
4740 |
05 Feb 09 |
nicklas |
@param autoLoadChildren TRUE to create node loaders that automatically |
4740 |
05 Feb 09 |
nicklas |
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 |
Get the auto load children setting. |
4740 |
05 Feb 09 |
nicklas |
@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 |
Get the null loader setting. |
4740 |
05 Feb 09 |
nicklas |
@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 |
Set a flag that determines if a {@link NullNodeLoader} should be used |
4740 |
05 Feb 09 |
nicklas |
or if an {@link ItemNotFoundException} should be thrown |
4740 |
05 Feb 09 |
nicklas |
if no registered node loader is found for a specific key. |
4740 |
05 Feb 09 |
nicklas |
@param useNullLoader TRUE to use a NullNodeLoader, FALSE to throw |
4740 |
05 Feb 09 |
nicklas |
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 |
Registers default item node loaders from {@link BioSource} |
4740 |
05 Feb 09 |
nicklas |
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 |
// 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 |
} |