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 (-42 / +97 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 listeners.
197
         */
194
        private final HashMap preChange = new HashMap();
198
        private final HashMap preChange = new HashMap();
199
        /**
200
         * Maps source objects to pre-change hierarchy listeners.
201
         */
202
        private final HashMap preChangeHierarchy = 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 hierarchy listeners.
209
         */
210
        private final HashMap changeHierarchy = 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 241-246 Link Here
241
         * Adds <code>listener</code> for object <code>source</code>.
252
         * Adds <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) {
255
            /* We do not check if the listener was already added as hierarchy listener.
256
             * If a listener is added as well as simple as also as hierarchy listener,
257
             * the correctness of the implementation will not be affected. */
244
            if (listener instanceof MDRPreChangeListener) {
258
            if (listener instanceof MDRPreChangeListener) {
245
                register(preChange, listener, source);
259
                register(preChange, listener, source);
246
            } else {
260
            } else {
Lines 249-261 Link Here
249
        }
263
        }
250
264
251
        /**
265
        /**
266
         * Adds hierarchy <code>listener</code> for object <code>source</code>.
267
         */
268
        public void addHierarchyListener(MDRChangeListener listener, Object source) {
269
            /* We do not check if the listener was already added as simple listener.
270
             * If a listener is added as well as simple as also as hierarchy listener,
271
             * the correctness of the implementation will not be affected. */
272
            if (listener instanceof MDRPreChangeListener) {
273
                register(preChangeHierarchy, listener, source);
274
            } else {
275
                register(changeHierarchy, listener, source);
276
            }
277
        }
278
279
        /**
252
         * Removes <code>listener</code> for object <code>source</code>.
280
         * Removes <code>listener</code> for object <code>source</code>.
253
         */
281
         */
254
        public void removeListener(MDRChangeListener listener, Object source) {
282
        public void removeListener(MDRChangeListener listener, Object source) {
255
            if (listener instanceof MDRPreChangeListener) {
283
            if (listener instanceof MDRPreChangeListener) {
256
                unregister(preChange, listener, source);
284
                unregister(preChange, listener, source);
285
                unregister(preChangeHierarchy, listener, source);
257
            } else {
286
            } else {
258
                unregister(change, listener, source);
287
                unregister(change, listener, source);
288
                unregister(changeHierarchy, listener, source);
259
            }
289
            }
260
        }
290
        }
261
291
Lines 271-277 Link Here
271
        public void firePlannedChange(Object current, MDRChangeEvent event) {
301
        public void firePlannedChange(Object current, MDRChangeEvent event) {
272
            localQueue.addLast(event);
302
            localQueue.addLast(event);
273
            HashSet collected = new HashSet();
303
            HashSet collected = new HashSet();
274
            collectListeners(current, event, false, collected);
304
            collectSimpleListeners(current, false, collected);
305
            collectHierarchyListeners(current, event, false, collected);
275
            for (Iterator it = collected.iterator(); it.hasNext();) {
306
            for (Iterator it = collected.iterator(); it.hasNext();) {
276
                try {
307
                try {
277
                    ((MDRPreChangeListener) it.next()).plannedChange(event);
308
                    ((MDRPreChangeListener) it.next()).plannedChange(event);
Lines 283-313 Link Here
283
            if (preChangeListeners.put(event, collected.clone()) != null) {
314
            if (preChangeListeners.put(event, collected.clone()) != null) {
284
                throw new DebugException("Same event fired twice.");
315
                throw new DebugException("Same event fired twice.");
285
            }
316
            }
286
            collectListeners(current, event, true, collected);
317
            collectSimpleListeners(current, true, collected);
318
            collectHierarchyListeners(current, event, true, collected);
287
            if (changeListeners.put(event, collected) != null) {
319
            if (changeListeners.put(event, collected) != null) {
288
                throw new DebugException("Same event fired twice.");
320
                throw new DebugException("Same event fired twice.");
289
            }
321
            }
290
        }
322
        }
291
323
292
        /**
324
        /**
293
         * Collect the listeners for the given <code>event</code> on object
325
         * Collect listeners from map <code>listeners</code> for object <code>current</code>
294
         * <code>current</code>. This method has to be overwritten by derived
326
         * 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
         */
327
         */
307
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
328
        private void collectListenersImpl(Map listeners, Object current, Set collected) {
308
            Set value;
329
            Set value;
309
            Map listeners = post ? change : preChange;
330
            
310
311
            // fire event on all listeners registered on this object
331
            // fire event on all listeners registered on this object
312
            synchronized (listeners) {
332
            synchronized (listeners) {
313
                value = (Set) listeners.get(current);
333
                value = (Set) listeners.get(current);
Lines 316-321 Link Here
316
                }
336
                }
317
            }
337
            }
318
        }
338
        }
339
        
340
        /**
341
         * Collect the simple listeners for the given <code>event</code> on object
342
         * <code>current</code>.
343
         * @param current the object on which the event was fired
344
         * @param post if <code>false</code>, simple listeners implementing
345
         *    {@link org.netbeans.api.mdr.events.MDRPreChangeListener} are
346
         *    collected, otherwise simple listeners implementing only
347
         *    {@link org.netbeans.api.mdr.events.MDRChangeListener} 
348
         * @param collected the set to which the collected simple listeners have to be
349
         *             added
350
         */
351
        private void collectSimpleListeners(Object current, boolean post, Set collected) {
352
            collectListenersImpl(post ? change : preChange, current, collected);
353
        }
354
        
355
        /**
356
         * Collect the hierarchy listeners for the given <code>event</code> on object
357
         * <code>current</code>. This method has to be overridden by derived
358
         * classes to inform hierarchy listeners on owner objects. Overwriting methods
359
         * shall call this method and then add any further hierarchy listeners.
360
         *
361
         * @param current the object on which the event was fired
362
         * @param event the event, super-classes will use this parameter to decide
363
         *              how to forward the event
364
         * @param post if <code>false</code>, hierarchy listeners implementing
365
         *    {@link org.netbeans.api.mdr.events.MDRPreChangeListener} are
366
         *    collected, otherwise hierarchy listeners implementing only
367
         *    {@link org.netbeans.api.mdr.events.MDRChangeListener} 
368
         * @param collected the set to which the collected hierarchy listeners have to be
369
         *             added
370
         */
371
        protected void collectHierarchyListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
372
            collectListenersImpl(post ? changeHierarchy : preChangeHierarchy, current, collected);
373
        }
319
    }
374
    }
320
    
375
    
321
    /* -------------------------------------------------------------------- */
376
    /* -------------------------------------------------------------------- */
Lines 331-352 Link Here
331
        }
386
        }
332
        
387
        
333
        /**
388
        /**
334
         * Adds listeners on the instances participating in the association link
389
         * Adds hierarchy listeners on the instances participating in the association link
335
         * added resp. removed and on the owning package.
390
         * added resp. removed and on the owning package.
336
         */
391
         */
337
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
392
        protected void collectHierarchyListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
338
            super.collectListeners(current, event, post, collected);
393
            super.collectHierarchyListeners(current, event, post, collected);
339
            
394
            
340
            // fire event on all listeners registered on instances that were affected
395
            // fire event on all listeners registered on instances that were affected
341
            if (event instanceof AssociationEvent) {
396
            if (event instanceof AssociationEvent) {
342
                AssociationEvent assocEvent = (AssociationEvent) event;
397
                AssociationEvent assocEvent = (AssociationEvent) event;
343
                if (assocEvent.getFixedElement() != null) INSTANCE.collectListeners(assocEvent.getFixedElement(), event, post, collected);
398
                if (assocEvent.getFixedElement() != null) INSTANCE.collectHierarchyListeners(assocEvent.getFixedElement(), event, post, collected);
344
                if (assocEvent.getOldElement() != null) INSTANCE.collectListeners(assocEvent.getOldElement(), event, post, collected);
399
                if (assocEvent.getOldElement() != null) INSTANCE.collectHierarchyListeners(assocEvent.getOldElement(), event, post, collected);
345
                if (assocEvent.getNewElement() != null) INSTANCE.collectListeners(assocEvent.getNewElement(), event, post, collected);
400
                if (assocEvent.getNewElement() != null) INSTANCE.collectHierarchyListeners(assocEvent.getNewElement(), event, post, collected);
346
            }
401
            }
347
            
402
            
348
            // fire event on the immediate package extent
403
            // fire event on the immediate package extent
349
            PACKAGE.collectListeners(((RefAssociation) current).refImmediatePackage(), event, post, collected);
404
            PACKAGE.collectHierarchyListeners(((RefAssociation) current).refImmediatePackage(), event, post, collected);
350
        }
405
        }
351
    }
406
    }
352
    
407
    
Lines 365-373 Link Here
365
        /**
420
        /**
366
         * Adds listeners on the owning package.
421
         * Adds listeners on the owning package.
367
         */
422
         */
368
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
423
        protected void collectHierarchyListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
369
            super.collectListeners(current, event, post, collected);
424
            super.collectHierarchyListeners(current, event, post, collected);
370
            PACKAGE.collectListeners(((RefClass) current).refImmediatePackage(), event, post, collected);
425
            PACKAGE.collectHierarchyListeners(((RefClass) current).refImmediatePackage(), event, post, collected);
371
        }
426
        }
372
    }
427
    }
373
    
428
    
Lines 384-394 Link Here
384
        }
439
        }
385
        
440
        
386
        /**
441
        /**
387
         * Adds listeners on the owning class proxy.
442
         * Adds hierarchy listeners on the owning class proxy.
388
         */
443
         */
389
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
444
        protected void collectHierarchyListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
390
            super.collectListeners(current, event, post, collected);
445
            super.collectHierarchyListeners(current, event, post, collected);
391
            CLASS.collectListeners(((RefObject) current).refClass(), event, post, collected);
446
            CLASS.collectHierarchyListeners(((RefObject) current).refClass(), event, post, collected);
392
        }
447
        }
393
    }
448
    }
394
    
449
    
Lines 405-420 Link Here
405
        }
460
        }
406
        
461
        
407
        /**
462
        /**
408
         * Adds listeners on the owning package resp., if this package is
463
         * Adds hierarchy listeners on the owning package resp., if this package is
409
         * outermost, on the repository.
464
         * outermost, on the repository.
410
         */
465
         */
411
        protected void collectListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
466
        protected void collectHierarchyListeners(Object current, MDRChangeEvent event, boolean post, Set collected) {
412
            super.collectListeners(current, event, post, collected);
467
            super.collectHierarchyListeners(current, event, post, collected);
413
            RefPackage immediate = ((RefPackage) current).refImmediatePackage();
468
            RefPackage immediate = ((RefPackage) current).refImmediatePackage();
414
            if (immediate != null) {
469
            if (immediate != null) {
415
                collectListeners(immediate, event, post, collected);
470
                collectHierarchyListeners(immediate, event, post, collected);
416
            } else {
471
            } else {
417
                REPOSITORY.collectListeners(((BaseObjectHandler) current)._getDelegate().getMdrStorage(), event, post, collected);
472
                REPOSITORY.collectHierarchyListeners(((BaseObjectHandler) current)._getDelegate().getMdrStorage(), event, post, collected);
418
            }
473
            }
419
        }
474
        }
420
    }
475
    }
(-)org/netbeans/mdr/handlers/InstanceHandler.java (+7 lines)
Lines 355-360 Link Here
355
        _getMdrStorage().getEventNotifier().INSTANCE.addListener(listener, this);
355
        _getMdrStorage().getEventNotifier().INSTANCE.addListener(listener, this);
356
    }
356
    }
357
    
357
    
358
    /** Registers a hierarchy listener for receiving event notifications.
359
     * @param listener Object that implements {@link Listener} interface.
360
     */
361
    public void addHierarchyListener(MDRChangeListener listener) {
362
        _getMdrStorage().getEventNotifier().INSTANCE.addHierarchyListener(listener, this);
363
    }
364
    
358
    /** Removes listener from the list of objects registered for events notifications.
365
    /** Removes listener from the list of objects registered for events notifications.
359
     * @param listener Object that implements {@link Listener} interface.
366
     * @param listener Object that implements {@link Listener} interface.
360
     */
367
     */
(-)org/netbeans/mdr/handlers/ClassProxyHandler.java (+7 lines)
Lines 241-246 Link Here
241
    public void addListener(MDRChangeListener listener) {
241
    public void addListener(MDRChangeListener listener) {
242
        _getMdrStorage().getEventNotifier().CLASS.addListener(listener, this);
242
        _getMdrStorage().getEventNotifier().CLASS.addListener(listener, this);
243
    }
243
    }
244
245
    /** Registers a hierarchy listener for receiving event notifications.
246
     * @param listener Object that implements {@link Listener} interface.
247
     */
248
    public void addHierarchyListener(MDRChangeListener listener) {
249
        _getMdrStorage().getEventNotifier().CLASS.addHierarchyListener(listener, this);
250
    }
244
    
251
    
245
    /** Removes listener from the list of objects registered for events notifications.
252
    /** Removes listener from the list of objects registered for events notifications.
246
     * @param listener Object that implements {@link Listener} interface.
253
     * @param listener Object that implements {@link Listener} interface.
(-)org/netbeans/mdr/handlers/PackageProxyHandler.java (+7 lines)
Lines 333-338 Link Here
333
    public void addListener(MDRChangeListener listener) {
333
    public void addListener(MDRChangeListener listener) {
334
        _getMdrStorage().getEventNotifier().PACKAGE.addListener(listener, this);
334
        _getMdrStorage().getEventNotifier().PACKAGE.addListener(listener, this);
335
    }
335
    }
336
337
    /** Registers a hierarchy listener for receiving event notifications.
338
     * @param listener Object that implements {@link Listener} interface.
339
     */
340
    public void addHierarchyListener(MDRChangeListener listener) {
341
        _getMdrStorage().getEventNotifier().PACKAGE.addHierarchyListener(listener, this);
342
    }
336
    
343
    
337
    /** Removes listener from the list of objects registered for events notifications.
344
    /** Removes listener from the list of objects registered for events notifications.
338
     * @param listener Object that implements {@link Listener} interface.
345
     * @param listener Object that implements {@link Listener} interface.
(-)org/netbeans/mdr/handlers/AssociationHandler.java (+7 lines)
Lines 310-315 Link Here
310
        _getMdrStorage().getEventNotifier().ASSOCIATION.addListener(listener, this);
310
        _getMdrStorage().getEventNotifier().ASSOCIATION.addListener(listener, this);
311
    }
311
    }
312
    
312
    
313
    /** Registers a hierarchy listener for receiving event notifications.
314
     * @param listener Object that implements {@link Listener} interface.
315
     */
316
    public void addHierarchyListener(MDRChangeListener listener) {
317
        _getMdrStorage().getEventNotifier().ASSOCIATION.addHierarchyListener(listener, this);
318
    }
319
    
313
    /** Removes listener from the list of objects registered for events notifications.
320
    /** Removes listener from the list of objects registered for events notifications.
314
     * @param listener Object that implements {@link Listener} interface.
321
     * @param listener Object that implements {@link Listener} interface.
315
     */
322
     */
(-)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.addHierarchyListener(this);
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 / +28 lines)
Lines 18-38 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>Listeners can be registered for events originating on the object the
23
 * listener is registered for by calling {@link #addListener(MDRChangeListener)}.
24
 * Listeners can also be registered for events originating on a hierarchy of
25
 * objects by calling {@link #addHierarchyListener(MDRChangeListener)}.</p>
26
 *
27
 * The repository should distribute all the events to hierarchy listeners in the following way:
22
 * <ul>
28
 * <ul>
23
 * <li>Each event fired on an instance is also fired on the corresponding class proxy for this instance.
29
 * <li>Each event fired on an instance are also propagated to the hierarchy listeners for the
24
 * <li>Events fired on a class proxy are propagated to its immediate package proxy.
30
 *        corresponding class proxy for this instance.
25
 * <li>Events fired on an association proxy are fired on all the instances affected by this event 
31
 * <li>Events fired on a class proxy are propagated to the hierarchy listeners
26
 * (e.g. instances added/removed from a link) and also it is fired on the immediate package proxy.
32
 *       for its immediate package proxy.
27
 * <li>Each event fired on a package proxy are propagated to its immediate package proxy.
33
 * <li>Events fired on an association proxy are propagated to the hierarchy listeners on
28
 * If the package proxy is outermost, the event is propagated to the MDRepository that contains
34
 *    the instances affected by this event (e.g. instances added/removed from a link)
29
 * the proxy.
35
 * and also it is propagated to the hierarchy listeners on the immediate package proxy.
36
 * <li>Each event fired on a package proxy is propagated to the hierarchy listeners
37
 * of its immediate package proxy. If the package proxy is outermost, the event is
38
 * propagated to the hierarchy listeners of the MDRepository that contains the proxy.
30
 * </ul>
39
 * </ul>
31
 * All the events are propagated recursively till they reach the repository object (e.g. each
40
 * All the events are propagated recursively to hierarchy listeners till they reach
41
 * the repository object (e.g. each
32
 * instance event is as a result of propagation always fired on the instance itself,
42
 * 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
43
 * 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
44
 * the immediate package proxy to the outermost package proxy and at the end on the repository containing
35
 * instance).<br>
45
 * instance - all hierarchy listeners in this chain of objects are informed about the
46
 * event, and 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 
47
 * 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
48
 * 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). 
49
 * class proxy and its instances - it receives each notification only once per event). 
Lines 40-49 Link Here
40
 * @author Martin Matula
51
 * @author Martin Matula
41
 */
52
 */
42
public interface MDRChangeSource {
53
public interface MDRChangeSource {
43
    /** Registers a listener for receiving event notifications.
54
    /** Registers a listener for receiving event notifications for this
55
     *  <code>MDRChangeSource</code>.
44
     * @param listener Object that implements {@link MDRChangeListener} interface.
56
     * @param listener Object that implements {@link MDRChangeListener} interface.
45
     */    
57
     */    
46
    public void addListener(MDRChangeListener listener);
58
    public void addListener(MDRChangeListener listener);
59
    /** Registers a listener for receiving event notifications for this
60
     *  <code>MDRChangeSource</code> and its children.
61
     * @param listener Object that implements {@link MDRChangeListener} interface.
62
     */    
63
    public void addHierarchyListener(MDRChangeListener listener);
47
    /** Removes listener from the list of objects registered for events notifications.
64
    /** Removes listener from the list of objects registered for events notifications.
48
     * @param listener Object that implements {@link MDRChangeListener} interface.
65
     * @param listener Object that implements {@link MDRChangeListener} interface.
49
     */    
66
     */    
(-)org/netbeans/mdr/NBMDRepositoryImpl.java (-3 / +13 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 135-140 Link Here
135
    public void addListener(MDRChangeListener listener) {
137
    public void addListener(MDRChangeListener listener) {
136
        initCheck();
138
        initCheck();
137
        mdrStorage.getEventNotifier().REPOSITORY.addListener(listener, mdrStorage);
139
        mdrStorage.getEventNotifier().REPOSITORY.addListener(listener, mdrStorage);
140
    }
141
    
142
    /** Registers a hierarchy listener for receiving event notifications.
143
     * @param listener Object that implements {@link Listener} interface.
144
     */
145
    public void addHierarchyListener(MDRChangeListener listener) {
146
        initCheck();
147
        mdrStorage.getEventNotifier().REPOSITORY.addHierarchyListener(listener, mdrStorage);
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