Skip to main content
summaryrefslogtreecommitdiffstats
blob: b8ba83927bf14b883d15d472f20e22b5b5fbcf57 (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
/*******************************************************************************
 *  Copyright (c) 2005, 2009 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  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()
	 */
	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)
	 */
	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()
     */
    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)
	 */
	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) {
                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, -1);
			}
			// 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