Lines 1-411
Link Here
|
1 |
/** |
|
|
2 |
* Copyright (c) 2003,2008 Craig Setera and others. |
3 |
* |
4 |
* All rights reserved. This program and the accompanying materials |
5 |
* are made available under the terms of the Eclipse Public License v1.0 |
6 |
* which accompanies this distribution, and is available at |
7 |
* http://www.eclipse.org/legal/epl-v10.html |
8 |
* |
9 |
* Contributors: |
10 |
* Craig Setera (EclipseME) - Initial implementation |
11 |
* Diego Sandin (Motorola) - Refactoring package name to follow eclipse |
12 |
* standards |
13 |
* Gang Ma (Sybase) - Moving debugger settings verification to a |
14 |
* more appropriate location |
15 |
*/ |
16 |
package org.eclipse.mtj.ui.internal.launching; |
17 |
|
18 |
import java.lang.reflect.InvocationTargetException; |
19 |
import java.util.ArrayList; |
20 |
import java.util.Collections; |
21 |
import java.util.HashSet; |
22 |
import java.util.List; |
23 |
import java.util.Set; |
24 |
|
25 |
import org.eclipse.core.resources.IResource; |
26 |
import org.eclipse.core.runtime.CoreException; |
27 |
import org.eclipse.core.runtime.IProgressMonitor; |
28 |
import org.eclipse.core.runtime.IStatus; |
29 |
import org.eclipse.core.runtime.SubProgressMonitor; |
30 |
import org.eclipse.debug.core.DebugPlugin; |
31 |
import org.eclipse.debug.core.ILaunchConfiguration; |
32 |
import org.eclipse.debug.core.ILaunchConfigurationType; |
33 |
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
34 |
import org.eclipse.debug.core.ILaunchManager; |
35 |
import org.eclipse.debug.ui.DebugUITools; |
36 |
import org.eclipse.debug.ui.IDebugModelPresentation; |
37 |
import org.eclipse.debug.ui.IDebugUIConstants; |
38 |
import org.eclipse.debug.ui.ILaunchShortcut; |
39 |
import org.eclipse.jdt.core.IClassFile; |
40 |
import org.eclipse.jdt.core.ICompilationUnit; |
41 |
import org.eclipse.jdt.core.IJavaElement; |
42 |
import org.eclipse.jdt.core.IType; |
43 |
import org.eclipse.jdt.core.JavaCore; |
44 |
import org.eclipse.jdt.core.JavaModelException; |
45 |
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
46 |
import org.eclipse.jdt.ui.JavaElementLabelProvider; |
47 |
import org.eclipse.jface.dialogs.ErrorDialog; |
48 |
import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
49 |
import org.eclipse.jface.operation.IRunnableWithProgress; |
50 |
import org.eclipse.jface.viewers.ISelection; |
51 |
import org.eclipse.jface.viewers.IStructuredSelection; |
52 |
import org.eclipse.mtj.core.internal.MTJCorePlugin; |
53 |
import org.eclipse.mtj.core.internal.utils.Utils; |
54 |
import org.eclipse.mtj.core.launching.ILaunchConstants; |
55 |
import org.eclipse.mtj.ui.internal.MTJUIPlugin; |
56 |
import org.eclipse.swt.widgets.Shell; |
57 |
import org.eclipse.ui.IEditorInput; |
58 |
import org.eclipse.ui.IEditorPart; |
59 |
import org.eclipse.ui.IWorkbenchWindow; |
60 |
import org.eclipse.ui.dialogs.ElementListSelectionDialog; |
61 |
|
62 |
|
63 |
/** |
64 |
* Emulator launch shortcut implementation. |
65 |
* |
66 |
* @author Craig Setera |
67 |
*/ |
68 |
public class EmulatorLaunchShortcut implements ILaunchShortcut { |
69 |
|
70 |
/** |
71 |
* Default constructor. |
72 |
*/ |
73 |
public EmulatorLaunchShortcut() { |
74 |
super(); |
75 |
} |
76 |
|
77 |
/** |
78 |
* @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, |
79 |
* java.lang.String) |
80 |
*/ |
81 |
public void launch(ISelection selection, String mode) { |
82 |
if (selection instanceof IStructuredSelection) { |
83 |
launch(((IStructuredSelection) selection).toArray(), mode); |
84 |
} |
85 |
} |
86 |
|
87 |
/** |
88 |
* @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, |
89 |
* java.lang.String) |
90 |
*/ |
91 |
public void launch(IEditorPart editor, String mode) { |
92 |
IEditorInput input = editor.getEditorInput(); |
93 |
IJavaElement javaElement = (IJavaElement) input |
94 |
.getAdapter(IJavaElement.class); |
95 |
if (javaElement != null) { |
96 |
launch(new Object[] { javaElement }, mode); |
97 |
} |
98 |
} |
99 |
|
100 |
/** |
101 |
* Show a selection dialog that allows the user to choose one of the |
102 |
* specified launch configurations. Return the chosen config, or |
103 |
* <code>null</code> if the user canceled the dialog. |
104 |
*/ |
105 |
private ILaunchConfiguration chooseConfiguration(List configList, |
106 |
String mode) { |
107 |
IDebugModelPresentation labelProvider = DebugUITools |
108 |
.newDebugModelPresentation(); |
109 |
ElementListSelectionDialog dialog = new ElementListSelectionDialog( |
110 |
getShell(), labelProvider); |
111 |
dialog.setElements(configList.toArray()); |
112 |
dialog.setTitle("Launch configuration"); |
113 |
dialog.setMessage("Select launch configuration"); |
114 |
dialog.setMultipleSelection(false); |
115 |
|
116 |
int result = dialog.open(); |
117 |
labelProvider.dispose(); |
118 |
if (result == ElementListSelectionDialog.OK) { |
119 |
return (ILaunchConfiguration) dialog.getFirstResult(); |
120 |
} |
121 |
return null; |
122 |
} |
123 |
|
124 |
/** |
125 |
* Prompts the user to select a type |
126 |
* |
127 |
* @return the selected type or <code>null</code> if none. |
128 |
*/ |
129 |
private IType chooseType(IType[] types, String mode) { |
130 |
IType selectedType = null; |
131 |
|
132 |
ElementListSelectionDialog dialog = new ElementListSelectionDialog( |
133 |
getShell(), new JavaElementLabelProvider()); |
134 |
dialog.setElements(types); |
135 |
dialog.setTitle("Type Selection"); |
136 |
|
137 |
if (mode.equals(ILaunchManager.DEBUG_MODE)) { |
138 |
dialog.setMessage("Select the midlet to be debugged."); |
139 |
} else { |
140 |
dialog.setMessage("Select the midlet to be run."); |
141 |
} |
142 |
|
143 |
dialog.setMultipleSelection(false); |
144 |
if (dialog.open() == ElementListSelectionDialog.OK) { |
145 |
selectedType = (IType) dialog.getFirstResult(); |
146 |
} |
147 |
|
148 |
return selectedType; |
149 |
} |
150 |
|
151 |
/** |
152 |
* Collect up the MIDlet types related to the specified object. |
153 |
* |
154 |
* @param object |
155 |
* @param monitor |
156 |
* @param result |
157 |
* @throws JavaModelException |
158 |
*/ |
159 |
private void collectTypes(Object object, IProgressMonitor monitor, |
160 |
Set result) throws JavaModelException { |
161 |
IType type = null; |
162 |
|
163 |
if (object instanceof ICompilationUnit) { |
164 |
IType[] types = ((ICompilationUnit) object).getAllTypes(); |
165 |
for (int i = 0; i < types.length; i++) { |
166 |
collectTypes(types[i], monitor, result); |
167 |
} |
168 |
} else if (object instanceof IClassFile) { |
169 |
type = ((IClassFile) object).getType(); |
170 |
} else if (object instanceof IJavaElement) { |
171 |
type = (IType) ((IJavaElement) object) |
172 |
.getAncestor(IJavaElement.TYPE); |
173 |
} else if (object instanceof IResource) { |
174 |
collectTypes(JavaCore.create((IResource) object), monitor, result); |
175 |
} |
176 |
|
177 |
if (type != null) { |
178 |
if (Utils.isMidlet(type, monitor)) { |
179 |
result.add(type); |
180 |
} |
181 |
} |
182 |
} |
183 |
|
184 |
/** |
185 |
* Create & return a new configuration based on the specified |
186 |
* <code>IType</code>. |
187 |
*/ |
188 |
private ILaunchConfiguration createConfiguration(IType type) { |
189 |
ILaunchConfiguration config = null; |
190 |
try { |
191 |
ILaunchConfigurationType configType = getEmulatorConfigType(); |
192 |
|
193 |
String launchConfigName = DebugPlugin.getDefault() |
194 |
.getLaunchManager() |
195 |
.generateUniqueLaunchConfigurationNameFrom( |
196 |
type.getElementName()); |
197 |
ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, |
198 |
launchConfigName); |
199 |
|
200 |
wc.setAttribute(ILaunchConstants.EMULATED_CLASS, Utils |
201 |
.getQualifiedClassName(type)); |
202 |
wc.setAttribute( |
203 |
IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, type |
204 |
.getJavaProject().getElementName()); |
205 |
wc.setAttribute(ILaunchConstants.DO_OTA, false); |
206 |
|
207 |
DebugUITools.setLaunchPerspective(configType, |
208 |
ILaunchManager.RUN_MODE, |
209 |
IDebugUIConstants.PERSPECTIVE_DEFAULT); |
210 |
DebugUITools.setLaunchPerspective(configType, |
211 |
ILaunchManager.DEBUG_MODE, |
212 |
IDebugUIConstants.PERSPECTIVE_DEFAULT); |
213 |
|
214 |
config = wc.doSave(); |
215 |
|
216 |
} catch (CoreException ce) { |
217 |
MTJCorePlugin.log(IStatus.WARNING, "createConfiguration", ce); |
218 |
} |
219 |
|
220 |
return config; |
221 |
} |
222 |
|
223 |
/** |
224 |
* Locate a configuration to re-launch for the given type. If one cannot be |
225 |
* found, create one. |
226 |
* |
227 |
* @return a re-usable config or <code>null</code> if none |
228 |
*/ |
229 |
private ILaunchConfiguration findLaunchConfiguration(IType type, String mode) { |
230 |
ILaunchConfiguration configuration = null; |
231 |
List candidateConfigs = getCandidateConfigs(type); |
232 |
|
233 |
// If there are no existing configs associated with the IType, create |
234 |
// one. |
235 |
// If there is exactly one config associated with the IType, return it. |
236 |
// Otherwise, if there is more than one config associated with the |
237 |
// IType, prompt the |
238 |
// user to choose one. |
239 |
int candidateCount = candidateConfigs.size(); |
240 |
if (candidateCount < 1) { |
241 |
configuration = createConfiguration(type); |
242 |
} else if (candidateCount == 1) { |
243 |
configuration = (ILaunchConfiguration) candidateConfigs.get(0); |
244 |
} else { |
245 |
// Prompt the user to choose a config. A null result means the user |
246 |
// canceled the dialog, in which case this method returns null, |
247 |
// since canceling the dialog should also cancel launching |
248 |
// anything. |
249 |
ILaunchConfiguration config = chooseConfiguration(candidateConfigs, |
250 |
mode); |
251 |
if (config != null) { |
252 |
configuration = config; |
253 |
} |
254 |
} |
255 |
|
256 |
return configuration; |
257 |
} |
258 |
|
259 |
/** |
260 |
* Get the candidate launch configurations for the specified type. |
261 |
* |
262 |
* @param type |
263 |
* @return |
264 |
*/ |
265 |
private List getCandidateConfigs(IType type) { |
266 |
ILaunchConfigurationType configType = getEmulatorConfigType(); |
267 |
List candidateConfigs = Collections.EMPTY_LIST; |
268 |
try { |
269 |
ILaunchConfiguration[] configs = DebugPlugin.getDefault() |
270 |
.getLaunchManager().getLaunchConfigurations(configType); |
271 |
candidateConfigs = new ArrayList(configs.length); |
272 |
for (int i = 0; i < configs.length; i++) { |
273 |
ILaunchConfiguration config = configs[i]; |
274 |
String midletName = config.getAttribute( |
275 |
ILaunchConstants.EMULATED_CLASS, ""); |
276 |
String projectName = config |
277 |
.getAttribute( |
278 |
IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, |
279 |
""); |
280 |
|
281 |
if (midletName.equals(Utils.getQualifiedClassName(type)) |
282 |
&& projectName.equals(type.getJavaProject() |
283 |
.getElementName())) { |
284 |
candidateConfigs.add(config); |
285 |
} |
286 |
} |
287 |
} catch (CoreException e) { |
288 |
MTJCorePlugin.log(IStatus.WARNING, "getCandidateConfigs", e); |
289 |
} |
290 |
|
291 |
return candidateConfigs; |
292 |
} |
293 |
|
294 |
/** |
295 |
* Get the launch configuration type for wireless toolkit emulator. |
296 |
* |
297 |
* @return |
298 |
*/ |
299 |
private ILaunchConfigurationType getEmulatorConfigType() { |
300 |
ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); |
301 |
ILaunchConfigurationType configType = lm |
302 |
.getLaunchConfigurationType(ILaunchConstants.LAUNCH_CONFIG_TYPE); |
303 |
return configType; |
304 |
} |
305 |
|
306 |
/** |
307 |
* Find all of the IType instances related to the specified selection. |
308 |
* |
309 |
* @param selection |
310 |
* @return |
311 |
*/ |
312 |
private IType[] findTypes(final Object[] selection) { |
313 |
final Set result = new HashSet(); |
314 |
|
315 |
if (selection.length > 0) { |
316 |
IRunnableWithProgress runnable = getTypeCollectionRunnable( |
317 |
selection, result); |
318 |
|
319 |
try { |
320 |
new ProgressMonitorDialog(getShell()).run(true, true, runnable); |
321 |
} catch (InvocationTargetException e) { |
322 |
MTJCorePlugin.log(IStatus.WARNING, "findTypes", e); |
323 |
} catch (InterruptedException e) { |
324 |
// Ignore |
325 |
} |
326 |
} |
327 |
|
328 |
return (IType[]) result.toArray(new IType[result.size()]); |
329 |
} |
330 |
|
331 |
/** |
332 |
* Get the runnable to be used in collecting IType instances. |
333 |
* |
334 |
* @param selection |
335 |
* @param result |
336 |
* @return |
337 |
*/ |
338 |
private IRunnableWithProgress getTypeCollectionRunnable( |
339 |
final Object[] selection, final Set result) { |
340 |
return new IRunnableWithProgress() { |
341 |
public void run(IProgressMonitor pm) throws InterruptedException { |
342 |
int nElements = selection.length; |
343 |
pm.beginTask("Searching", nElements); |
344 |
try { |
345 |
for (int i = 0; i < nElements; i++) { |
346 |
try { |
347 |
collectTypes(selection[i], new SubProgressMonitor( |
348 |
pm, 1), result); |
349 |
} catch (JavaModelException e) { |
350 |
MTJCorePlugin.log(IStatus.WARNING, "collectTypes", |
351 |
e); |
352 |
} |
353 |
if (pm.isCanceled()) { |
354 |
throw new InterruptedException(); |
355 |
} |
356 |
} |
357 |
} finally { |
358 |
pm.done(); |
359 |
} |
360 |
} |
361 |
}; |
362 |
} |
363 |
|
364 |
/** |
365 |
* Get the active workbench window's shell. |
366 |
* |
367 |
* @return |
368 |
*/ |
369 |
private Shell getShell() { |
370 |
Shell shell = null; |
371 |
|
372 |
IWorkbenchWindow workbenchWindow = MTJUIPlugin.getDefault() |
373 |
.getWorkbench().getActiveWorkbenchWindow(); |
374 |
if (workbenchWindow != null) { |
375 |
shell = workbenchWindow.getShell(); |
376 |
} |
377 |
|
378 |
return shell; |
379 |
} |
380 |
|
381 |
/** |
382 |
* Attempt to find and launch the objects in the selection. |
383 |
* |
384 |
* @param selection |
385 |
* @param mode |
386 |
*/ |
387 |
private void launch(Object[] selection, String mode) { |
388 |
IType type = null; |
389 |
IType[] types = findTypes(selection); |
390 |
|
391 |
// Choose a type |
392 |
if (types.length == 1) { |
393 |
type = types[0]; |
394 |
} else if (types.length > 1) { |
395 |
type = chooseType(types, mode); |
396 |
} |
397 |
|
398 |
if (type != null) { |
399 |
ILaunchConfiguration config = findLaunchConfiguration(type, mode); |
400 |
if (config != null) { |
401 |
try { |
402 |
config.launch(mode, null); |
403 |
} catch (CoreException e) { |
404 |
ErrorDialog.openError(getShell(), "Error Launching " |
405 |
+ config.getName(), e.getMessage(), e.getStatus()); |
406 |
} |
407 |
} |
408 |
|
409 |
} |
410 |
} |
411 |
} |