Lines 32-38
Link Here
|
32 |
* @author Jaroslav Tulach |
32 |
* @author Jaroslav Tulach |
33 |
*/ |
33 |
*/ |
34 |
final class DataObjectPool extends Object |
34 |
final class DataObjectPool extends Object |
35 |
implements ChangeListener, RepositoryListener, PropertyChangeListener, Runnable { |
35 |
implements ChangeListener, RepositoryListener, PropertyChangeListener { |
|
|
36 |
/** set to non null if the constructor is called from somewhere else than DataObject.find */ |
37 |
private static final ThreadLocal FIND = new ThreadLocal (); |
36 |
/** validator */ |
38 |
/** validator */ |
37 |
private static final Validator VALIDATOR = new Validator (); |
39 |
private static final Validator VALIDATOR = new Validator (); |
38 |
|
40 |
|
Lines 68-73
Link Here
|
68 |
return POOL; |
70 |
return POOL; |
69 |
} |
71 |
} |
70 |
|
72 |
|
|
|
73 |
/** Calls into one loader. Setups security condition to allow DataObject ocnstructor |
74 |
* to succeed. |
75 |
*/ |
76 |
public static DataObject findDataObject (DataLoader loader, FileObject fo, DataLoader.RecognizedFiles rec) |
77 |
throws java.io.IOException { |
78 |
DataObject ret; |
79 |
|
80 |
Object prev = FIND.get (); |
81 |
try { |
82 |
FIND.set (loader); |
83 |
|
84 |
ret = loader.findDataObject (fo, rec); |
85 |
} finally { |
86 |
FIND.set (prev); |
87 |
} |
88 |
|
89 |
// notify it |
90 |
if (ret != null) { |
91 |
DataObjectPool.getPOOL().notifyCreation (ret); |
92 |
} |
93 |
|
94 |
return ret; |
95 |
} |
96 |
|
71 |
/** Collection of all objects that has been created but their |
97 |
/** Collection of all objects that has been created but their |
72 |
* creation has not been yet notified to OperationListener.postCreate |
98 |
* creation has not been yet notified to OperationListener.postCreate |
73 |
* method. |
99 |
* method. |
Lines 96-121
Link Here
|
96 |
*/ |
122 |
*/ |
97 |
private ThreadLocal last = new ThreadLocal (); |
123 |
private ThreadLocal last = new ThreadLocal (); |
98 |
|
124 |
|
99 |
/** Time when the toNotify set has been modified. |
|
|
100 |
*/ |
101 |
private long toNotifyModified; |
102 |
/** A delay to check the notify modified content. It is expected that |
125 |
/** A delay to check the notify modified content. It is expected that |
103 |
* in 500ms each constructor can finish, so 500ms after the registration |
126 |
* in 500ms each constructor can finish, so 500ms after the registration |
104 |
* of object in a toNotify map, it should be ready and initialized. |
127 |
* of object in a toNotify map, it should be ready and initialized. |
105 |
*/ |
128 |
*/ |
106 |
private static final int SAFE_NOTIFY_DELAY = 500; |
129 |
private static final int SAFE_NOTIFY_DELAY = 0; |
107 |
|
130 |
|
108 |
private static final Integer ONE = new Integer(1); |
131 |
private static final Integer ONE = new Integer(1); |
109 |
|
132 |
|
110 |
/** A task to check toNotify content and notify that objects were created. |
|
|
111 |
*/ |
112 |
private RequestProcessor.Task task; |
113 |
|
114 |
/** Constructor. |
133 |
/** Constructor. |
115 |
*/ |
134 |
*/ |
116 |
private DataObjectPool () { |
135 |
private DataObjectPool () { |
117 |
task = RequestProcessor.createRequest (this); |
|
|
118 |
task.setPriority (Thread.MIN_PRIORITY); |
119 |
} |
136 |
} |
120 |
|
137 |
|
121 |
|
138 |
|
Lines 230-240
Link Here
|
230 |
return; |
247 |
return; |
231 |
} |
248 |
} |
232 |
|
249 |
|
233 |
if (toNotify.isEmpty ()) { |
|
|
234 |
// ok, we do not need the task |
235 |
task.cancel (); |
236 |
} |
237 |
|
238 |
// if somebody is caught in waitNotified then wake him up |
250 |
// if somebody is caught in waitNotified then wake him up |
239 |
notifyAll (); |
251 |
notifyAll (); |
240 |
} |
252 |
} |
Lines 272-320
Link Here
|
272 |
} |
284 |
} |
273 |
|
285 |
|
274 |
|
286 |
|
275 |
/** Invoked to periodicaly check whether some data objects are not notified |
|
|
276 |
* to be created. In such case it notifies about their creation. |
277 |
*/ |
278 |
public void run () { |
279 |
Item arr []; |
280 |
|
281 |
synchronized (this) { |
282 |
if (toNotify.isEmpty()) { |
283 |
return; |
284 |
} |
285 |
|
286 |
if (System.currentTimeMillis () < toNotifyModified + SAFE_NOTIFY_DELAY) { |
287 |
task.schedule (SAFE_NOTIFY_DELAY); |
288 |
return; |
289 |
} |
290 |
arr = (Item [])toNotify.toArray (new Item [toNotify.size ()]); |
291 |
} |
292 |
|
293 |
// notify each created object |
294 |
for (int i = 0; i < arr.length; i++) { |
295 |
DataObject obj = arr[i].getDataObjectOrNull (); |
296 |
|
297 |
// notifyCreation removes object from toNotify queue, |
298 |
// if object was already invalidated then remove it as well |
299 |
if (obj != null) { |
300 |
notifyCreation (obj); |
301 |
} else { |
302 |
synchronized (this) { |
303 |
toNotify.remove (arr[i]); |
304 |
} |
305 |
} |
306 |
} |
307 |
} |
308 |
|
309 |
/** Add to list of created objects. |
287 |
/** Add to list of created objects. |
310 |
*/ |
288 |
*/ |
311 |
private void notifyAdd (Item item) { |
289 |
private void notifyAdd (Item item) { |
312 |
if (toNotify.isEmpty()) { |
|
|
313 |
task.schedule (SAFE_NOTIFY_DELAY); |
314 |
} |
315 |
toNotify.add (item); |
290 |
toNotify.add (item); |
316 |
last.set (item); |
291 |
last.set (item); |
317 |
toNotifyModified = System.currentTimeMillis (); |
|
|
318 |
} |
292 |
} |
319 |
|
293 |
|
320 |
|
294 |
|
Lines 398-403
Link Here
|
398 |
* @exception DataObjectExistsException if the file object is already registered |
372 |
* @exception DataObjectExistsException if the file object is already registered |
399 |
*/ |
373 |
*/ |
400 |
public Item register (FileObject fo, DataLoader loader) throws DataObjectExistsException { |
374 |
public Item register (FileObject fo, DataLoader loader) throws DataObjectExistsException { |
|
|
375 |
if (FIND.get () == null) throw new IllegalStateException ("DataObject constructor can be called only thru DataObject.find - use that method"); // NOI18N |
376 |
|
401 |
// here we're registering a listener on fo's FileSystem so we can deliver |
377 |
// here we're registering a listener on fo's FileSystem so we can deliver |
402 |
// fo changes to DO without lots of tiny listeners on folders |
378 |
// fo changes to DO without lots of tiny listeners on folders |
403 |
// The new DS bound to a repository can simply place a single listener |
379 |
// The new DS bound to a repository can simply place a single listener |
Lines 490-498
Link Here
|
490 |
// (e.g. BB/AAA/A1) is left in the toNotify pool forever. This |
466 |
// (e.g. BB/AAA/A1) is left in the toNotify pool forever. This |
491 |
// point is reached; remove it now. -jglick |
467 |
// point is reached; remove it now. -jglick |
492 |
if (toNotify.remove(item)) { |
468 |
if (toNotify.remove(item)) { |
493 |
if (toNotify.isEmpty()) { |
|
|
494 |
task.cancel(); |
495 |
} |
496 |
notifyAll(); |
469 |
notifyAll(); |
497 |
} |
470 |
} |
498 |
return; |
471 |
return; |