From 5e1cb0caed52d984280f4888456f6a98188284f8 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Mon, 21 Oct 2013 10:28:36 +0200 Subject: TCF Debugger: Fix launch overwrites path map rules set by other clients on the same channel. This changes applies to the "Remote Debug" launch configuration type only. Behavior of the "Target Communication Launch" launch configuration type is unchanged.--- .../tcf/te/tcf/launch/core/delegates/Launch.java | 71 ++++++++++++++++++++++ .../core/internal/services/PathMapService.java | 26 +++++++- 2 files changed, 96 insertions(+), 1 deletion(-) (limited to 'target_explorer') diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java index 4424b0f00..d48ec0682 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java @@ -9,8 +9,10 @@ *******************************************************************************/ package org.eclipse.tcf.te.tcf.launch.core.delegates; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -20,6 +22,9 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.tcf.internal.debug.model.TCFLaunch; import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.protocol.IToken; +import org.eclipse.tcf.services.IPathMap; +import org.eclipse.tcf.services.IPathMap.DoneSet; import org.eclipse.tcf.services.IPathMap.PathMapRule; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.properties.PropertiesContainer; @@ -102,6 +107,72 @@ public final class Launch extends TCFLaunch { } } + /* (non-Javadoc) + * @see org.eclipse.tcf.internal.debug.model.TCFLaunch#applyPathMap(org.eclipse.tcf.protocol.IChannel, org.eclipse.tcf.services.IPathMap.PathMapRule[], org.eclipse.tcf.services.IPathMap.DoneSet) + */ + @Override + protected void applyPathMap(final IChannel channel, final PathMapRule[] map, final DoneSet done) { + // Get the client ID + final String clientID = getClientID(); + // If we have a client ID, we can identify path map rules set by other clients + // and leave them alone. Otherwise, just set the path map. + if (clientID != null) { + final IPathMap svc = getService(IPathMap.class); + if (svc != null) { + // Get the old path maps first. Keep path map rules not coming from us + svc.get(new IPathMap.DoneGet() { + @Override + public void doneGet(IToken token, Exception error, PathMapRule[] oldMap) { + // Merge the maps to a new list + List rules = new ArrayList(); + + if (oldMap != null && oldMap.length > 0) { + for (PathMapRule rule : oldMap) { + if (rule.getID() == null || !rule.getID().startsWith(clientID)) { + rules.add(rule); + } + } + } + + rules.addAll(Arrays.asList(map)); + + // Determine if the map has changed + boolean changed = oldMap != null ? oldMap.length != rules.size() : !rules.isEmpty(); + if (!changed && !rules.isEmpty()) { + // Make a copy of new map and remove all rules listed + // by the old map. If not empty at the end, the new map + // is different from the old map. + List copy = new ArrayList(rules); + for (PathMapRule rule : oldMap) { + Iterator iter = copy.iterator(); + while (iter.hasNext()) { + PathMapRule r = iter.next(); + if (r.equals(rule)) { + iter.remove(); + break; + } + } + } + + changed = !copy.isEmpty(); + } + + // If the path map has changed, apply the map + if (changed) { + svc.set(rules.toArray(new PathMapRule[rules.size()]), done); + } else { + done.doneSet(token, null); + } + } + }); + } else { + done.doneSet(null, null); + } + } else { + super.applyPathMap(channel, map, done); + } + } + /* (non-Javadoc) * @see org.eclipse.debug.core.Launch#getAdapter(java.lang.Class) */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java index 6679182bb..423ed62a5 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java @@ -11,6 +11,7 @@ package org.eclipse.tcf.te.tcf.launch.core.internal.services; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -340,7 +341,30 @@ public class PathMapService extends AbstractService implements IPathMapService { } rules.addAll(Arrays.asList(configuredMap)); - if (!rules.isEmpty()) { + + // Determine if the map has changed + boolean changed = map != null ? map.length != rules.size() : !rules.isEmpty(); + if (!changed && !rules.isEmpty()) { + // Make a copy of new map and remove all rules listed + // by the old map. If not empty at the end, the new map + // is different from the old map. + List copy = new ArrayList(rules); + for (PathMapRule rule : map) { + Iterator iter = copy.iterator(); + while (iter.hasNext()) { + PathMapRule r = iter.next(); + if (r.equals(rule)) { + iter.remove(); + break; + } + } + } + + changed = !copy.isEmpty(); + } + + // If the path map has changed, apply the map + if (changed) { svc.set(rules.toArray(new PathMapRule[rules.size()]), new IPathMap.DoneSet() { @Override public void doneSet(IToken token, Exception error) { -- cgit v1.2.3