Skip to main content
summaryrefslogtreecommitdiffstats
blob: cb71acf5ac4b3eddf40b1af0dc9cf6b676181f37 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*******************************************************************************
 *  Copyright (c) 2005, 2009 IBM Corporation and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.ui.viewers.update;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.jface.viewers.Viewer;

/**
 * Default model proxy for a debug target.
 *
 * @since 3.2
 */
public class DebugTargetProxy extends EventHandlerModelProxy {

    private IDebugTarget fDebugTarget;

    public DebugTargetProxy(IDebugTarget target) {
        fDebugTarget = target;
    }

    /* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.update.EventHandlerModelProxy#dispose()
	 */
	@Override
	public synchronized void dispose() {
		super.dispose();
		fDebugTarget = null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.update.EventHandlerModelProxy#containsEvent(org.eclipse.debug.core.DebugEvent)
	 */
	@Override
	protected boolean containsEvent(DebugEvent event) {
        Object source = event.getSource();
        if (source instanceof IDebugElement) {
            IDebugTarget debugTarget = ((IDebugElement) source).getDebugTarget();
            // an expression can return null for debug target
            if (debugTarget != null) {
            	return debugTarget.equals(fDebugTarget);
            }
        }
        return false;
    }

    /* (non-Javadoc)
     * @see org.eclipse.debug.internal.ui.viewers.update.EventHandlerModelProxy#createEventHandlers()
     */
    @Override
	protected DebugEventHandler[] createEventHandlers() {
        ThreadEventHandler threadEventHandler = new ThreadEventHandler(this);
		return new DebugEventHandler[] { new DebugTargetEventHandler(this), threadEventHandler,
				new StackFrameEventHandler(this, threadEventHandler) };
    }

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy#installed(org.eclipse.jface.viewers.Viewer)
	 */
	@Override
	public void installed(Viewer viewer) {
		// select any thread that is already suspended after installation
		IDebugTarget target = fDebugTarget;
		if (target != null) {
			ModelDelta delta = getNextSuspendedThreadDelta(null, false);
			if (delta == null) {
                try {
                    ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
                    ILaunch launch = target.getLaunch();
                    int launchIndex = indexOf(manager.getLaunches(), target.getLaunch());
                    int targetIndex = indexOf(target.getLaunch().getChildren(), target);
                    delta = new ModelDelta(manager, IModelDelta.NO_CHANGE);
                    ModelDelta node = delta.addNode(launch, launchIndex, IModelDelta.NO_CHANGE, target.getLaunch().getChildren().length);
                    node = node.addNode(target, targetIndex, IModelDelta.EXPAND | IModelDelta.SELECT, target.getThreads().length);
                } catch (DebugException e) {
                    // In case of exception do not fire delta
                    return;
                }
			}
			// expand the target if no suspended thread
			fireModelChanged(delta);
		}
	}

    protected ModelDelta getNextSuspendedThreadDelta(IThread currentThread, boolean reverse) {
        IDebugTarget target = fDebugTarget;
        if (target != null) {
            try {
                IThread[] threads = target.getThreads();
                ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
                ILaunch launch = target.getLaunch();
                int launchIndex = indexOf(manager.getLaunches(), target.getLaunch());
                int targetIndex = indexOf(target.getLaunch().getChildren(), target);
                IThread chosen = null;
                int threadIndex = -1;
                // select the first thread with a breakpoint, or the first suspended thread
                // if none have breakpoints
                boolean takeNext = currentThread == null;
                int startIdx = reverse ? threads.length - 1 : 0;
                int endIdx = reverse ? -1 : threads.length;
                int increment = reverse ? -1 : 1;
                for (int i = startIdx; i != endIdx; i = i + increment) {
                    IThread thread = threads[i];
                    if (takeNext && thread.isSuspended()) {
                        IBreakpoint[] bps = thread.getBreakpoints();
                        if (bps != null && bps.length > 0) {
                            chosen = thread;
                            threadIndex = i;
                            break;
                        } else {
                            if (chosen == null) {
                                chosen = thread;
                                threadIndex = i;
                            }
                        }
                    }
                    takeNext = takeNext || thread.equals(currentThread);
                }
                if (chosen != null) {
                    IStackFrame frame = chosen.getTopStackFrame();
                    if (frame != null) {
                        ModelDelta delta = new ModelDelta(manager, IModelDelta.NO_CHANGE);
                        ModelDelta node = delta.addNode(launch, launchIndex, IModelDelta.NO_CHANGE, target.getLaunch().getChildren().length);
                        node = node.addNode(target, targetIndex, IModelDelta.NO_CHANGE, threads.length);
                        node = node.addNode(chosen, threadIndex, IModelDelta.NO_CHANGE | IModelDelta.EXPAND, chosen.getStackFrames().length);
                        node = node.addNode(frame, 0, IModelDelta.NO_CHANGE | IModelDelta.SELECT, 0);
                        return delta;
                    }
                }
            } catch (DebugException e) {
            }
        }
        return null;
    }

}

Back to the top