|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
NodeSPI.java | - | - | - | - |
|
1 | /* | |
2 | * JBoss, Home of Professional Open Source | |
3 | * | |
4 | * Distributable under LGPL license. | |
5 | * See terms of license at gnu.org. | |
6 | */ | |
7 | package org.jboss.cache; | |
8 | ||
9 | import net.jcip.annotations.NotThreadSafe; | |
10 | import org.jboss.cache.lock.NodeLock; | |
11 | import org.jboss.cache.optimistic.DataVersion; | |
12 | import org.jboss.cache.transaction.GlobalTransaction; | |
13 | ||
14 | import java.util.Map; | |
15 | import java.util.Set; | |
16 | ||
17 | /** | |
18 | * A more detailed interface to {@link Node}, which is used when writing plugins for or extending JBoss Cache. References are usually | |
19 | * obtained by calling methods on {@link org.jboss.cache.CacheSPI}. | |
20 | * <p/> | |
21 | * <B><I>You should NEVER attempt to directly cast a {@link Node} instance to this interface. In future, the implementation may not allow it.</I></B> | |
22 | * <p/> | |
23 | * This interface contains overridden method signatures of some methods from {@link Node}, overridden to ensure return | |
24 | * types of {@link Node} are replaced with {@link NodeSPI}. | |
25 | * <p/> | |
26 | * <b><i>An important note</i></b> on the xxxDirect() methods below. These methods are counterparts to similarly named | |
27 | * methods in {@link Node} - e.g., {@link NodeSPI#getDirect(Object)} is a direct access counterpart to {@link Node#get(Object)}, | |
28 | * the difference being that: | |
29 | * <p/> | |
30 | * <ul> | |
31 | * <li>{@link Node#get(Object)} - Passes the call up the interceptor stack, applies all aspects including node locking, cache loading, passivation, etc etc.</li> | |
32 | * <li>{@link NodeSPI#getDirect(Object)} - directly works on the underlying data in the node.</li> | |
33 | * </ul> | |
34 | * <p/> | |
35 | * The big difference with the direct access methods are that it is the onus of the caller to ensure proper locks are obtained | |
36 | * prior to the call. A proper call should have gone through a locking-capable interceptor first and based on the cache | |
37 | * configuration's locking policy, an appropriate lock should be obtained prior to the call. These direct access methods will | |
38 | * throw {@link org.jboss.cache.lock.LockingException}s if appropriate locks haven't been obtained by the caller. | |
39 | * <p/> | |
40 | * It is important to node that the direct <b>read</b> methods, such as getDataDirect(), return unmodifiable collections. | |
41 | * In addition to being unmodifiable, they are also defensively copied from the underlying data map to ensure view consistency. | |
42 | * <p/> | |
43 | * | |
44 | * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a> | |
45 | * @see Node | |
46 | * @see org.jboss.cache.CacheSPI | |
47 | * @since 2.0.0 | |
48 | */ | |
49 | @NotThreadSafe | |
50 | public interface NodeSPI<K, V> extends Node<K, V> | |
51 | { | |
52 | /** | |
53 | * Returns true if the children of this node were loaded from a cache loader. | |
54 | * | |
55 | * @return true if the children of this node were loaded from a cache loader. | |
56 | */ | |
57 | boolean getChildrenLoaded(); | |
58 | ||
59 | /** | |
60 | * Sets if the children of this node were loaded from a cache loader. | |
61 | * | |
62 | * @param loaded true if loaded, false otherwise | |
63 | */ | |
64 | void setChildrenLoaded(boolean loaded); | |
65 | ||
66 | /** | |
67 | * Returns true if the data was loaded from the cache loader. | |
68 | * | |
69 | * @return true if the data was loaded from the cache loader. | |
70 | */ | |
71 | public boolean getDataLoaded(); | |
72 | ||
73 | /** | |
74 | * Sets if the data was loaded from the cache loader. | |
75 | * | |
76 | * @param dataLoaded true if loaded, false otherwise | |
77 | */ | |
78 | public void setDataLoaded(boolean dataLoaded); | |
79 | ||
80 | /** | |
81 | * Returns a map to access the raw children. | |
82 | * This method may return a null if the node does not have any children. It is important to note that this method | |
83 | * returns a direct reference to the underlying child map and is intended for internal use only. Incorrect use | |
84 | * may result in very inconsistent state of the cache. | |
85 | * | |
86 | * @return Map, keyed by child name, values Nodes. | |
87 | */ | |
88 | Map<Object, Node<K, V>> getChildrenMapDirect(); | |
89 | ||
90 | /** | |
91 | * Sets the node's children explictly. | |
92 | * This method will remove all children currently associated with this node and add all the children passed in. | |
93 | * | |
94 | * @param children cannot be null | |
95 | */ | |
96 | void setChildrenMapDirect(Map<Object, Node<K, V>> children); | |
97 | ||
98 | /** | |
99 | * Returns an existing child or creates a new one using a global transaction. | |
100 | * | |
101 | * @param name name of child to create | |
102 | * @param tx transaction under which to create child | |
103 | * @return newly created node | |
104 | */ | |
105 | NodeSPI<K, V> getOrCreateChild(Object name, GlobalTransaction tx); | |
106 | ||
107 | /** | |
108 | * Returns a lock for this node. | |
109 | * | |
110 | * @return node lock | |
111 | */ | |
112 | NodeLock getLock(); | |
113 | ||
114 | /** | |
115 | * Sets the FQN of this node and resets the names of all children as well. | |
116 | * | |
117 | * @param f fqn to set | |
118 | */ | |
119 | void setFqn(Fqn<?> f); | |
120 | ||
121 | /** | |
122 | * Returns true if the instance has been deleted in the current transaction. | |
123 | * | |
124 | * @return true if the instance has been deleted in the current transaction. | |
125 | */ | |
126 | boolean isDeleted(); | |
127 | ||
128 | /** | |
129 | * Marks the node as being deleted (or not) in the current transaction. This is not recursive, child nodes are not affected. | |
130 | * | |
131 | * @param marker true if the node has been deleted, false if not. | |
132 | */ | |
133 | void markAsDeleted(boolean marker); | |
134 | ||
135 | /** | |
136 | * Same as {@link #markAsDeleted(boolean)} except that the option to recurse into children is provided. | |
137 | * | |
138 | * @param marker true if the node has been deleted, false if not. | |
139 | * @param recursive if true, child nodes (and their children) are marked as well. | |
140 | */ | |
141 | void markAsDeleted(boolean marker, boolean recursive); | |
142 | ||
143 | /** | |
144 | * Adds or replaces a child by name. | |
145 | * | |
146 | * @param nodeName child node name (not an FQN) | |
147 | * @param nodeToAdd child node | |
148 | */ | |
149 | void addChild(Object nodeName, Node<K, V> nodeToAdd); | |
150 | ||
151 | /** | |
152 | * Prints details of this node to the StringBuffer passed in. | |
153 | * | |
154 | * @param sb StringBuffer to print to | |
155 | * @param indent depth of this node in the tree. Used to indent details by prepending spaces. | |
156 | */ | |
157 | void printDetails(StringBuffer sb, int indent); | |
158 | ||
159 | /** | |
160 | * Prints basic information of this node to the StringBuffer passed in. | |
161 | * | |
162 | * @param sb StringBuffer to print to | |
163 | * @param indent depth of this node in the tree. Used to indent details by prepending spaces. | |
164 | */ | |
165 | ||
166 | void print(StringBuffer sb, int indent); | |
167 | ||
168 | // versioning | |
169 | /** | |
170 | * Sets the data version of this node if versioning is supported. | |
171 | * | |
172 | * @param version data version to apply | |
173 | * @throws UnsupportedOperationException if versioning is not supported | |
174 | */ | |
175 | void setVersion(DataVersion version); | |
176 | ||
177 | /** | |
178 | * Returns the data version of this node if versioning is supported. | |
179 | * | |
180 | * @return data version | |
181 | * @throws UnsupportedOperationException if versioning is not supported | |
182 | */ | |
183 | DataVersion getVersion(); | |
184 | ||
185 | ||
186 | // ------- these XXXDirect() methods work directly on the node and bypass the interceptor chain. | |
187 | /** | |
188 | * Functionally the same as {@link #getChildren()} except that it operates directly on the node and bypasses the | |
189 | * interceptor chain. | |
190 | * <p/> | |
191 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
192 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
193 | * <p/> | |
194 | * | |
195 | * @return set of child nodes. | |
196 | * @see #getChildren() | |
197 | */ | |
198 | Set<NodeSPI<K, V>> getChildrenDirect(); | |
199 | ||
200 | /** | |
201 | * Directly removes all children for this node. | |
202 | * The only direct method that does not have a non-direct counterpart. | |
203 | */ | |
204 | void removeChildrenDirect(); | |
205 | ||
206 | /** | |
207 | * Retrieves children (directly), optionally including any marked as deleted nodes. | |
208 | * <p/> | |
209 | * The caller needs to ensure a proper lock has been obtained prior to calling this method. | |
210 | * | |
211 | * @param includeMarkedAsDeleted if true, the returned set will include nodes marked as deleted | |
212 | * @return a set of nodes | |
213 | * @throws org.jboss.cache.lock.LockingException | |
214 | * if locking was not obtained | |
215 | */ | |
216 | Set<NodeSPI<K, V>> getChildrenDirect(boolean includeMarkedAsDeleted); | |
217 | ||
218 | /** | |
219 | * Retrives a child directly by name. | |
220 | * Functionally the same as {@link #getChild(Object)} except that it bypasses the | |
221 | * interceptor chain. | |
222 | * <p/> | |
223 | * The caller needs to ensure a proper lock has been obtained prior to calling this method. | |
224 | * | |
225 | * @param childName name of child | |
226 | * @return child node | |
227 | * @throws org.jboss.cache.lock.LockingException | |
228 | * if locking was not obtained | |
229 | * @see #getChild(Object) | |
230 | */ | |
231 | NodeSPI<K, V> getChildDirect(Object childName); | |
232 | ||
233 | /** | |
234 | * Adds a child directly to a Node. | |
235 | * Functionally the same as {@link #addChild(Fqn)} except that it bypasses the | |
236 | * interceptor chain. | |
237 | * <p/> | |
238 | * The caller needs to ensure a proper lock has been obtained prior to calling this method. | |
239 | * | |
240 | * @param childName name of child | |
241 | * @return child node | |
242 | * @throws org.jboss.cache.lock.LockingException | |
243 | * if locking was not obtained | |
244 | * @see #addChild(Fqn) | |
245 | */ | |
246 | NodeSPI<K, V> addChildDirect(Fqn childName); | |
247 | ||
248 | /** | |
249 | * Directly adds the node passed in to the children map of the current node. Will throw a CacheException if | |
250 | * <tt>child.getFqn().getParent().equals(getFqn())</tt> returns false. | |
251 | * | |
252 | * @param child child to add | |
253 | */ | |
254 | void addChildDirect(NodeSPI<K, V> child); | |
255 | ||
256 | /** | |
257 | * Retrives a child directly by fully qualified name. | |
258 | * Functionally the same as {@link #getChild(Fqn)} except that it bypasses the | |
259 | * interceptor chain. | |
260 | * <p/> | |
261 | * The caller needs to ensure a proper lock has been obtained prior to calling this method. | |
262 | * | |
263 | * @param childName name of child | |
264 | * @return child node | |
265 | * @throws org.jboss.cache.lock.LockingException | |
266 | * if locking was not obtained | |
267 | * @see #getChild(Fqn) | |
268 | */ | |
269 | NodeSPI<K, V> getChildDirect(Fqn childName); | |
270 | ||
271 | /** | |
272 | * Removes a child directly from a node. | |
273 | * Functionally the same as {@link #removeChild(Fqn)} except that it bypasses the | |
274 | * interceptor chain. | |
275 | * <p/> | |
276 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
277 | * | |
278 | * @param fqn of child. | |
279 | * @return true if the node was found, false otherwise | |
280 | * @throws org.jboss.cache.lock.LockingException | |
281 | * if locking was not obtained | |
282 | * @see #removeChild(Fqn) | |
283 | */ | |
284 | boolean removeChildDirect(Fqn fqn); | |
285 | ||
286 | /** | |
287 | * Removes a child directly from a node. | |
288 | * Functionally the same as {@link #removeChild(Object)} except that bypasses the | |
289 | * interceptor chain. | |
290 | * <p/> | |
291 | * The caller needs to ensure a proper lock has been obtained prior to calling this method. | |
292 | * | |
293 | * @param childName of child. | |
294 | * @return true if the node was found, false otherwise | |
295 | * @throws org.jboss.cache.lock.LockingException | |
296 | * if locking was not obtained | |
297 | * @see #removeChild(Object) | |
298 | */ | |
299 | boolean removeChildDirect(Object childName); | |
300 | ||
301 | ||
302 | /** | |
303 | * Removes a data key directly from a node. | |
304 | * Functionally the same as {@link #remove(Object)} except that it bypasses the | |
305 | * interceptor chain. | |
306 | * <p/> | |
307 | * The caller needs to ensure a proper lock has been obtained prior to calling this method. | |
308 | * | |
309 | * @param key to remove | |
310 | * @return the old data contained under the key | |
311 | * @throws org.jboss.cache.lock.LockingException | |
312 | * if locking was not obtained | |
313 | * @see #remove(Object) | |
314 | */ | |
315 | V removeDirect(K key); | |
316 | ||
317 | /** | |
318 | * Functionally the same as {@link #put(Object,Object)} except that it operates directly on the node and bypasses the | |
319 | * interceptor chain. | |
320 | * <p/> | |
321 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
322 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
323 | * <p/> | |
324 | * | |
325 | * @param key of data | |
326 | * @param value of data | |
327 | * @return the previous value under the key passed in, or <tt>null</tt> | |
328 | * @see #put(Object,Object) | |
329 | */ | |
330 | V putDirect(K key, V value); | |
331 | ||
332 | /** | |
333 | * Functionally the same as {@link #putAll(Map)} except that it operates directly on the node and bypasses the | |
334 | * interceptor chain. | |
335 | * <p/> | |
336 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
337 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
338 | * <p/> | |
339 | * | |
340 | * @param data to put | |
341 | * @see #putAll(Map) | |
342 | */ | |
343 | void putAllDirect(Map<K, V> data); | |
344 | ||
345 | /** | |
346 | * Functionally the same as {@link #getData()} except that it operates directly on the node and bypasses the | |
347 | * interceptor chain. | |
348 | * <p/> | |
349 | * Note that this returns a reference to access the node's data. | |
350 | * This data should only be modified by the cache itself. | |
351 | * This method should never return null. | |
352 | * <p/> | |
353 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
354 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
355 | * <p/> | |
356 | * | |
357 | * @return map containing data | |
358 | * @see #getData() | |
359 | */ | |
360 | Map<K, V> getDataDirect(); | |
361 | ||
362 | /** | |
363 | * Functionally the same as {@link #get(Object)} except that it operates directly on the node and bypasses the | |
364 | * interceptor chain. | |
365 | * <p/> | |
366 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
367 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
368 | * <p/> | |
369 | * | |
370 | * @param key data to get | |
371 | * @return value under key | |
372 | * @see #get(Object) | |
373 | */ | |
374 | V getDirect(K key); | |
375 | ||
376 | ||
377 | /** | |
378 | * Functionally the same as {@link #clearData()} except that it operates directly on the node and bypasses the | |
379 | * interceptor chain. | |
380 | * <p/> | |
381 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
382 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
383 | * <p/> | |
384 | * | |
385 | * @see #clearData() | |
386 | */ | |
387 | void clearDataDirect(); | |
388 | ||
389 | ||
390 | /** | |
391 | * Functionally the same as {@link #getKeys()} except that it operates directly on the node and bypasses the | |
392 | * interceptor chain. | |
393 | * <p/> | |
394 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
395 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
396 | * <p/> | |
397 | * | |
398 | * @return set of keys | |
399 | * @see #getKeys() | |
400 | */ | |
401 | Set<K> getKeysDirect(); | |
402 | ||
403 | /** | |
404 | * Functionally the same as {@link #getChildrenNames()} except that it operates directly on the node and bypasses the | |
405 | * interceptor chain. | |
406 | * <p/> | |
407 | * The caller needs to ensure a proper lock has been obtained prior to calling this method, otherwise a | |
408 | * {@link org.jboss.cache.lock.LockingException} will be thrown. | |
409 | * <p/> | |
410 | * | |
411 | * @return set of children names | |
412 | * @see #getChildrenNames() | |
413 | */ | |
414 | Set<Object> getChildrenNamesDirect(); | |
415 | ||
416 | /** | |
417 | * Retrieves a reference to the cache in which this Node resides. | |
418 | * | |
419 | * @return a cache | |
420 | */ | |
421 | CacheSPI<K, V> getCache(); | |
422 | ||
423 | // ----------- these methods override their corresponding methods in Node, so that the return types are NodeSPI rather than Node. | |
424 | ||
425 | /** | |
426 | * Returns the parent node as a {@link NodeSPI}, instead | |
427 | * of {@link Node} from {@link Node#getParent()}, and is otherwise identical. | |
428 | * | |
429 | * @return parent node | |
430 | * @see Node#getParent() | |
431 | */ | |
432 | NodeSPI<K, V> getParent(); | |
433 | ||
434 | /** | |
435 | * @return true if the node has one or more child nodes; false otherwise. | |
436 | */ | |
437 | boolean hasChildrenDirect(); | |
438 | } |
|