Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2014-04-30 05:27:17 -0400
committerUwe Stieber2014-04-30 05:27:17 -0400
commit3d81a4ed3563d0d14b160b07a0775678123c52ff (patch)
tree2e16ce595a28e716b6682660726fdcbd3e0990c7
parent779d4193705266a0d5d8bb8ccac892aebfcfbbf6 (diff)
downloadorg.eclipse.tcf-3d81a4ed3563d0d14b160b07a0775678123c52ff.tar.gz
org.eclipse.tcf-3d81a4ed3563d0d14b160b07a0775678123c52ff.tar.xz
org.eclipse.tcf-3d81a4ed3563d0d14b160b07a0775678123c52ff.zip
Target Explorer: Add handling of path map rules marked with ID="agent" to the path map service and unified code
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java61
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java56
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java169
3 files changed, 151 insertions, 135 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
index 3ff304057..adb769657 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
@@ -30,7 +30,6 @@ import org.eclipse.tcf.protocol.IPeer;
import org.eclipse.tcf.protocol.IToken;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.services.IPathMap;
-import org.eclipse.tcf.services.IPathMap.PathMapRule;
import org.eclipse.tcf.services.IStreams;
import org.eclipse.tcf.te.runtime.callback.Callback;
import org.eclipse.tcf.te.runtime.interfaces.IDisposable;
@@ -96,60 +95,18 @@ public final class ChannelManager extends PlatformObject implements IChannelMana
final IPathMapService service = ServiceManager.getInstance().getService(peer, IPathMapService.class);
final IPathMap svc = channel.getRemoteService(IPathMap.class);
if (service != null && svc != null) {
- // Get the configured path maps
- final AtomicReference<PathMapRule[]> configuredMap = new AtomicReference<PathMapRule[]>();
- // The runnable to execute within the TCF event dispatch thread once
- // the configured path map has been retrieved from the launch configuration.
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- if (configuredMap.get() != null && configuredMap.get().length > 0) {
- // 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 e, PathMapRule[] map) {
- // Merge the maps to a new list
- List<PathMapRule> rules = new ArrayList<PathMapRule>();
-
- if (map != null && map.length > 0) {
- for (PathMapRule rule : map) {
- if (rule.getID() == null || !(!rule.getID().startsWith(service.getClientID()) && !"Agent".equals(rule.getID()))) { //$NON-NLS-1$
- rules.add(rule);
- }
- }
- }
-
- for (PathMapRule rule : configuredMap.get()) {
- if (IPathMapService.PATHMAP_PROTOCOL_HOST_TO_TARGET.equals(rule.getProtocol())) continue;
- rules.add(rule);
- }
-
- if (!rules.isEmpty()) {
- svc.set(rules.toArray(new PathMapRule[rules.size()]), new IPathMap.DoneSet() {
- @Override
- public void doneSet(IToken token, Exception e) {
- done.doneOpenChannel(error, channel);
- }
- });
- } else {
- done.doneOpenChannel(error, channel);
- }
- }
- });
- } else {
- done.doneOpenChannel(error, channel);
- }
- }
- };
-
- // Getting the path map from the launch configuration must happen
- // outside the TCF dispatch thread as it may trigger the launch
- // configuration change listeners.
+ // Apply the initial path map to the opened channel.
+ // This must happen outside the TCF dispatch thread as it may trigger
+ // the launch configuration change listeners.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
- configuredMap.set(service.getPathMap(peer));
- Protocol.invokeLater(runnable);
+ service.applyPathMap(peer, new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ done.doneOpenChannel(error, channel);
+ }
+ });
}
});
thread.start();
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 576764463..8b46fe0ef 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,10 +9,8 @@
*******************************************************************************/
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;
@@ -35,6 +33,7 @@ import org.eclipse.tcf.te.runtime.utils.StatusHelper;
import org.eclipse.tcf.te.tcf.core.Tcf;
import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager;
import org.eclipse.tcf.te.tcf.core.interfaces.IPathMapGeneratorService;
+import org.eclipse.tcf.te.tcf.launch.core.internal.services.PathMapService;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
/**
@@ -150,7 +149,7 @@ public final class Launch extends TCFLaunch {
* @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) {
+ protected void applyPathMap(final IChannel channel, final PathMapRule[] configuredMap, 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
@@ -161,54 +160,25 @@ public final class Launch extends TCFLaunch {
// 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<PathMapRule> rules = new ArrayList<PathMapRule>();
-
- if (oldMap != null && oldMap.length > 0) {
- for (PathMapRule rule : oldMap) {
- if (rule.getID() == null || (!rule.getID().startsWith(clientID) && !"Agent".equals(rule.getID()))) { //$NON-NLS-1$
- 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<PathMapRule> copy = new ArrayList<PathMapRule>(rules);
- for (PathMapRule rule : oldMap) {
- Iterator<PathMapRule> 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);
+ public void doneGet(IToken token, Exception error, PathMapRule[] map) {
+ // Merge the path maps
+ List<PathMapRule> rules = PathMapService.mergePathMaps(clientID, map, configuredMap);
+
+ // If the merged path map differs from the agent side path map, apply the map
+ if (PathMapService.isDifferent(rules, map)) {
+ // Apply the path map
+ PathMapService.set(rules, svc, done);
} else {
- done.doneSet(token, null);
+ done.doneSet(null, null);
}
}
});
+
} else {
done.doneSet(null, null);
}
} else {
- super.applyPathMap(channel, map, done);
+ super.applyPathMap(channel, configuredMap, done);
}
}
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 60450b6b0..df979efa0 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.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
@@ -94,7 +95,11 @@ public class PathMapService extends AbstractService implements IPathMapService {
if (!rulesList.isEmpty()) {
int cnt = 0;
String id = getClientID();
- for (PathMapRule r : rulesList) r.getProperties().put(IPathMap.PROP_ID, id + "/" + cnt++); //$NON-NLS-1$
+ for (PathMapRule r : rulesList) {
+ if (r.getProperties().get(IPathMap.PROP_ID) == null) {
+ r.getProperties().put(IPathMap.PROP_ID, id + "/" + cnt++); //$NON-NLS-1$
+ }
+ }
rules = rulesList.toArray(new PathMapRule[rulesList.size()]);
}
} finally {
@@ -331,46 +336,13 @@ public class PathMapService extends AbstractService implements IPathMapService {
svc.get(new IPathMap.DoneGet() {
@Override
public void doneGet(IToken token, Exception error, PathMapRule[] map) {
- // Merge the maps to a new list
- List<PathMapRule> rules = new ArrayList<PathMapRule>();
-
- if (map != null && map.length > 0) {
- for (PathMapRule rule : map) {
- if (rule.getID() == null || (!rule.getID().startsWith(getClientID()) && !"Agent".equals(rule.getID()))) { //$NON-NLS-1$
- rules.add(rule);
- }
- }
- }
-
- for (PathMapRule rule : configuredMap) {
- if (IPathMapService.PATHMAP_PROTOCOL_HOST_TO_TARGET.equals(rule.getProtocol())) continue;
- rules.add(rule);
- }
-
- // 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<PathMapRule> copy = new ArrayList<PathMapRule>(rules);
- for (PathMapRule rule : map) {
- Iterator<PathMapRule> iter = copy.iterator();
- while (iter.hasNext()) {
- PathMapRule r = iter.next();
- if (r.equals(rule)) {
- iter.remove();
- break;
- }
- }
- }
+ // Merge the path maps
+ List<PathMapRule> rules = mergePathMaps(getClientID(), map, configuredMap);
- 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() {
+ // If the merged path map differs from the agent side path map, apply the map
+ if (isDifferent(rules, map)) {
+ // Apply the path map
+ set(rules, svc, new IPathMap.DoneSet() {
@Override
public void doneSet(IToken token, Exception error) {
callback.done(PathMapService.this, StatusHelper.getStatus(error));
@@ -399,6 +371,123 @@ public class PathMapService extends AbstractService implements IPathMapService {
}
}
+ /**
+ * Merge the given agent and client side path maps.
+ *
+ * @param clientID The current client ID. Must not be <code>null</code>.
+ * @param agentSidePathMap The agent side path map or <code>null</code>.
+ * @param clientSidePathMap The client side path map. Must not be <code>null</code>.
+ *
+ * @return The merged path map.
+ */
+ public static List<PathMapRule> mergePathMaps(String clientID, PathMapRule[] agentSidePathMap, PathMapRule[] clientSidePathMap) {
+ Assert.isNotNull(clientID);
+ Assert.isNotNull(clientSidePathMap);
+
+ // Merge the maps to a new list
+ List<PathMapRule> rules = new ArrayList<PathMapRule>();
+ // The map of agent side path map rules
+ List<PathMapRule> agentSideRules = new ArrayList<PathMapRule>();
+
+ if (agentSidePathMap != null && agentSidePathMap.length > 0) {
+ for (PathMapRule rule : agentSidePathMap) {
+ if (rule.getID() == null || (!rule.getID().startsWith(clientID) && !"agent".equalsIgnoreCase(rule.getID()))) { //$NON-NLS-1$
+ rules.add(rule);
+ } else if ("agent".equalsIgnoreCase(rule.getID())) { //$NON-NLS-1$
+ agentSideRules.add(rule);
+ }
+ }
+ }
+
+ for (PathMapRule rule : clientSidePathMap) {
+ if (IPathMapService.PATHMAP_PROTOCOL_HOST_TO_TARGET.equals(rule.getProtocol())) continue;
+ // If the configured rule matches an agent side path map rule, ignore the configured rule
+ // and add the agent side rule
+ boolean addRule = true;
+ Map<String, Object> m1 = new HashMap<String, Object>(rule.getProperties());
+ m1.remove(IPathMap.PROP_ID);
+ for (PathMapRule agentSideRule : agentSideRules) {
+ Map<String, Object> m2 = new HashMap<String, Object>(agentSideRule.getProperties());
+ m2.remove(IPathMap.PROP_ID);
+ if (m1.equals(m2)) {
+ rules.add(agentSideRule);
+ addRule = false;
+ break;
+ }
+ }
+ // Add the configured rule
+ if (addRule) rules.add(rule);
+ }
+
+ return rules;
+ }
+
+ /**
+ * Returns if or if not the given merged path map is different from the given agent
+ * side path map.
+ *
+ * @param mergedPathMap The merged path map. Must not be <code>null</code>.
+ * @param agentSidePathMap The agent side path map or <code>null</code>.
+ *
+ * @return <code>True</code> if the merged path map is different, <code>false</code> if not.
+ */
+ public static boolean isDifferent(List<PathMapRule> mergedPathMap, PathMapRule[] agentSidePathMap) {
+ Assert.isNotNull(mergedPathMap);
+
+ boolean changed = agentSidePathMap != null ? agentSidePathMap.length != mergedPathMap.size() : !mergedPathMap.isEmpty();
+ if (!changed && !mergedPathMap.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<PathMapRule> copy = new ArrayList<PathMapRule>(mergedPathMap);
+ for (PathMapRule rule : agentSidePathMap) {
+ Iterator<PathMapRule> iter = copy.iterator();
+ while (iter.hasNext()) {
+ PathMapRule r = iter.next();
+ if (r.equals(rule)) {
+ iter.remove();
+ break;
+ }
+ }
+ }
+
+ changed = !copy.isEmpty();
+ }
+
+ return changed;
+ }
+
+ /**
+ * Set the given path map.
+ * <p>
+ * <b>Note:</b> This method must be called from within the TCF dispatch thread.
+ *
+ * @param map The path map. Must not be <code>null</code>.
+ * @param svc The path map service. Must not be <code>null</code>.
+ * @param done The callback to invoke. Must not be <code>null</code>.
+ */
+ public static void set(List<PathMapRule> map, IPathMap svc, IPathMap.DoneSet done) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
+ Assert.isNotNull(map);
+ Assert.isNotNull(svc);
+ Assert.isNotNull(done);
+
+ // Get rid of the agent side rules before applying the rules for real
+ Iterator<PathMapRule> iter = map.iterator();
+ while (iter.hasNext()) {
+ PathMapRule rule = iter.next();
+ if ("agent".equalsIgnoreCase(rule.getID())) { //$NON-NLS-1$
+ iter.remove();
+ }
+ }
+ // Apply the path map rules if not empty
+ if (!map.isEmpty()) {
+ svc.set(map.toArray(new PathMapRule[map.size()]), done);
+ } else {
+ done.doneSet(null, null);
+ }
+ }
+
/* (non-Javadoc)
* @see org.eclipse.tcf.te.tcf.core.interfaces.IPathMapService#getClientID()
*/

Back to the top