This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 25186
Collapse All | Expand All

(-)org/netbeans/mdr/util/EventNotifier.java (-47 / +95 lines)
Lines 22-27 Link Here
22
 * after transactions.
22
 * after transactions.
23
 *
23
 *
24
 * @author  mmatula
24
 * @author  mmatula
25
 * @author <a href="mailto:hkrug@rationalizer.com">Holger Krug</a>
25
 * @version 
26
 * @version 
26
 */
27
 */
27
public final class EventNotifier {
28
public final class EventNotifier {
Lines 144-150 Link Here
144
     * Catches all exceptions and logs the stack trace.
145
     * Catches all exceptions and logs the stack trace.
145
     *
146
     *
146
     * <p>Returns if a queued change event was not planned before (i.e. does
147
     * <p>Returns if a queued change event was not planned before (i.e. does
147
     *   not correspond to an entry in {@link #changeListeners}.
148
     *   not correspond to an entry in {@link #changeListeners}).</p>
148
     */
149
     */
149
    private class EventsDelivery implements Runnable {
150
    private class EventsDelivery implements Runnable {
150
        /**
151
        /**
Lines 191-203 Link Here
191
     * the local queue and to fire the pre-change events.
192
     * the local queue and to fire the pre-change events.
192
     */ 
193
     */ 
193
    public abstract class Abstract {
194
    public abstract class Abstract {
195
        /**
196
         * Maps source objects to pre-change simple listeners.
197
         */
194
        private final HashMap preChange = new HashMap();
198
        private final HashMap preChange = new HashMap();
199
        /**
200
         * Maps source objects to pre-change recursive listeners.
201
         */
202
        private final HashMap preChangeRecursive = new HashMap();
203
        /**
204
         * Maps source objects to change listeners.
205
         */
195
        private final HashMap change = new HashMap();
206
        private final HashMap change = new HashMap();
207
        /**
208
         * Maps source objects to change recursive listeners.
209
         */
210
        private final HashMap changeRecursive = new HashMap();
196
    
211
    
197
        /** Registers a new listener in the map <code>listeners</code>.
212
        /** Registers a new listener in the map <code>listeners</code>.
198
         *
213
         *
199
         * <p>[PENDING]: make this method <code>static</code>
200
         *
201
         * @param listeners a map from source objects to sets of listeners
214
         * @param listeners a map from source objects to sets of listeners
202
         * @param listener the listener to be added to <code>listeners</code>
215
         * @param listener the listener to be added to <code>listeners</code>
203
         * @param the source object the listener shall be added for
216
         * @param the source object the listener shall be added for
Lines 217-224 Link Here
217
230
218
        /** Removes a listener from the map <code>listeners</code>.
231
        /** Removes a listener from the map <code>listeners</code>.
219
         *
232
         *
220
         * <p>[PENDING]: make this method <code>static</code>
221
         *
222
         * @param listeners a map from source objects to sets of listeners
233
         * @param listeners a map from source objects to sets of listeners
223
         * @param listener the listener to be removed from <code>listeners</code>
234
         * @param listener the listener to be removed from <code>listeners</code>
224
         * @param the source object the listener shall be removed for
235
         * @param the source object the listener shall be removed for
Lines 238-250 Link Here
238
        }
249
        }
239
250
240
        /**
251
        /**
241
         * Adds <code>listener</code> for object <code>source</code>.
252
         * Adds simple or recursive <code>listener</code> for object <code>source</code>.
242
         */
253
         */
243
        public void addListener(MDRChangeListener listener, Object source) {
254
        public void addListener(MDRChangeListener listener, Object source, boolean recursive) {
244
            if (listener instanceof MDRPreChangeListener) {
255
            /* A listener might well be added as a simple and a recursive listener.
245
                register(preChange, listener, source);
256
             * That causes no problems to our implementation. */
257
            if ( recursive ) {
258
                if (listener instanceof MDRPreChangeListener) {
259
                    register(preChangeRecursive, listener, source);
260
                } else {
261
                    register(changeRecursive, listener, source);
262
                }
246
            } else {
263
            } else {
247
                register(change, listener, source);
264
                if (listener instanceof MDRPreChangeListener) {
265
                    register(preChange, listener, source);
266
                } else {
267
                    register(change, listener, source);
268
                }
248
            }
269
            }
249
        }
270
        }
250
271
Lines 254-261 Link Here
254
        public void removeListener(MDRChangeListener listener, Object source) {
275
        public void removeListener(MDRChangeListener listener, Object source) {
255
            if (listener instanceof MDRPreChangeListener) {
276
            if (listener instanceof MDRPreChangeListener) {
256
                unregister(preChange, listener, source);
277
                unregister(preChange, listener, source);
278
                unregister(preChangeRecursive, listener, source);
257
            } else {
279
            } else {
258
                unregister(change, listener, source);
280
                unregister(change, listener, source);
281
                unregister(changeRecursive, listener, source);
259
            }
282
            }
260
        }
283
        }
261
284
Lines 271-277 Link Here
271
        public void firePlannedChange(Object current, MDRChangeEvent event) {
294
        public void firePlannedChange(Object current, MDRChangeEvent event) {
272
            localQueue.addLast(event);
295
            localQueue.addLast(event);
273
            HashSet collected = new HashSet();
296
            HashSet collected = new HashSet();
274
            collectListeners(current, event, false, collected);
297
            collectSimpleListeners(current, false, collected);
298
            collectRecursiveListeners(current, event, false, collected);
275
            for (Iterator it = collected.iterator(); it.hasNext();) {
299
            for (Iterator it = collected.iterator(); it.hasNext();) {
276
                try {
300
                try {
277
                    ((MDRPreChangeListener) it.next()).plannedChange(event);
301
                    ((MDRPreChangeListener) it.next()).plannedChange(event);
Lines 283-313 Link Here
283
            if (preChangeListeners.put(event, collected.clone()) != null) {
307
            if (preChangeListeners.put(event, collected.clone()) != null) {
284
                throw new DebugException("Same event fired twice.");
308
                throw new DebugException("Same event fired twice.");
285
            }
309
            }
286
            collectListeners(current, event, true, collected);
310
            collectSimpleListeners(current, true, collected);
311
            collectRecursiveListeners(current, event, true, collected);
287
            if (changeListeners.put(event, collected) != null) {
312
            if (changeListeners.put(event, collected) != null) {
288
                throw new DebugException("Same event fired twice.");
313
                throw new DebugException("Same event fired twice.");
289
            }
314
            }
290
        }
315
        }
291
316
292
        /**
317
        /**
293
         * Collect the listeners for the given <code>event</code> on object
318
         * Collect listeners from map <code>listeners</code> for object <code>current</code>
294
         * <code>current</code>. This method has to be overwritten by derived
319
         * into set <code>collected</code>.
295
         * classes to inform listeners on owner objects. Overwriting methods
296
         * shall call this method on then add any further listeners.
297
         *
298
         * @param current the object on which the event was fired
299
         * @param event the event
300
         * @param post if <code>false</code>, listeners implementing
301
         *    {@link org.netbeans.api.mdr.events.MDRPreChangeListener} are
302
         *    collected, otherwise listeners implementing only
303
         *    {@link org.netbeans.api.mdr.events.MDRChangeListener} 
304
         * @param collected the set to which the collected listeners have to be
305
         *             added
306
         */
320
         */
307
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
321
        private void collectListenersImpl(Map listeners, Object current, Set collected) {
308
            Set value;
322
            Set value;
309
            Map listeners = post ? change : preChange;
323
            
310
311
            // fire event on all listeners registered on this object
324
            // fire event on all listeners registered on this object
312
            synchronized (listeners) {
325
            synchronized (listeners) {
313
                value = (Set) listeners.get(current);
326
                value = (Set) listeners.get(current);
Lines 316-321 Link Here
316
                }
329
                }
317
            }
330
            }
318
        }
331
        }
332
        
333
        /**
334
         * Collect the simple listeners for the given <code>event</code> on object
335
         * <code>current</code>.
336
         * @param current the object on which the event was fired
337
         * @param post if <code>false</code>, simple listeners implementing
338
         *    {@link org.netbeans.api.mdr.events.MDRPreChangeListener} are
339
         *    collected, otherwise simple listeners implementing only
340
         *    {@link org.netbeans.api.mdr.events.MDRChangeListener} 
341
         * @param collected the set to which the collected simple listeners have to be
342
         *             added
343
         */
344
        private void collectSimpleListeners(Object current, boolean post, Set collected) {
345
            collectListenersImpl(post ? change : preChange, current, collected);
346
        }
347
        
348
        /**
349
         * Collect the recursive listeners for the given <code>event</code> on object
350
         * <code>current</code>. This method has to be overridden by derived
351
         * classes to inform recursive listeners on owner objects. Overwriting methods
352
         * shall call this method and then add any further recursive listeners.
353
         *
354
         * @param current the object on which the event was fired
355
         * @param event the event, super-classes will use this parameter to decide
356
         *              how to forward the event
357
         * @param post if <code>false</code>, recursive listeners implementing
358
         *    {@link org.netbeans.api.mdr.events.MDRPreChangeListener} are
359
         *    collected, otherwise recursive listeners implementing only
360
         *    {@link org.netbeans.api.mdr.events.MDRChangeListener} 
361
         * @param collected the set to which the collected recursive listeners have to be
362
         *             added
363
         */
364
        protected void collectRecursiveListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
365
            collectListenersImpl(post ? changeRecursive : preChangeRecursive, current, collected);
366
        }
319
    }
367
    }
320
    
368
    
321
    /* -------------------------------------------------------------------- */
369
    /* -------------------------------------------------------------------- */
Lines 331-352 Link Here
331
        }
379
        }
332
        
380
        
333
        /**
381
        /**
334
         * Adds listeners on the instances participating in the association link
382
         * Adds recursive listeners on the instances participating in the association link
335
         * added resp. removed and on the owning package.
383
         * added resp. removed and on the owning package.
336
         */
384
         */
337
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
385
        protected void collectRecursiveListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
338
            super.collectListeners(current, event, post, collected);
386
            super.collectRecursiveListeners(current, event, post, collected);
339
            
387
            
340
            // fire event on all listeners registered on instances that were affected
388
            // fire event on all listeners registered on instances that were affected
341
            if (event instanceof AssociationEvent) {
389
            if (event instanceof AssociationEvent) {
342
                AssociationEvent assocEvent = (AssociationEvent) event;
390
                AssociationEvent assocEvent = (AssociationEvent) event;
343
                if (assocEvent.getFixedElement() != null) INSTANCE.collectListeners(assocEvent.getFixedElement(), event, post, collected);
391
                if (assocEvent.getFixedElement() != null) INSTANCE.collectRecursiveListeners(assocEvent.getFixedElement(), event, post, collected);
344
                if (assocEvent.getOldElement() != null) INSTANCE.collectListeners(assocEvent.getOldElement(), event, post, collected);
392
                if (assocEvent.getOldElement() != null) INSTANCE.collectRecursiveListeners(assocEvent.getOldElement(), event, post, collected);
345
                if (assocEvent.getNewElement() != null) INSTANCE.collectListeners(assocEvent.getNewElement(), event, post, collected);
393
                if (assocEvent.getNewElement() != null) INSTANCE.collectRecursiveListeners(assocEvent.getNewElement(), event, post, collected);
346
            }
394
            }
347
            
395
            
348
            // fire event on the immediate package extent
396
            // fire event on the immediate package extent
349
            PACKAGE.collectListeners(((RefAssociation) current).refImmediatePackage(), event, post, collected);
397
            PACKAGE.collectRecursiveListeners(((RefAssociation) current).refImmediatePackage(), event, post, collected);
350
        }
398
        }
351
    }
399
    }
352
    
400
    
Lines 365-373 Link Here
365
        /**
413
        /**
366
         * Adds listeners on the owning package.
414
         * Adds listeners on the owning package.
367
         */
415
         */
368
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
416
        protected void collectRecursiveListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
369
            super.collectListeners(current, event, post, collected);
417
            super.collectRecursiveListeners(current, event, post, collected);
370
            PACKAGE.collectListeners(((RefClass) current).refImmediatePackage(), event, post, collected);
418
            PACKAGE.collectRecursiveListeners(((RefClass) current).refImmediatePackage(), event, post, collected);
371
        }
419
        }
372
    }
420
    }
373
    
421
    
Lines 384-394 Link Here
384
        }
432
        }
385
        
433
        
386
        /**
434
        /**
387
         * Adds listeners on the owning class proxy.
435
         * Adds recursive listeners on the owning class proxy.
388
         */
436
         */
389
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
437
        protected void collectRecursiveListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
390
            super.collectListeners(current, event, post, collected);
438
            super.collectRecursiveListeners(current, event, post, collected);
391
            CLASS.collectListeners(((RefObject) current).refClass(), event, post, collected);
439
            CLASS.collectRecursiveListeners(((RefObject) current).refClass(), event, post, collected);
392
        }
440
        }
393
    }
441
    }
394
    
442
    
Lines 405-420 Link Here
405
        }
453
        }
406
        
454
        
407
        /**
455
        /**
408
         * Adds listeners on the owning package resp., if this package is
456
         * Adds recursive listeners on the owning package resp., if this package is
409
         * outermost, on the repository.
457
         * outermost, on the repository.
410
         */
458
         */
411
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
459
        protected void collectRecursiveListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
412
            super.collectListeners(current, event, post, collected);
460
            super.collectRecursiveListeners(current, event, post, collected);
413
            RefPackage immediate = ((RefPackage) current).refImmediatePackage();
461
            RefPackage immediate = ((RefPackage) current).refImmediatePackage();
414
            if (immediate != null) {
462
            if (immediate != null) {
415
                collectListeners(immediate, event, post, collected);
463
                collectRecursiveListeners(immediate, event, post, collected);
416
            } else {
464
            } else {
417
                REPOSITORY.collectListeners(((BaseObjectHandler) current)._getDelegate().getMdrStorage(), event, post, collected);
465
                REPOSITORY.collectRecursiveListeners(((BaseObjectHandler) current)._getDelegate().getMdrStorage(), event, post, collected);
418
            }
466
            }
419
        }
467
        }
420
    }
468
    }
(-)org/netbeans/mdr/handlers/ClassProxyHandler.java (-2 / +10 lines)
Lines 236-245 Link Here
236
    /* -------------------------------------------------------------------- */
236
    /* -------------------------------------------------------------------- */
237
    
237
    
238
    /** Registers a listener for receiving event notifications.
238
    /** Registers a listener for receiving event notifications.
239
     * @param listener Object that implements {@link Listener} interface.
239
     * @param listener Object that implements {@link MDRChangeListener} interface.
240
     */
240
     */
241
    public void addListener(MDRChangeListener listener) {
241
    public void addListener(MDRChangeListener listener) {
242
        _getMdrStorage().getEventNotifier().CLASS.addListener(listener, this);
242
        addListener(listener, false);
243
    }
244
245
    /** Registers a hierarchy listener for receiving event notifications.
246
     * @param listener Object that implements {@link MDRChangeListener} interface.
247
     * @param recursive
248
     */
249
    public void addListener(MDRChangeListener listener, boolean recursive) {
250
        _getMdrStorage().getEventNotifier().CLASS.addListener(listener, this, recursive);
243
    }
251
    }
244
    
252
    
245
    /** Removes listener from the list of objects registered for events notifications.
253
    /** Removes listener from the list of objects registered for events notifications.
(-)org/netbeans/mdr/handlers/InstanceHandler.java (-2 / +10 lines)
Lines 349-358 Link Here
349
    /* -------------------------------------------------------------------- */
349
    /* -------------------------------------------------------------------- */
350
    
350
    
351
    /** Registers a listener for receiving event notifications.
351
    /** Registers a listener for receiving event notifications.
352
     * @param listener Object that implements {@link Listener} interface.
352
     * @param listener Object that implements {@link MDRChangeListener} interface.
353
     */
353
     */
354
    public void addListener(MDRChangeListener listener) {
354
    public void addListener(MDRChangeListener listener) {
355
        _getMdrStorage().getEventNotifier().INSTANCE.addListener(listener, this);
355
        addListener(listener, false);
356
    }
357
    
358
    /** Registers a hierarchy listener for receiving event notifications.
359
     * @param listener Object that implements {@link MDRChangeListener} interface.
360
     * @param recursive
361
     */
362
    public void addListener(MDRChangeListener listener, boolean recursive) {
363
        _getMdrStorage().getEventNotifier().INSTANCE.addListener(listener, this, recursive);
356
    }
364
    }
357
    
365
    
358
    /** Removes listener from the list of objects registered for events notifications.
366
    /** Removes listener from the list of objects registered for events notifications.
(-)org/netbeans/mdr/handlers/PackageProxyHandler.java (-2 / +10 lines)
Lines 328-337 Link Here
328
    /* -------------------------------------------------------------------- */
328
    /* -------------------------------------------------------------------- */
329
329
330
    /** Registers a listener for receiving event notifications.
330
    /** Registers a listener for receiving event notifications.
331
     * @param listener Object that implements {@link Listener} interface.
331
     * @param listener Object that implements {@link MDRChangeListener} interface.
332
     */
332
     */
333
    public void addListener(MDRChangeListener listener) {
333
    public void addListener(MDRChangeListener listener) {
334
        _getMdrStorage().getEventNotifier().PACKAGE.addListener(listener, this);
334
        addListener(listener, false);
335
    }
336
337
    /** Registers a hierarchy listener for receiving event notifications.
338
     * @param listener Object that implements {@link MDRChangeListener} interface.
339
     * @param recursive
340
     */
341
    public void addListener(MDRChangeListener listener, boolean recursive) {
342
        _getMdrStorage().getEventNotifier().PACKAGE.addListener(listener, this, recursive);
335
    }
343
    }
336
    
344
    
337
    /** Removes listener from the list of objects registered for events notifications.
345
    /** Removes listener from the list of objects registered for events notifications.
(-)org/netbeans/mdr/handlers/AssociationHandler.java (-2 / +10 lines)
Lines 304-313 Link Here
304
    }
304
    }
305
     */
305
     */
306
    /** Registers a listener for receiving event notifications.
306
    /** Registers a listener for receiving event notifications.
307
     * @param listener Object that implements {@link Listener} interface.
307
     * @param listener Object that implements {@link MDRChangeListener} interface.
308
     */
308
     */
309
    public void addListener(MDRChangeListener listener) {
309
    public void addListener(MDRChangeListener listener) {
310
        _getMdrStorage().getEventNotifier().ASSOCIATION.addListener(listener, this);
310
        addListener(listener, false);
311
    }
312
    
313
    /** Registers a hierarchy listener for receiving event notifications.
314
     * @param listener Object that implements {@link MDRChangeListener} interface.
315
     * @param recursive
316
     */
317
    public void addListener(MDRChangeListener listener, boolean recursive) {
318
        _getMdrStorage().getEventNotifier().ASSOCIATION.addListener(listener, this, recursive);
311
    }
319
    }
312
    
320
    
313
    /** Removes listener from the list of objects registered for events notifications.
321
    /** Removes listener from the list of objects registered for events notifications.
(-)org/netbeans/modules/mdrexplorer/looks/MDREventHandler.java (-45 / +68 lines)
Lines 26-49 Link Here
26
import org.netbeans.api.looks.Look;
26
import org.netbeans.api.looks.Look;
27
27
28
/**
28
/**
29
 * Instances of <code>MDREventHandler</code> are event handlers which listen
30
 * on repository changes on behalf of {@link org.netbeans.api.looks.LookNodeSubstitutes
31
 * node substitutes}. They manage a map from repository objects to node substitutes
32
 * to be able to access the node substitute for a given repository object. Looks
33
 * have to register their node subsitutes by calling {@link #addNodeSubstitute(Look.NodeSubstitute)}
34
 * or {@link #addNodeSubstitute(Object, Look.NodeSubstitute)} from within
35
 * {@link org.netbeans.api.looks.Look#attachTo(ook.NodeSubstitute)}.
29
 *
36
 *
37
 * @deprecated register NodeSubstitutes directly on repository objects instead, see
38
 *     <a href="http://mdr.netbeans.org/issues/show_bug.cgi?id=25186">issue 25186</a>
30
 * @author  Tomas Zezula
39
 * @author  Tomas Zezula
31
 */
40
 */
32
public class MDREventHandler implements MDRPreChangeListener {
41
public class MDREventHandler implements MDRPreChangeListener {
33
    
42
    
43
    /* --------------------------------------------------------------------- */
44
    /* -- Attributes ------------------------------------------------------- */
45
    /* --------------------------------------------------------------------- */
46
47
    /**
48
     * Maps repository content to node substitutes.
49
     */
34
    private HashMap registeredNodeSubstitutes;
50
    private HashMap registeredNodeSubstitutes;
51
    
52
    /**
53
     * Map storing the parents of objects to be deleted. After an object has
54
     * been deleted, its parent node is not accessible any more. Nevertheless it
55
     * must be refreshed to reflect the deletion of the node representing the object.
56
     * Hence the parents of the objects to be deleted are stored in the map.
57
     */
35
    private HashMap pendingEvents;
58
    private HashMap pendingEvents;
36
    private ReferenceQueue queue;
59
    private ReferenceQueue queue;
37
    private MDRepository repository;
60
    private MDRepository repository;
38
    
61
    
62
    /* --------------------------------------------------------------------- */
63
    /* -- Constructor ------------------------------------------------------ */
64
    /* --------------------------------------------------------------------- */
65
    
39
    public MDREventHandler  (MDRepository repository) {
66
    public MDREventHandler  (MDRepository repository) {
40
        this.queue = new ReferenceQueue();
67
        this.queue = new ReferenceQueue();
41
        this.registeredNodeSubstitutes = new HashMap();
68
        this.registeredNodeSubstitutes = new HashMap();
42
        this.pendingEvents = new HashMap();
69
        this.pendingEvents = new HashMap();
43
        this.repository = repository;
70
        this.repository = repository;
44
        this.repository.addListener(this);
71
        this.repository.addListener(this, true);
45
    }
72
    }
46
    
73
    
74
    /* --------------------------------------------------------------------- */
75
    /* -- Management of NodeSubstitutes ------------------------------------ */
76
    /* --------------------------------------------------------------------- */
77
    
47
    public synchronized void addNodeSubstitute(Look.NodeSubstitute substitute) {
78
    public synchronized void addNodeSubstitute(Look.NodeSubstitute substitute) {
48
        if (substitute == null)
79
        if (substitute == null)
49
            return;
80
            return;
Lines 56-87 Link Here
56
        this.registeredNodeSubstitutes.put(key, new WeakReference(substitute,this.queue));
87
        this.registeredNodeSubstitutes.put(key, new WeakReference(substitute,this.queue));
57
    }
88
    }
58
    
89
    
59
    /** This method is called when the node was garbage collected. You shoud
90
    private synchronized Look.NodeSubstitute getNodeSubstituteForObject(Object object) {
60
     * unregister from all objects where this object was registered as a
91
        if (object ==null)
61
     * listener.
92
            return null;
62
     */
93
        Reference ref = (Reference) this.registeredNodeSubstitutes.get(object);
63
    
94
        if (ref == null) {
64
    /** This method gets called if a planned change (which was already announced
95
            return null; // Not registered object
65
     * by calling {@link #plannedChange} was cancelled (e.g. the operation that was
66
     * going to perform the change failed). This method is called synchronously by
67
     * the operation that tried to perform the change.<p>
68
     * Any run-time exception thrown by the implementation of this method should
69
     * not affect the events dispatching (i.e. it should be ignored by the event source).
70
     * @param e Object describing the cancelled change (has to be the same instance
71
     * as passed to the {@link #plannedChange} method).
72
     */
73
    public void changeCancelled(MDRChangeEvent e) {
74
        if ((e.getType() & 2) == 2) {
75
            this.pendingEvents.remove(e.getSource());
76
        }
96
        }
97
        Look.NodeSubstitute substitute = (Look.NodeSubstitute) ref.get();
98
        return substitute;
77
    }
99
    }
78
    
100
    
79
    /** This method gets called when a repository change is planned to occur.
101
    /* --------------------------------------------------------------------- */
80
     * Any operation that performs a change in MDR has to fire this notification
102
    /* -- Implements org.netbeans.api.mdr.MDRPreChangeListener ------------- */
81
     * synchronously on each registered pre-change listener before the change is performed.<p>
103
    /* --------------------------------------------------------------------- */
82
     * Any run-time exception thrown by the implementation of this method should
104
    
83
     * not affect the events dispatching (i.e. it should be ignored by the event source).
105
    /**
84
     * @param e Object describing the planned change.
106
     * Handles deletion events only. Stores the parents of objects to be deleted.
107
     * This is necessary to refresh parent nodes when the object to be deleted
108
     * has been deleted.
85
     */
109
     */
86
    public void plannedChange(MDRChangeEvent e) {
110
    public void plannedChange(MDRChangeEvent e) {
87
        if ((e.getType() & ExtentEvent.EVENT_EXTENT_DELETE) == ExtentEvent.EVENT_EXTENT_DELETE) {
111
        if ((e.getType() & ExtentEvent.EVENT_EXTENT_DELETE) == ExtentEvent.EVENT_EXTENT_DELETE) {
Lines 107-122 Link Here
107
        }
131
        }
108
    }
132
    }
109
    
133
    
110
    /** This method gets called after a repository change is performed. This method
134
    /**
111
     * is called asynchronously.
135
     * Removes the information stored for the pending event <code>e</code>.
112
     * If a listener implements {@link MDRPreChangeListener} which is a descedant
136
     * @see #plannedChange(MDRChangeEvent)
113
     * of this interface, the event object passed to this method must be the same
137
     */
114
     * instance as the event object previously passed to the corresponding
138
    public void changeCancelled(MDRChangeEvent e) {
115
     * {@link MDRPreChangeListener#plannedChange} method call of the listener.<p>
139
        if ((e.getType() & 2) == 2) {
116
     * Any run-time exception thrown by the implementation of this method should
140
            this.pendingEvents.remove(e.getSource());
117
     * not affect the events dispatching (i.e. it should be ignored by the event source).
141
        }
118
     *
142
    }
119
     * @param e Object describing the performed change.
143
144
    /**
145
     * Refreshes the nodes affected by <code>e</code>.
120
     */
146
     */
121
    public void change(MDRChangeEvent e) {
147
    public void change(MDRChangeEvent e) {
122
        if ((e.getType() & ExtentEvent.EVENT_EXTENT_CREATE) == ExtentEvent.EVENT_EXTENT_CREATE) {
148
        if ((e.getType() & ExtentEvent.EVENT_EXTENT_CREATE) == ExtentEvent.EVENT_EXTENT_CREATE) {
Lines 171-176 Link Here
171
        }
197
        }
172
    }
198
    }
173
    
199
    
200
    /* --------------------------------------------------------------------- */
201
    /* -- Clean-up dangling map entries ------------------------------------ */
202
    /* --------------------------------------------------------------------- */
203
    
204
    /**
205
     * Removes entries with garbage collected values from the map associating
206
     * repository objects with node substitutes.
207
     */
174
    synchronized void flushReferenceQueue() {
208
    synchronized void flushReferenceQueue() {
175
        if (this.queue.poll()!=null) {
209
        if (this.queue.poll()!=null) {
176
            Iterator values = this.registeredNodeSubstitutes.values().iterator();
210
            Iterator values = this.registeredNodeSubstitutes.values().iterator();
Lines 184-200 Link Here
184
        }
218
        }
185
    }
219
    }
186
    
220
    
187
    
188
    private synchronized Look.NodeSubstitute getNodeSubstituteForObject(Object object) {
189
        if (object ==null)
190
            return null;
191
        Reference ref = (Reference) this.registeredNodeSubstitutes.get(object);
192
        if (ref == null) {
193
            return null; // Not registered object
194
        }
195
        Look.NodeSubstitute substitute = (Look.NodeSubstitute) ref.get();
196
        return substitute;
197
    }
198
    
221
    
199
    
222
    
200
}
223
}
(-)org/netbeans/api/mdr/events/MDRChangeSource.java (-11 / +34 lines)
Lines 18-49 Link Here
18
 * The objects that have to be registered for event
18
 * The objects that have to be registered for event
19
 * notifications need to implement {@link MDRChangeListener}
19
 * notifications need to implement {@link MDRChangeListener}
20
 * or {@link MDRPreChangeListener} interface.<p>
20
 * or {@link MDRPreChangeListener} interface.<p>
21
 * The repository should distribute all the events in the following way:
21
 *
22
 * <p>The user can register simple and recursive listeners. Simple listeners
23
 * can be registered for events originating on the object the
24
 * listener is registered for by calling <code>addListener(listener)</code>.
25
 * Recursive listeners, which receive events originating on a hierarchy of objects,
26
 * can be registered by calling <code>addListener(listener, true)</code>.</p>
27
 *
28
 * The repository should distribute the events to recursive listeners in the
29
 * following way:
22
 * <ul>
30
 * <ul>
23
 * <li>Each event fired on an instance is also fired on the corresponding class proxy for this instance.
31
 * <li>Events fired on an instance are propagated to the recursive listeners for the
24
 * <li>Events fired on a class proxy are propagated to its immediate package proxy.
32
 *        corresponding class proxy for this instance.
25
 * <li>Events fired on an association proxy are fired on all the instances affected by this event 
33
 * <li>Events fired on a class proxy are propagated to the recursive listeners
26
 * (e.g. instances added/removed from a link) and also it is fired on the immediate package proxy.
34
 *       for its immediate package proxy.
27
 * <li>Each event fired on a package proxy are propagated to its immediate package proxy.
35
 * <li>Events fired on an association proxy are propagated to the recursive listeners on
28
 * If the package proxy is outermost, the event is propagated to the MDRepository that contains
36
 *    the instances affected by this event (e.g. instances added/removed from a link)
29
 * the proxy.
37
 * and is also propagated to the recursive listeners on the immediate package proxy.
38
 * <li>Event fired on a package proxy are propagated to the recursive listeners
39
 * of its immediate package proxy. If the package proxy is outermost, the event is
40
 * propagated to the recursive listeners of the MDRepository that contains the proxy.
30
 * </ul>
41
 * </ul>
31
 * All the events are propagated recursively till they reach the repository object (e.g. each
42
 * All the events are propagated recursively to recursive listeners till they reach
43
 * the repository object (e.g. each
32
 * instance event is as a result of propagation always fired on the instance itself,
44
 * instance event is as a result of propagation always fired on the instance itself,
33
 * on its class proxy, on its immediate package proxy, on all other package proxies containing
45
 * on its class proxy, on its immediate package proxy, on all other package proxies containing
34
 * the immediate package proxy to the outermost package proxy and at the end on the repository containing
46
 * the immediate package proxy to the outermost package proxy and at the end on the repository containing
35
 * instance).<br>
47
 * instance - all recursive listeners in this chain of objects are informed about the
48
 * event, and also the simple listeners at the starting point of the chain).<br>
36
 * In addition, any event is fired only once for each listener (so no matter how many objects 
49
 * In addition, any event is fired only once for each listener (so no matter how many objects 
37
 * on the event's propagation path is a listener registered on - e.g. on both
50
 * on the event's propagation path is a listener registered on - e.g. on both
38
 * class proxy and its instances - it receives each notification only once per event). 
51
 * class proxy and its instances - it receives each notification only once per event). 
39
 *
52
 *
40
 * @author Martin Matula
53
 * @author Martin Matula
54
 * @author <a href="mailto:hkrug@rationalizer.com">Holger Krug</a>
41
 */
55
 */
42
public interface MDRChangeSource {
56
public interface MDRChangeSource {
43
    /** Registers a listener for receiving event notifications.
57
    /** Registers a simple listener to receive event notifications for this
58
     *  <code>MDRChangeSource</code>. The same as <code>addListener(listener, false)</code>.
44
     * @param listener Object that implements {@link MDRChangeListener} interface.
59
     * @param listener Object that implements {@link MDRChangeListener} interface.
45
     */    
60
     */    
46
    public void addListener(MDRChangeListener listener);
61
    public void addListener(MDRChangeListener listener);
62
    /** Registers a simple or recursive listener to receive event notifications
63
     *  for this <code>MDRChangeSource</code> and, if <code>recursive == true</code>,
64
     * its "children".
65
     * @param listener Object that implements {@link MDRChangeListener} interface.
66
     * @recursive if <code>true</code> the listener is recursive, otherwise it is
67
     *    simple
68
     */    
69
    public void addListener(MDRChangeListener listener, boolean recursive);
47
    /** Removes listener from the list of objects registered for events notifications.
70
    /** Removes listener from the list of objects registered for events notifications.
48
     * @param listener Object that implements {@link MDRChangeListener} interface.
71
     * @param listener Object that implements {@link MDRChangeListener} interface.
49
     */    
72
     */    
(-)org/netbeans/mdr/NBMDRepositoryImpl.java (-5 / +15 lines)
Lines 110-123 Link Here
110
    }
110
    }
111
    
111
    
112
    /** Creates new {@link org.netbeans.api.mdr.MDRepository} with given parameters.
112
    /** Creates new {@link org.netbeans.api.mdr.MDRepository} with given parameters.
113
     *  The following parameters are processed:
113
     *  The following parameter is processed:
114
     *
114
     *
115
     *  <p><ol>
115
     *  <p><ol>
116
     *    <li><code>storage</code>: name of a class implementing {@link
116
     *    <li><code>storage</code>: name of a class implementing {@link
117
     *          org.netbeans.mdr.persistence.StorageFactory}</li>
117
     *          org.netbeans.mdr.persistence.StorageFactory}</li>
118
     *    <li><code>fileName</code>: storage location</li>
118
     *  </ol></p>
119
     *  </ol>
120
     *
119
     *
120
     *  <p>All other parameters depend on the <code>StorageFactory</code> and are
121
     *     forwarded to
122
     *   {@link rg.netbeans.mdr.persistence.StorageFactory#createStorage(java.util.Map)}.</p>
121
     */
123
     */
122
    public NBMDRepositoryImpl(Map parameters) {
124
    public NBMDRepositoryImpl(Map parameters) {
123
        Log.out.println("Creating MDRepository implementation ...");
125
        Log.out.println("Creating MDRepository implementation ...");
Lines 130-140 Link Here
130
    /* -------------------------------------------------------------------- */
132
    /* -------------------------------------------------------------------- */
131
    
133
    
132
    /** Registers a listener for receiving event notifications.
134
    /** Registers a listener for receiving event notifications.
133
     * @param listener Object that implements {@link Listener} interface.
135
     * @param listener Object that implements {@link MDRChangeListener} interface.
134
     */
136
     */
135
    public void addListener(MDRChangeListener listener) {
137
    public void addListener(MDRChangeListener listener) {
138
        addListener(listener, false);
139
    }
140
    
141
    /** Registers a hierarchy listener for receiving event notifications.
142
     * @param listener Object that implements {@link MDRChangeListener} interface.
143
     * @param recursive
144
     */
145
    public void addListener(MDRChangeListener listener, boolean recursive) {
136
        initCheck();
146
        initCheck();
137
        mdrStorage.getEventNotifier().REPOSITORY.addListener(listener, mdrStorage);
147
        mdrStorage.getEventNotifier().REPOSITORY.addListener(listener, mdrStorage, recursive);
138
    }
148
    }
139
    
149
    
140
    /** Removes listener from the list of objects registered for events notifications.
150
    /** Removes listener from the list of objects registered for events notifications.

Return to bug 25186