1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.eclipse.pdt.internal;
18 
19 import com.android.ide.eclipse.ddms.IDebuggerConnector;
20 
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.debug.core.DebugPlugin;
24 import org.eclipse.debug.core.ILaunchConfiguration;
25 import org.eclipse.debug.core.ILaunchConfigurationType;
26 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
27 import org.eclipse.debug.core.ILaunchManager;
28 import org.eclipse.debug.ui.DebugUITools;
29 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
30 
31 import java.util.HashMap;
32 import java.util.Map;
33 
34 /**
35  * Implementation of the com.android.ide.ddms.debuggerConnector extension point.
36  */
37 public class DebuggerConnector extends DevTreeProjectProvider implements IDebuggerConnector {
38 
39     private final static String ATTR_CONNECT_MAP_PORT = "port"; //$NON-NLS-1$
40     private final static String ATTR_CONNECT_MAP_HOSTNAME = "hostname"; //$NON-NLS-1$
41 
42     @Override
isWorkspaceApp(String appName)43     public boolean isWorkspaceApp(String appName) {
44         return getProject() != null;
45     }
46 
47     @Override
connectDebugger(String appName, int appPort, int selectedPort)48     public boolean connectDebugger(String appName, int appPort, int selectedPort) {
49         IProject project = getProject();
50 
51         if (project != null) {
52             // get the launch manager
53             ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
54 
55             // get the config for the remote launch config.
56             ILaunchConfigurationType configType = manager.getLaunchConfigurationType(
57                             IJavaLaunchConfigurationConstants.ID_REMOTE_JAVA_APPLICATION);
58 
59             String projectName = project.getName();
60 
61             // look for an existing launch config
62             ILaunchConfiguration config = findConfig(manager, configType, projectName,
63                     selectedPort);
64 
65             if (config == null) {
66                 // Didn't find a matching config, so we make one.
67                 // It'll be made in the "working copy" object first.
68                 ILaunchConfigurationWorkingCopy wc = null;
69 
70                 try {
71                     // make the working copy object with a unique name
72                     wc = configType.newInstance(null,
73                             manager.generateUniqueLaunchConfigurationNameFrom(projectName));
74 
75                     // set the project name
76                     wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
77                             projectName);
78 
79                     // set the connect map info
80                     Map<String, String> connectMap = new HashMap<String, String>();
81                     connectMap.put(ATTR_CONNECT_MAP_PORT, Integer.toString(selectedPort));
82                     connectMap.put(ATTR_CONNECT_MAP_HOSTNAME, "localhost"); //$NON-NLS-1$
83                     wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, connectMap);
84 
85                     // set the VM connector ID
86                     wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR,
87                             IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR);
88 
89                     // save the working copy to get the launch config object which we return.
90                     config = wc.doSave();
91 
92                 } catch (CoreException e) {
93 
94                 }
95 
96             }
97 
98             if (config != null) {
99                 DebugUITools.launch(config, ILaunchManager.DEBUG_MODE);
100                 return true;
101             }
102         }
103 
104         return false;
105     }
106 
107     /**
108      * Looks for and returns an existing {@link ILaunchConfiguration} object for a
109      * specified project and connection port.
110      * @param manager The {@link ILaunchManager}.
111      * @param type The {@link ILaunchConfigurationType}.
112      * @param projectName The name of the project
113      * @param connectionPort the remote connection port.
114      * @return an existing <code>ILaunchConfiguration</code> object matching the project, or
115      *      <code>null</code>.
116      */
findConfig(ILaunchManager manager, ILaunchConfigurationType type, String projectName, int connectionPort)117     private static ILaunchConfiguration findConfig(ILaunchManager manager,
118             ILaunchConfigurationType type,
119             String projectName, int connectionPort) {
120         try {
121             ILaunchConfiguration[] configs = manager.getLaunchConfigurations(type);
122 
123             // look for one set up for the project with a debug equal to the selected debug port.
124             for (ILaunchConfiguration config : configs) {
125 
126                 Map<?, ?> attributes = config.getAttributes();
127 
128                 String name = (String) attributes.get(
129                         IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME);
130 
131                 if (name == null || name.equals(projectName) == false) {
132                     continue;
133                 }
134 
135                 Map<?, ?> connectMap = (Map<?, ?>) attributes.get(
136                         IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP);
137 
138                 if (connectMap != null) {
139                     String portStr = (String) connectMap.get(ATTR_CONNECT_MAP_PORT);
140                     if (portStr != null) {
141                         Integer port = Integer.valueOf(portStr);
142                         if (connectionPort == port) {
143                             return config;
144                         }
145                     }
146                 }
147 
148             }
149         } catch (CoreException e) {
150         }
151 
152         // didn't find anything that matches. Return null
153         return null;
154     }
155 }
156