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 235565
Collapse All | Expand All

(-)a/spi.debugger.ui/manifest.mf (-1 / +1 lines)
Lines 2-7 Link Here
2
OpenIDE-Module: org.netbeans.spi.debugger.ui/1
2
OpenIDE-Module: org.netbeans.spi.debugger.ui/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/debugger/ui/Bundle.properties
4
OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/debugger/resources/mf-layer.xml
5
OpenIDE-Module-Specification-Version: 2.41
5
OpenIDE-Module-Specification-Version: 2.42
6
OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui
6
OpenIDE-Module-Provides: org.netbeans.spi.debugger.ui
7
OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class
7
OpenIDE-Module-Install: org/netbeans/modules/debugger/ui/DebuggerModule.class
(-)94c11ec6a4c3 (+626 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.spi.debugger.ui;
44
45
import java.awt.Image;
46
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
48
import java.beans.PropertyChangeSupport;
49
import java.lang.annotation.ElementType;
50
import java.lang.annotation.Retention;
51
import java.lang.annotation.RetentionPolicy;
52
import java.lang.annotation.Target;
53
import java.lang.ref.Reference;
54
import java.lang.ref.WeakReference;
55
import java.util.Collection;
56
import java.util.LinkedList;
57
import java.util.List;
58
import java.util.Set;
59
import java.util.prefs.Preferences;
60
import javax.swing.Action;
61
import javax.swing.Icon;
62
import org.netbeans.api.debugger.Breakpoint;
63
import org.netbeans.api.debugger.Session;
64
import org.netbeans.modules.debugger.ui.views.debugging.DebuggingViewComponent;
65
import org.netbeans.modules.debugger.ui.views.debugging.FiltersDescriptor;
66
import org.netbeans.modules.debugger.ui.views.debugging.FiltersDescriptor.FilterImpl;
67
import org.netbeans.modules.debugger.ui.views.debugging.FiltersDescriptor.FiltersAccessor;
68
import org.openide.windows.TopComponent;
69
70
/**
71
 * Debugging view component provider. The debugging view displays application threads.
72
 * Implement {@link DVSupport} and register under your session name to use
73
 * debugging view UI and register appropriate view models for path <session name>/DebuggingView.
74
 * 
75
 * @author Martin Entlicher
76
 * @since 2.42
77
 */
78
public final class DebuggingView {
79
    
80
    private final static DebuggingView INSTANCE = new DebuggingView();
81
    
82
    private Reference<DebuggingViewComponent> dvcRef = new WeakReference<DebuggingViewComponent>(null);
83
    
84
    private DebuggingView() {
85
        //this.dvc = DebuggingViewComponent.getInstance();
86
    }
87
    
88
    /**
89
     * Get the default implementation of debugging view provider.
90
     * @return the default instance of debugging view provider.
91
     */
92
    public static DebuggingView getDefault() {
93
        return INSTANCE;
94
    }
95
    
96
    private DebuggingViewComponent getDVC() {
97
        DebuggingViewComponent dvc;
98
        synchronized (this) {
99
            dvc = dvcRef.get();
100
            if (dvc == null) {
101
                dvc = DebuggingViewComponent.getInstance();
102
                dvcRef = new WeakReference<DebuggingViewComponent>(dvc);
103
            }
104
        }
105
        return dvc;
106
    }
107
    
108
    /**
109
     * Get the debugging view top component.
110
     * @return the {@link TopComponent} of the debugging view.
111
     */
112
    public TopComponent getViewTC() {
113
        return getDVC();
114
    }
115
    
116
    /**
117
     * Support for debugging view. The component tree is created from view models
118
     * registered under path &lt;session name&gt;/DebuggingView. But to fully
119
     * support the debugging view UI, additional information is necessary.
120
     * Implement this class to provide the additional information.
121
     * Debugging view is created for the given debugger session only when an
122
     * implementation of this class is found in the current session engine lookup.
123
     */
124
    public static abstract class DVSupport {
125
        
126
        /** Property name constant. */
127
        public static final String          PROP_THREAD_STARTED = "threadStarted";      // NOI18N
128
        /** Property name constant. */
129
        public static final String          PROP_THREAD_DIED = "threadDied";            // NOI18N
130
        /** Property name constant. */
131
        public static final String          PROP_THREAD_GROUP_ADDED = "threadGroupAdded";   // NOI18N
132
        /** Property name constant. */
133
        public static final String          PROP_THREAD_SUSPENDED = "threadSuspended";  // NOI18N
134
        /** Property name constant. */
135
        public static final String          PROP_THREAD_RESUMED = "threadResumed";      // NOI18N
136
        /** Property name constant. */
137
        public static final String          PROP_CURRENT_THREAD = "currentThread";      // NOI18N
138
139
        /**
140
         * Name of property which is fired when deadlock occurs.
141
         */
142
        public static final String          PROP_DEADLOCK = "deadlock";                 // NOI18N
143
        public static final String          PROP_STATE = "state";                       // NOI18N
144
145
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
146
        
147
        /**
148
         * The debugger state.
149
         */
150
        public static enum STATE {
151
            RUNNING,
152
            DISCONNECTED
153
        }
154
        
155
        static {
156
            FiltersDescriptor.getInstance().setFiltersAccessor(new FiltersAccessor() {
157
                @Override
158
                public List<DVFilter> getFilters(DVSupport dvs) {
159
                    return dvs.getFilters();
160
                }
161
                @Override
162
                public FilterImpl getImpl(DVFilter filter) {
163
                    return filter.getImpl();
164
                }
165
            });
166
        }
167
        
168
        protected DVSupport() {
169
        }
170
    
171
        /**
172
         * Get the debugger state.
173
         * @return current state of debugger
174
         */
175
        public abstract STATE getState();
176
        
177
        /**
178
         * Get listing of all threads at this moment.
179
         * @return list of all threads
180
         */
181
        public abstract List<DVThread> getAllThreads();
182
        
183
        /**
184
         * Get a current thread, if any.
185
         * @return a current thread, or <code>null</code>.
186
         */
187
        public abstract DVThread getCurrentThread();
188
        
189
        /**
190
         * Get the display name of the thread. It can contain more information
191
         * than a thread name, like current session name, etc.
192
         * @param thread the thread
193
         * @return the thread display name
194
         */
195
        public abstract String getDisplayName(DVThread thread);
196
        
197
        /**
198
         * Get the thread icon.
199
         * @param thread the thread
200
         * @return the thread icon
201
         */
202
        public abstract Image getIcon(DVThread thread);
203
204
        /**
205
         * Get the session associated with this debugging view.
206
         * @return 
207
         */
208
        public abstract Session getSession();
209
210
        /**
211
         * Resume the application (all it's threads).
212
         */
213
        public abstract void resume();
214
215
        /**
216
         * Get the set of detected deadlocks, if any.
217
         * @return The set of deadlocks, or <code>null</code> when no deadlocks are detected.
218
         */
219
        public abstract Set<Deadlock> getDeadlocks();
220
        
221
        /**
222
         * Utility method used by the implementing class to create deadlock description instances.
223
         * @param threads The threads in deadlock
224
         * @return Deadlock instance
225
         */
226
        protected final Deadlock createDeadlock(Collection<DVThread> threads) {
227
            return new Deadlock(threads);
228
        }
229
        
230
        /**
231
         * Get the list of filters applied to debugging view.
232
         * @return list of filters
233
         */
234
        protected abstract List<DVFilter> getFilters();
235
        
236
        /**
237
         * Get actions created from the provided filters.
238
         * The result can be added to actions provider view model.
239
         * @return filter actions.
240
         */
241
        public final Action[] getFilterActions() {
242
            return FiltersDescriptor.getInstance().getFilterActions();
243
        }
244
        
245
        protected final void firePropertyChange(PropertyChangeEvent pce) {
246
            pcs.firePropertyChange(pce);
247
        }
248
        
249
        /**
250
         * Fire a property change event.
251
         * @param propertyName the property name
252
         * @param oldValue old value
253
         * @param newValue new value
254
         */
255
        protected final void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
256
            pcs.firePropertyChange(propertyName, oldValue, newValue);
257
        }
258
        
259
        /**
260
         * Add a property change listener.
261
         * @param pcl the property change listener
262
         */
263
        public final void addPropertyChangeListener(PropertyChangeListener pcl) {
264
            pcs.addPropertyChangeListener(pcl);
265
        }
266
        
267
        /**
268
         * Remove a property change listener.
269
         * @param pcl the property change listener
270
         */
271
        public final void removePropertyChangeListener(PropertyChangeListener pcl) {
272
            pcs.removePropertyChangeListener(pcl);
273
        }
274
        
275
        /**
276
         * Declarative registration of a DVSupport implementation.
277
         * By marking the implementation class with this annotation,
278
         * you automatically register that implementation for use by the debugging view.
279
         * The class must be public and have a public constructor which takes
280
         * no arguments or takes {@link ContextProvider} as an argument.
281
         *
282
         * @author Martin Entlicher
283
         */
284
        @Retention(RetentionPolicy.SOURCE)
285
        @Target({ElementType.TYPE})
286
        public @interface Registration {
287
            /**
288
             * The path to register this implementation in.
289
             * Usually the session ID.
290
             */
291
            String path();
292
            
293
            /**
294
             * An optional position in which to register this service relative to others.
295
             * Lower-numbered services are returned in the lookup result first.
296
             * Services with no specified position are returned last.
297
             */
298
            int position() default Integer.MAX_VALUE;
299
300
        }
301
302
    }
303
    
304
    /**
305
     * Representation of a thread in debugging view.
306
     * Nodes representing a thread in debugging view model should implement this
307
     * interface.
308
     */
309
    public static interface DVThread {
310
        
311
        /**
312
         * Property name fired when a thread gets suspended.
313
         */
314
        public static final String PROP_SUSPENDED = "suspended";            // NOI18N
315
        /**
316
         * Property name fired when list of locker threads change.
317
         */
318
        public static final String PROP_LOCKER_THREADS = "lockerThreads";   // NOI18N
319
        /**
320
         * Property name fired when current breakpoint is changed.
321
         */
322
        public static final String PROP_BREAKPOINT = "currentBreakpoint";   // NOI18N
323
        
324
        /**
325
         * Get the name of the thread.
326
         * @return the name of the thread
327
         */
328
        public String getName();
329
        
330
        /**
331
         * Test if this thread is currently suspended by debugger.
332
         * @return <code>true</code> when the thread is suspended, <code>false</code> otherwise.
333
         */
334
        public boolean isSuspended();
335
        
336
        /**
337
         * Resume this thread.
338
         */
339
        public void resume();
340
341
        /**
342
         * Suspend this thread.
343
         */
344
        public void suspend();
345
        
346
        /**
347
         * Make this thread current. Code evaluation and stepping should be performed
348
         * in the current thread.
349
         */
350
        public void makeCurrent();
351
352
        /**
353
         * Get the debugging view support that provides this thread.
354
         * @return the debugging view support
355
         */
356
        public DVSupport getDVSupport();
357
358
        /**
359
         * Lists threads that hold monitors that this thread is waiting on.
360
         * @return list of locker threads
361
         */
362
        public List<DVThread> getLockerThreads();
363
        
364
        /**
365
         * Resume any suspended threads that block execution of this thread by holding monitors.
366
         */
367
        public void resumeBlockingThreads();
368
369
        /**
370
         * Get current breakpoint, if any. This is a breakpoint that this thread is suspended on.
371
         * @return the current breakpoint or <code>null</code>
372
         */
373
        public Breakpoint getCurrentBreakpoint();
374
        
375
        /**
376
         * Test if this thread is performing a step operation right now.
377
         * @return <code>true</code> if this thread is in a step, <code>false</code> otherwise.
378
         */
379
        public boolean isInStep();
380
381
        /**
382
         * Add a property change listener.
383
         * @param pcl the property change listener
384
         */
385
        public void addPropertyChangeListener(PropertyChangeListener pcl);
386
387
        /**
388
         * Remove a property change listener.
389
         * @param pcl the property change listener
390
         */
391
        public void removePropertyChangeListener(PropertyChangeListener pcl);
392
393
    }
394
    
395
    /**
396
     * Representation of a thread group in debugging view.
397
     * Nodes representing a thread group in debugging view model should implement
398
     * this interface.
399
     */
400
    public static interface DVThreadGroup {
401
        
402
        /**
403
         * Get the name of the thread group.
404
         * @return the name of the thread group
405
         */
406
        public String getName();
407
        
408
        /**
409
         * Get the parent thread group, if exists.
410
         * @return the parent thread group or <code>null</code> if this thread group has no parent (root thread group).
411
         */
412
        public DVThreadGroup getParentThreadGroup();
413
        
414
        /**
415
         * Get this thread group's threads.
416
         * @return threads from this thread group
417
         */
418
        public DVThread[] getThreads();
419
        
420
        /**
421
         * Get this thread group's thread groups.
422
         * @return thread groups from this thread group
423
         */
424
        public DVThreadGroup[] getThreadGroups();
425
    }
426
    
427
    /**
428
     * Representation of a deadlock - one set of mutually deadlocked threads.
429
     */
430
    public static final class Deadlock {
431
432
        private final Collection<DVThread> threads;
433
        
434
        private Deadlock(Collection<DVThread> threads) {
435
            this.threads = threads;
436
        }
437
        
438
        /**
439
         * Get the threads in deadlock.
440
         * @return The threads in deadlock.
441
         */
442
        public Collection<DVThread> getThreads() {
443
            return threads;
444
        }
445
    }
446
    
447
    /**
448
     * Boolean state filter that is applied to the debugging view.
449
     * It's icon is made visible in the debugging view bottom panel.
450
     */
451
    public static final class DVFilter {
452
453
        /**
454
         * Pre-defined default filters enumeration.
455
         */
456
        public static enum DefaultFilter {
457
            sortAlphabetic,
458
            sortSuspend,
459
            sortNatural,
460
            showQualifiedNames,
461
            showMonitors,
462
            showSystemThreads,
463
            showSuspendTable,
464
            showThreadGroups,
465
            showSuspendedThreadsOnly,
466
        }
467
        
468
        private static final Group sortGroup = new Group();
469
        
470
        /**
471
         * Get an instance of a default filter.
472
         * @param filter the default filter kind
473
         * @return filter implementation
474
         */
475
        public static DVFilter getDefault(DefaultFilter filter) {
476
            FilterImpl fimpl = FilterImpl.createDefault(filter);
477
            Group g;
478
            switch (filter) {
479
                case sortAlphabetic:
480
                case sortNatural:
481
                case sortSuspend:
482
                    g = sortGroup;
483
                    break;
484
                default:
485
                    g = null;
486
            }
487
            fimpl.setGroup(g);
488
            return new DVFilter(fimpl, g);
489
        }
490
        
491
        /**
492
         * Create a custom filter.
493
         * @param name name of the filter
494
         * @param displayName display name of the filter (visible in an action menu)
495
         * @param tooltip tool-tip of the filter
496
         * @param selectedIcon icon of the filter
497
         * @param valuePrefs preferences which are asked for the filter value
498
         * @param valuePrefKey key that is used to retrieve the filter value from preferences
499
         * @param isSelectedDefault whether the filter should be selected by default when preferences do not contain the value
500
         * @param group a filter group, can be <code>null</code>
501
         * @return implementation of the filter
502
         */
503
        public static DVFilter create(String name, String displayName,
504
                                      String tooltip, Icon selectedIcon,
505
                                      Preferences valuePrefs, String valuePrefKey,
506
                                      boolean isSelectedDefault, Group group) {
507
            FilterImpl fimpl = new FilterImpl(name, displayName, tooltip, selectedIcon,
508
                                              valuePrefs, valuePrefKey, isSelectedDefault);
509
            fimpl.setGroup(group);
510
            return new DVFilter(fimpl, group);
511
        }
512
        
513
        private final FilterImpl fimpl;
514
        private final Group group;
515
        
516
        DVFilter (FilterImpl fimpl, Group group) {
517
            this.fimpl = fimpl;
518
            this.group = group;
519
            group.add(this);
520
        }
521
522
        private FilterImpl getImpl() {
523
            return fimpl;
524
        }
525
        
526
        /**
527
         * Get the filter group.
528
         * @return the filter group, or <code>null</code> when the filter has no group
529
         */
530
        public Group getGroup() {
531
            return group;
532
        }
533
        
534
        /**
535
         * Get the filter name.
536
         * @return the filter name
537
         */
538
        public String getName() {
539
            return fimpl.getName();
540
        }
541
        
542
        /**
543
         * Get the filter display name.
544
         * @return the filter display name
545
         */
546
        public String getDisplayName() {
547
            return fimpl.getDisplayName();
548
        }
549
        
550
        /**
551
         * Get the filter tooltip.
552
         * @return the filter tooltip
553
         */
554
        public String getTooltip() {
555
            return fimpl.getTooltip();
556
        }
557
558
        /**
559
         * Get the filter icon.
560
         * @return the filter icon
561
         */
562
        public Icon getIcon() {
563
            return fimpl.getIcon();
564
        }
565
566
        /**
567
         * Test if the filter is selected.
568
         * @return whether the filter is selected right now
569
         */
570
        public boolean isSelected() {
571
            return fimpl.isSelected();
572
        }
573
        
574
        /**
575
         * Set the filter as selected/unselected.
576
         * @param state whether to select the filter
577
         */
578
        public void setSelected(boolean state) {
579
            fimpl.setSelected(state);
580
        }
581
        
582
        /**
583
         * Get the filter preferences.
584
         * @return the preferences of this filter
585
         */
586
        public Preferences getPreferences() {
587
            return fimpl.getPreferences();
588
        }
589
        
590
        /**
591
         * Get the preference key.
592
         * @return key that is used to retrieve the filter value from preferences
593
         */
594
        public String getPrefKey() {
595
            return fimpl.getPrefKey();
596
        }
597
        
598
        /**
599
         * The filter group.
600
         */
601
        public static final class Group {
602
            
603
            private final List<DVFilter> items = new LinkedList<DVFilter>();
604
            
605
            /**
606
             * Create a new empty group.
607
             */
608
            public Group() {
609
            }
610
            
611
            void add(DVFilter filter) {
612
                items.add(filter);
613
            }
614
            
615
            /**
616
             * Get list of filters in this group.
617
             * @return list of filters
618
             */
619
            public List<DVFilter> getItems() {
620
                return items;
621
            }
622
        }
623
        
624
    }
625
    
626
}

Return to bug 235565