diff options
Diffstat (limited to 'plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java')
-rw-r--r-- | plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java new file mode 100644 index 000000000..ecf35cb11 --- /dev/null +++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 org.eclipse.tm.internal.tcf.debug.launch; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.LaunchConfigurationDelegate; +import org.eclipse.tm.internal.tcf.debug.Activator; +import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants; +import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch; +import org.eclipse.tm.internal.tcf.debug.model.TCFMemoryRegion; +import org.eclipse.tm.tcf.protocol.JSON; +import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.services.IMemoryMap; +import org.eclipse.tm.tcf.services.IPathMap; +import org.eclipse.tm.tcf.util.TCFTask; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +public class TCFLaunchDelegate extends LaunchConfigurationDelegate { + + public static final String + ATTR_PEER_ID = ITCFConstants.ID_TCF_DEBUG_MODEL + ".PeerID", + ATTR_PROJECT_NAME = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProjectName", + ATTR_LOCAL_PROGRAM_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".LocalProgramFile", + ATTR_REMOTE_PROGRAM_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProgramFile", + ATTR_COPY_TO_REMOTE_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".CopyToRemote", + ATTR_PROGRAM_ARGUMENTS = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProgramArguments", + ATTR_WORKING_DIRECTORY = ITCFConstants.ID_TCF_DEBUG_MODEL + ".WorkingDirectory", + ATTR_ATTACH_CHILDREN = ITCFConstants.ID_TCF_DEBUG_MODEL + ".AttachChildren", + ATTR_DISCONNECT_ON_CTX_EXIT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".DisconnectOnCtxExit", + ATTR_USE_TERMINAL = ITCFConstants.ID_TCF_DEBUG_MODEL + ".UseTerminal", + ATTR_RUN_LOCAL_AGENT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".RunLocalAgent", + ATTR_USE_LOCAL_AGENT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".UseLocalAgent", + ATTR_SIGNALS_DONT_STOP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".SignalsDontStop", + ATTR_SIGNALS_DONT_PASS = ITCFConstants.ID_TCF_DEBUG_MODEL + ".SignalsDontPath", + ATTR_PATH_MAP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".PathMap", + ATTR_MEMORY_MAP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".MemoryMap"; + + public static class PathMapRule implements IPathMap.PathMapRule { + + private final Map<String,Object> props; + + public PathMapRule(Map<String,Object> props) { + this.props = props; + } + + public Map<String,Object> getProperties() { + return props; + } + + public String getID() { + return (String)props.get(IPathMap.PROP_ID); + } + + public String getSource() { + return (String)props.get(IPathMap.PROP_SOURCE); + } + + public String getDestination() { + return (String)props.get(IPathMap.PROP_DESTINATION); + } + + public String getHost() { + return (String)props.get(IPathMap.PROP_HOST); + } + + public String getProtocol() { + return (String)props.get(IPathMap.PROP_PROTOCOL); + } + + public String toString() { + StringBuffer bf = new StringBuffer(); + for (String nm : props.keySet()) { + Object o = props.get(nm); + if (o != null) { + bf.append(nm); + bf.append('='); + String s = o.toString(); + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + if (ch >= ' ' && ch != '|' && ch != '\\') { + bf.append(ch); + } + else { + bf.append('\\'); + bf.append((int)ch); + bf.append(';'); + } + } + bf.append('|'); + } + } + bf.append('|'); + return bf.toString(); + } + } + + /** + * Given value of ATTR_PATH_MAP, return array of PathMapRule objects. + * @param s - value of ATTR_PATH_MAP. + * @return array of PathMapRule objects. + */ + public static ArrayList<PathMapRule> parsePathMapAttribute(String s) { + ArrayList<PathMapRule> map = new ArrayList<PathMapRule>(); + StringBuffer bf = new StringBuffer(); + int i = 0; + while (i < s.length()) { + PathMapRule e = new PathMapRule(new HashMap<String,Object>()); + while (i < s.length()) { + char ch = s.charAt(i++); + if (ch == '|') { + map.add(e); + break; + } + bf.setLength(0); + bf.append(ch); + while (i < s.length()) { + ch = s.charAt(i++); + if (ch == '=') break; + bf.append(ch); + } + String nm = bf.toString(); + bf.setLength(0); + while (i < s.length()) { + ch = s.charAt(i++); + if (ch == '|') { + if (bf.length() > 0) e.props.put(nm, bf.toString()); + break; + } + else if (ch == '\\') { + int n = 0; + while (i < s.length()) { + char d = s.charAt(i++); + if (d == ';') break; + n = n * 10 + (d - '0'); + } + bf.append((char)n); + } + else { + bf.append(ch); + } + } + } + } + return map; + } + + /** + * Given value of ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, + * return array of PathMapRule objects. + * @param s - value of ATTR_PATH_MAP. + * @return array of PathMapRule objects. + */ + public static ArrayList<PathMapRule> parseSourceLocatorMemento(String s) throws CoreException { + ArrayList<PathMapRule> map = new ArrayList<PathMapRule>(); + if (s == null || s.length() == 0) return map; + Element root = DebugPlugin.parseDocument(s); + NodeList list = root.getChildNodes(); + int length = list.getLength(); + for (int i = 0; i < length; i++) { + Node node = list.item(i); + short type = node.getNodeType(); + if (type == Node.ELEMENT_NODE) { + Element entry = (Element)node; + if (entry.getNodeName().equalsIgnoreCase("sourceContainers")) { + parseSourceContainers(map, entry); + } + } + } + return map; + } + + private static void parseSourceContainers(ArrayList<PathMapRule> map, Element element) throws CoreException { + NodeList list = element.getChildNodes(); + int length = list.getLength(); + for (int i = 0; i < length; i++) { + Node node = list.item(i); + short type = node.getNodeType(); + if (type == Node.ELEMENT_NODE) { + Element entry = (Element)node; + String memento = entry.getAttribute("memento"); + if (memento != null && memento.length() > 0) readSourceContainer(map, memento); + } + } + } + + private static void readSourceContainer(ArrayList<PathMapRule> map, String s) throws CoreException { + Element root = DebugPlugin.parseDocument(s); + if ("mapping".equals(root.getNodeName())) { + NodeList list = root.getChildNodes(); + int length = list.getLength(); + for (int i = 0; i < length; i++) { + Node node = list.item(i); + short type = node.getNodeType(); + if (type == Node.ELEMENT_NODE) { + Element entry = (Element)node; + if (entry.getNodeName().equalsIgnoreCase("mapEntry")) { + String memento = entry.getAttribute("memento"); + if (memento != null && memento.length() > 0) { + Element map_entry = DebugPlugin.parseDocument(memento); + String src = map_entry.getAttribute("backendPath"); + String dst = map_entry.getAttribute("localPath"); + if (src != null) src = src.replace('\\', '/'); + PathMapRule e = new PathMapRule(new HashMap<String,Object>()); + e.props.put(IPathMap.PROP_SOURCE, src); + e.props.put(IPathMap.PROP_DESTINATION, dst); + map.add(e); + } + } + } + } + } + } + + /** + * Given value of ATTR_MEMORY_MAP, add lists of TCFMemoryRegion objects into 'maps'. + * @param maps - Map object to fill with memory maps. + * @param s - value of ATTR_MEMORY_MAP. + */ + @SuppressWarnings("unchecked") + public static void parseMemMapsAttribute(Map<String,ArrayList<IMemoryMap.MemoryRegion>> maps, String s) throws Exception { + if (s == null || s.length() == 0) return; + Collection<Map<String,Object>> list = (Collection<Map<String,Object>>)JSON.parseOne(s.getBytes("UTF-8")); + if (list == null) return; + for (Map<String,Object> map : list) { + String id = (String)map.get(IMemoryMap.PROP_ID); + if (id != null) { + ArrayList<IMemoryMap.MemoryRegion> l = maps.get(id); + if (l == null) { + l = new ArrayList<IMemoryMap.MemoryRegion>(); + maps.put(id, l); + } + l.add(new TCFMemoryRegion(map)); + } + } + } + + /** + * Read ATTR_MEMORY_MAP attribute of a launch configuration. + * @param maps - Map object to fill with memory maps. + * @param cfg - the launch configuration. + * @throws Exception + */ + public static void getMemMapsAttribute(Map<String,ArrayList<IMemoryMap.MemoryRegion>> maps, + ILaunchConfiguration cfg) throws Exception { + String maps_cfg = cfg.getAttribute(ATTR_MEMORY_MAP, (String)null); + parseMemMapsAttribute(maps, maps_cfg); + } + + /** + * Given project name and program name returns absolute path of the program. + * @param project_name - workspace project name. + * @param program_name - launch program name. + * @return program path or null if both project name and program name are null. + */ + public static String getProgramPath(String project_name, String program_name) { + if (program_name == null || program_name.length() == 0) return null; + if (project_name == null || project_name.length() == 0) { + File file = new File(program_name); + if (!file.isAbsolute()) { + File ws = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile(); + file = new File(ws, program_name); + } + return file.getAbsolutePath(); + } + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(project_name); + IPath program_path = new Path(program_name); + if (!program_path.isAbsolute()) { + if (project == null || !project.getFile(program_name).exists()) return null; + program_path = project.getFile(program_name).getLocation(); + } + return program_path.toOSString(); + } + + /** + * Create new TCF launch object. + * @return new TCFLaunch object + */ + public ILaunch getLaunch(final ILaunchConfiguration configuration, final String mode) throws CoreException { + return new TCFTask<ILaunch>() { + int cnt; + public void run() { + // Need to delay at least one dispatch cycle to work around + // a possible racing between thread that calls getLaunch() and + // the process of activation of other TCF plug-ins. + if (cnt++ < 2) Protocol.invokeLater(this); + else done(new TCFLaunch(configuration, mode)); + } + }.getE(); + } + + /** + * Launch TCF session. + */ + public void launch(final ILaunchConfiguration configuration, final String mode, + final ILaunch launch, final IProgressMonitor monitor) throws CoreException { + String local_id = null; + int task_cnt = 1; + if (configuration.getAttribute(ATTR_RUN_LOCAL_AGENT, false)) { + task_cnt++; + if (monitor != null) monitor.beginTask("Starting TCF Agent", task_cnt); //$NON-NLS-1$ + local_id = TCFLocalAgent.runLocalAgent(); + } + else if (configuration.getAttribute(ATTR_USE_LOCAL_AGENT, true)) { + task_cnt++; + if (monitor != null) monitor.beginTask("Searching TCF Agent", task_cnt); //$NON-NLS-1$ + local_id = TCFLocalAgent.getLocalAgentID(); + if (local_id == null) throw new CoreException(new Status(IStatus.ERROR, + Activator.PLUGIN_ID, 0, + "Cannot find TCF agent on the local host", + null)); + } + if (monitor != null) monitor.beginTask("Launching TCF debugger session", task_cnt); //$NON-NLS-1$ + final String id = + configuration.getAttribute(ATTR_USE_LOCAL_AGENT, true) ? + local_id : configuration.getAttribute(ATTR_PEER_ID, ""); + Protocol.invokeLater(new Runnable() { + public void run() { + ((TCFLaunch)launch).launchTCF(mode, id); + if (monitor != null) monitor.done(); + } + }); + } +} |