Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/com.windriver.debug.tcf.core/src/com/windriver/debug/tcf/core/model/TCFBreakpointsModel.java')
-rw-r--r--plugins/com.windriver.debug.tcf.core/src/com/windriver/debug/tcf/core/model/TCFBreakpointsModel.java321
1 files changed, 321 insertions, 0 deletions
diff --git a/plugins/com.windriver.debug.tcf.core/src/com/windriver/debug/tcf/core/model/TCFBreakpointsModel.java b/plugins/com.windriver.debug.tcf.core/src/com/windriver/debug/tcf/core/model/TCFBreakpointsModel.java
new file mode 100644
index 000000000..a1998a9e2
--- /dev/null
+++ b/plugins/com.windriver.debug.tcf.core/src/com/windriver/debug/tcf/core/model/TCFBreakpointsModel.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package com.windriver.debug.tcf.core.model;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointListener;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.IBreakpointManagerListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+import com.windriver.debug.tcf.core.TCFCore;
+import com.windriver.tcf.api.protocol.IChannel;
+import com.windriver.tcf.api.protocol.IToken;
+import com.windriver.tcf.api.protocol.Protocol;
+import com.windriver.tcf.api.services.IBreakpoints;
+
+public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointManagerListener {
+
+ private static final String PROP_ID = "ID";
+ private final IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager();
+
+ private abstract class BreakpointUpdate implements Runnable {
+
+ private final ILaunch[] launches;
+ private final Map<String,Object> marker_attrs;
+ private final String marker_file;
+
+ IBreakpoints service;
+ IBreakpoints.DoneCommand done;
+ Map<String,Object> tcf_attrs;
+
+ @SuppressWarnings("unchecked")
+ BreakpointUpdate(IBreakpoint breakpoint) throws CoreException, IOException {
+ if (breakpoint == null) {
+ marker_attrs = null;
+ marker_file = null;
+ }
+ else {
+ marker_attrs = new HashMap<String,Object>(breakpoint.getMarker().getAttributes());
+ marker_file = getFilePath(breakpoint.getMarker().getResource());
+ }
+ launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
+ }
+
+ synchronized void exec() throws InterruptedException {
+ assert !Protocol.isDispatchThread();
+ Protocol.invokeLater(this);
+ wait();
+ }
+
+ public void run() {
+ if (marker_attrs != null) {
+ tcf_attrs = toBreakpointAttributes(marker_file, marker_attrs);
+ }
+ for (int i = 0; i < launches.length; i++) {
+ if (launches[i] instanceof TCFLaunch) {
+ TCFLaunch launch = (TCFLaunch)launches[i];
+ final IChannel channel = launch.getChannel();
+ if (channel == null) continue;
+ if (channel.getState() != IChannel.STATE_OPEN) continue;
+ service = channel.getRemoteService(IBreakpoints.class);
+ if (service == null) continue;
+ done = new IBreakpoints.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) channel.terminate(error);
+ }
+ };
+ update();
+ }
+ }
+ Protocol.sync(new Runnable() {
+ public void run() {
+ synchronized (BreakpointUpdate.this) {
+ BreakpointUpdate.this.notify();
+ }
+ }
+ });
+ };
+
+ abstract void update();
+ }
+
+ public TCFBreakpointsModel() {
+ bp_manager.addBreakpointListener(this);
+ bp_manager.addBreakpointManagerListener(this);
+ }
+
+ public void dispose() {
+ bp_manager.removeBreakpointListener(this);
+ bp_manager.removeBreakpointManagerListener(this);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void downloadBreakpoints(final IChannel channel, final Runnable done)
+ throws IOException, CoreException {
+ assert Protocol.isDispatchThread();
+ IBreakpoints service = channel.getRemoteService(IBreakpoints.class);
+ if (service != null) {
+ IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL);
+ if (arr != null && arr.length > 0) {
+ Map<String,Object>[] bps = new Map[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ IMarker marker = arr[i].getMarker();
+ String file = getFilePath(marker.getResource());
+ bps[i] = toBreakpointAttributes(file, marker.getAttributes());
+ }
+ service.set(bps, new IBreakpoints.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error == null) done.run();
+ else channel.terminate(error);
+ }
+ });
+ return;
+ }
+ }
+ Protocol.invokeLater(done);
+ }
+
+ public void breakpointManagerEnablementChanged(final boolean enabled) {
+ try {
+ IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL);
+ if (arr == null || arr.length == 0) return;
+ final Set<String> ids = new HashSet<String>();
+ for (int i = 0; i < arr.length; i++) {
+ IMarker marker = arr[i].getMarker();
+ Boolean b = marker.getAttribute(IBreakpoint.ENABLED, Boolean.FALSE);
+ if (!b.booleanValue()) continue;
+ ids.add(marker.getAttribute(
+ ITCFConstants.ID_TCF_DEBUG_MODEL + '.' + IBreakpoints.PROP_ID, (String)null));
+ }
+ if (ids.isEmpty()) return;
+ new BreakpointUpdate(null) {
+ @Override
+ void update() {
+ if (enabled) {
+ service.enable(ids.toArray(new String[ids.size()]), done);
+ }
+ else {
+ service.disable(ids.toArray(new String[ids.size()]), done);
+ }
+ }
+ }.exec();
+ }
+ catch (Throwable x) {
+ TCFCore.log("Unhandled exception in breakpoint listener", x);
+ }
+ }
+
+ private String getFilePath(IResource resource) throws IOException {
+ if (resource == ResourcesPlugin.getWorkspace().getRoot()) return null;
+ IPath p = resource.getRawLocation();
+ if (p == null) return null;
+ return p.toFile().getCanonicalPath();
+ }
+
+ public void breakpointAdded(IBreakpoint breakpoint) {
+ try {
+ if (!breakpoint.getModelIdentifier().equals(ITCFConstants.ID_TCF_DEBUG_MODEL)) return;
+ new BreakpointUpdate(breakpoint) {
+ @Override
+ void update() {
+ service.add(tcf_attrs, done);
+ }
+ }.exec();
+ }
+ catch (Throwable x) {
+ TCFCore.log("Unhandled exception in breakpoint listener", x);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Set<String> calcMarkerDeltaKeys(IMarker marker, IMarkerDelta delta) throws CoreException {
+ assert delta.getKind() == IResourceDelta.CHANGED;
+ Map<String,Object> m0 = delta.getAttributes();
+ Map<String,Object> m1 = marker.getAttributes();
+ Set<String> keys = new HashSet<String>();
+ if (m0 != null) keys.addAll(m0.keySet());
+ if (m1 != null) keys.addAll(m1.keySet());
+ for (Iterator<String> i = keys.iterator(); i.hasNext();) {
+ String key = i.next();
+ Object v0 = m0 != null ? m0.get(key) : null;
+ Object v1 = m1 != null ? m1.get(key) : null;
+ if (v0 instanceof String && ((String)v0).length() == 0) v0 = null;
+ if (v1 instanceof String && ((String)v1).length() == 0) v1 = null;
+ if (v0 instanceof Boolean && !((Boolean)v0).booleanValue()) v0 = null;
+ if (v1 instanceof Boolean && !((Boolean)v1).booleanValue()) v1 = null;
+ if ((v0 == null) != (v1 == null)) continue;
+ if (v0 != null && !v0.equals(v1)) continue;
+ i.remove();
+ }
+ return keys;
+ }
+
+ public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
+ try {
+ if (!breakpoint.getModelIdentifier().equals(ITCFConstants.ID_TCF_DEBUG_MODEL)) return;
+ final Set<String> s = calcMarkerDeltaKeys(breakpoint.getMarker(), delta);
+ if (s.isEmpty()) return;
+ new BreakpointUpdate(breakpoint) {
+ @Override
+ void update() {
+ if (s.size() == 1 && s.contains(IBreakpoint.ENABLED)) {
+ Boolean enabled = (Boolean)tcf_attrs.get(IBreakpoints.PROP_ENABLED);
+ if (enabled == null || !enabled.booleanValue()) {
+ service.disable(new String[]{ (String)tcf_attrs.get(PROP_ID) }, done);
+ }
+ else {
+ service.enable(new String[]{ (String)tcf_attrs.get(PROP_ID) }, done);
+ }
+ }
+ else {
+ service.change(tcf_attrs, done);
+ }
+ }
+ }.exec();
+ }
+ catch (Throwable x) {
+ TCFCore.log("Unhandled exception in breakpoint listener", x);
+ }
+ }
+
+ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
+ try {
+ if (!breakpoint.getModelIdentifier().equals(ITCFConstants.ID_TCF_DEBUG_MODEL)) return;
+ new BreakpointUpdate(breakpoint) {
+ @Override
+ void update() {
+ service.remove(new String[]{ (String)tcf_attrs.get(PROP_ID) }, done);
+ }
+ }.exec();
+ }
+ catch (Throwable x) {
+ TCFCore.log("Unhandled exception in breakpoint listener", x);
+ }
+ }
+
+ public Map<String,Object> toMarkerAttributes(Map<String,Object> p) {
+ assert Protocol.isDispatchThread();
+ Map<String,Object> m = new HashMap<String,Object>();
+ for (Iterator<Map.Entry<String,Object>> i = p.entrySet().iterator(); i.hasNext();) {
+ Map.Entry<String,Object> e = i.next();
+ String key = e.getKey();
+ Object val = e.getValue();
+ if (key.equals(IBreakpoints.PROP_ENABLED)) continue;
+ if (key.equals(IBreakpoints.PROP_FILE)) continue;
+ if (key.equals(IBreakpoints.PROP_LINE)) continue;
+ if (key.equals(IBreakpoints.PROP_COLUMN)) continue;
+ m.put(ITCFConstants.ID_TCF_DEBUG_MODEL + '.' + key, val);
+ }
+ Boolean enabled = (Boolean)p.get(IBreakpoints.PROP_ENABLED);
+ if (enabled == null) m.put(IBreakpoint.ENABLED, Boolean.FALSE);
+ else m.put(IBreakpoint.ENABLED, enabled);
+ m.put(IBreakpoint.REGISTERED, Boolean.TRUE);
+ m.put(IBreakpoint.PERSISTED, Boolean.TRUE);
+ m.put(IBreakpoint.ID, ITCFConstants.ID_TCF_DEBUG_MODEL);
+ String msg = "";
+ if (p.get(IBreakpoints.PROP_ADDRESS) != null) msg += p.get(IBreakpoints.PROP_ADDRESS);
+ m.put(IMarker.MESSAGE, "Breakpoint: " + msg);
+ Number line = (Number)p.get(IBreakpoints.PROP_LINE);
+ if (line != null) {
+ m.put(IMarker.LINE_NUMBER, Integer.toString(line.intValue() + 1));
+ Number column = (Number)p.get(IBreakpoints.PROP_COLUMN);
+ if (column != null) {
+ m.put(IMarker.CHAR_START, column.toString());
+ m.put(IMarker.CHAR_END, Integer.toString(column.intValue() + 1));
+ }
+ }
+ return m;
+ }
+
+ public Map<String,Object> toBreakpointAttributes(String file, Map<String,Object> p) {
+ assert Protocol.isDispatchThread();
+ Map<String,Object> m = new HashMap<String,Object>();
+ for (Iterator<Map.Entry<String,Object>> i = p.entrySet().iterator(); i.hasNext();) {
+ Map.Entry<String,Object> e = i.next();
+ String key = e.getKey();
+ Object val = e.getValue();
+ if (!key.startsWith(ITCFConstants.ID_TCF_DEBUG_MODEL)) continue;
+ m.put(key.substring(ITCFConstants.ID_TCF_DEBUG_MODEL.length() + 1), val);
+ }
+ Boolean enabled = (Boolean)p.get(IBreakpoint.ENABLED);
+ if (enabled != null && enabled.booleanValue() && bp_manager.isEnabled()) {
+ m.put(IBreakpoints.PROP_ENABLED, enabled);
+ }
+ if (file != null) {
+ m.put(IBreakpoints.PROP_FILE, file);
+ String line = (String)p.get(IMarker.LINE_NUMBER);
+ if (line != null) {
+ m.put(IBreakpoints.PROP_LINE, new Integer(Integer.parseInt(line) - 1));
+ String column = (String)p.get(IMarker.CHAR_START);
+ if (column != null) {
+ m.put(IBreakpoints.PROP_COLUMN, new Integer(column));
+ }
+ }
+ }
+ return m;
+ }
+}

Back to the top