001: package org.eclipse.pde.internal.junit.launcher;
002:
003: /*
004: * (c) Copyright IBM Corp. 2000, 2001.
005: * All Rights Reserved.
006: */
007:
008: import java.lang.reflect.InvocationTargetException;
009: import java.net.MalformedURLException;
010:
011: import org.eclipse.core.resources.IWorkspaceRoot;
012: import org.eclipse.core.resources.ResourcesPlugin;
013: import org.eclipse.core.runtime.CoreException;
014: import org.eclipse.core.runtime.IPath;
015: import org.eclipse.core.runtime.Path;
016: import org.eclipse.debug.core.ILaunchConfiguration;
017: import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
018: import org.eclipse.jdt.core.IClassFile;
019: import org.eclipse.jdt.core.ICompilationUnit;
020: import org.eclipse.jdt.core.IJavaElement;
021: import org.eclipse.jdt.core.IJavaModel;
022: import org.eclipse.jdt.core.IJavaProject;
023: import org.eclipse.jdt.core.ISourceReference;
024: import org.eclipse.jdt.core.IType;
025: import org.eclipse.jdt.core.JavaCore;
026: import org.eclipse.jdt.core.JavaModelException;
027: import org.eclipse.jdt.internal.junit.launcher.JUnitBaseLaunchConfiguration;
028: import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationTab;
029: import org.eclipse.jdt.internal.junit.launcher.TestSelectionDialog;
030: import org.eclipse.jdt.internal.junit.ui.JUnitPlugin;
031: import org.eclipse.jdt.internal.junit.util.TestSearchEngine;
032: import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
033: import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
034: import org.eclipse.jdt.ui.JavaElementLabelProvider;
035: import org.eclipse.jface.resource.ImageDescriptor;
036: import org.eclipse.jface.viewers.ILabelProvider;
037: import org.eclipse.pde.internal.junit.ui.JUnitPdePlugin;
038: import org.eclipse.swt.SWT;
039: import org.eclipse.swt.events.ModifyEvent;
040: import org.eclipse.swt.events.ModifyListener;
041: import org.eclipse.swt.events.SelectionAdapter;
042: import org.eclipse.swt.events.SelectionEvent;
043: import org.eclipse.swt.events.SelectionListener;
044: import org.eclipse.swt.graphics.Image;
045: import org.eclipse.swt.layout.GridData;
046: import org.eclipse.swt.layout.GridLayout;
047: import org.eclipse.swt.widgets.Button;
048: import org.eclipse.swt.widgets.Combo;
049: import org.eclipse.swt.widgets.Composite;
050: import org.eclipse.swt.widgets.DirectoryDialog;
051: import org.eclipse.swt.widgets.Label;
052: import org.eclipse.swt.widgets.Shell;
053: import org.eclipse.swt.widgets.Text;
054: import org.eclipse.ui.dialogs.ElementListSelectionDialog;
055: import org.eclipse.ui.dialogs.SelectionDialog;
056:
057: /**
058: * The JUnitPdeMainTab shows the project name, name of the test case and
059: * the name of the Eclipse application name.
060: */
061: public class JUnitPdeMainTab extends JUnitLaunchConfigurationTab {
062:
063: public static final String RT_WORKSPACE = "runtime-test-workspace";
064:
065: // Project UI widgets
066: private Label fProjLabel;
067: private Text fProjText;
068: private Button fProjButton;
069: private Button fKeepRunning;
070: private Button fDeleteWorkspace;
071:
072: // Test class UI widgets
073: private Label fTestLabel;
074: private Text fTestText;
075: private Button fSearchButton;
076:
077: // Application to launch
078: private Combo fApplicationName;
079:
080: private final Image fTestIcon = createImage("obj16/test.gif"); //$NON-NLS-1$
081: private Text fWorkspaceLocation;
082:
083: /**
084: * @see ILaunchConfigurationTab#createControl(Composite)
085: */
086: public void createControl(Composite parent) {
087: Composite comp = new Composite(parent, SWT.NONE);
088: setControl(comp);
089: GridLayout topLayout = new GridLayout();
090: topLayout.numColumns = 2;
091: comp.setLayout(topLayout);
092:
093: new Label(comp, SWT.NONE);
094:
095: createProjectControls(comp);
096: createTestControls(comp);
097:
098: createSeparator(comp);
099:
100: createApplicationControls(comp);
101: createKeepRunningControls(comp);
102: createWorkspaceDataControls(comp);
103: }
104:
105: public void createSeparator(Composite comp) {
106: GridData gd;
107: Label label = new Label(comp, SWT.SEPARATOR | SWT.HORIZONTAL);
108: gd = new GridData();
109: gd.horizontalAlignment = GridData.FILL;
110: gd.horizontalSpan = 2;
111: label.setLayoutData(gd);
112: }
113:
114: public void createWorkspaceDataControls(Composite comp) {
115: GridData gd;
116: Label wslabel = new Label(comp, SWT.NULL);
117: wslabel.setText("Workspace data:");
118: gd = new GridData();
119: gd.horizontalSpan = 2;
120: wslabel.setLayoutData(gd);
121:
122: fWorkspaceLocation = new Text(comp, SWT.SINGLE | SWT.BORDER);
123: gd = new GridData();
124: gd.horizontalAlignment = GridData.FILL;
125: gd.horizontalSpan = 1;
126: fWorkspaceLocation.setLayoutData(gd);
127: fWorkspaceLocation.addModifyListener(new ModifyListener() {
128: public void modifyText(ModifyEvent evt) {
129: updateLaunchConfigurationDialog();
130: }
131: });
132:
133: Button browseButton = new Button(comp, SWT.PUSH);
134: browseButton.setText("B&rowse...");
135: setButtonGridData(browseButton);
136: browseButton.addSelectionListener(new SelectionAdapter() {
137: public void widgetSelected(SelectionEvent evt) {
138: handleBrowseButtonSelected();
139: }
140: });
141:
142: fDeleteWorkspace = new Button(comp, SWT.CHECK);
143: fDeleteWorkspace.addSelectionListener(new SelectionListener() {
144: public void widgetSelected(SelectionEvent e) {
145: updateLaunchConfigurationDialog();
146: }
147:
148: public void widgetDefaultSelected(SelectionEvent e) {
149: }
150: });
151:
152: fDeleteWorkspace
153: .setText("Clear test &workspace before launching");
154: gd = new GridData();
155: gd.horizontalAlignment = GridData.FILL;
156: gd.horizontalSpan = 2;
157: fDeleteWorkspace.setLayoutData(gd);
158: }
159:
160: public void createKeepRunningControls(Composite comp) {
161: GridData gd;
162: fKeepRunning = new Button(comp, SWT.CHECK);
163: fKeepRunning
164: .setText("&Keep JUnit running after a test run when debugging");
165: gd = new GridData();
166: gd.horizontalAlignment = GridData.FILL;
167: gd.horizontalSpan = 2;
168: fKeepRunning.setLayoutData(gd);
169: fKeepRunning.addSelectionListener(new SelectionListener() {
170: public void widgetSelected(SelectionEvent e) {
171: updateLaunchConfigurationDialog();
172: }
173:
174: public void widgetDefaultSelected(SelectionEvent e) {
175: }
176: });
177: }
178:
179: public void createApplicationControls(Composite comp) {
180: GridData gd;
181: Label appLabel = new Label(comp, SWT.NONE);
182: appLabel.setText("&Application Name:");
183: gd = new GridData();
184: gd.horizontalSpan = 2;
185: appLabel.setLayoutData(gd);
186:
187: fApplicationName = new Combo(comp, SWT.READ_ONLY);
188: gd = new GridData(GridData.FILL_HORIZONTAL);
189: fApplicationName.setLayoutData(gd);
190: fApplicationName
191: .setItems(JUnitPdeLaunchConfiguration.fgApplicationNames);
192:
193: fApplicationName.addModifyListener(new ModifyListener() {
194: public void modifyText(ModifyEvent evt) {
195: updateLaunchConfigurationDialog();
196: }
197: });
198: }
199:
200: public void createTestControls(Composite comp) {
201: GridData gd;
202: fTestLabel = new Label(comp, SWT.NONE);
203: fTestLabel.setText("T&est class:");
204: gd = new GridData();
205: gd.horizontalSpan = 2;
206: fTestLabel.setLayoutData(gd);
207:
208: fTestText = new Text(comp, SWT.SINGLE | SWT.BORDER);
209: gd = new GridData(GridData.FILL_HORIZONTAL);
210: fTestText.setLayoutData(gd);
211: fTestText.addModifyListener(new ModifyListener() {
212: public void modifyText(ModifyEvent evt) {
213: updateLaunchConfigurationDialog();
214: }
215: });
216:
217: fSearchButton = new Button(comp, SWT.PUSH);
218: fSearchButton.setText("&Search...");
219: setButtonGridData(fSearchButton);
220: fSearchButton.addSelectionListener(new SelectionAdapter() {
221: public void widgetSelected(SelectionEvent evt) {
222: handleSearchButtonSelected();
223: }
224: });
225: }
226:
227: public void createProjectControls(Composite comp) {
228: GridData gd;
229: fProjLabel = new Label(comp, SWT.NONE);
230: fProjLabel.setText("&Project:");
231: gd = new GridData();
232: gd.horizontalSpan = 2;
233: fProjLabel.setLayoutData(gd);
234:
235: fProjText = new Text(comp, SWT.SINGLE | SWT.BORDER);
236: gd = new GridData(GridData.FILL_HORIZONTAL);
237: fProjText.setLayoutData(gd);
238: fProjText.addModifyListener(new ModifyListener() {
239: public void modifyText(ModifyEvent evt) {
240: updateLaunchConfigurationDialog();
241: }
242: });
243:
244: fProjButton = new Button(comp, SWT.PUSH);
245: fProjButton.setText("&Browse....");
246: setButtonGridData(fProjButton);
247:
248: fProjButton.addSelectionListener(new SelectionAdapter() {
249: public void widgetSelected(SelectionEvent evt) {
250: handleProjectButtonSelected();
251: }
252: });
253: }
254:
255: /**
256: * @see ILaunchConfigurationTab#initializeFrom(ILaunchConfiguration)
257: */
258: public void initializeFrom(ILaunchConfiguration config) {
259: updateProjectFromConfig(config);
260: updateTestTypeFromConfig(config);
261: updateApplicationFromConfig(config);
262: updateKeepRunning(config);
263: updateDeleteWorkspace(config);
264: updateWorkspaceLocation(config);
265: }
266:
267: private void updateWorkspaceLocation(ILaunchConfiguration config) {
268: String workspaceLocation = "";
269: try {
270: workspaceLocation = config.getAttribute(
271: JUnitPdeLaunchConfiguration.WORKSPACE_ATTR, "");
272: } catch (CoreException ce) {
273: }
274: fWorkspaceLocation.setText(workspaceLocation);
275: }
276:
277: private void updateKeepRunning(ILaunchConfiguration config) {
278: boolean running = false;
279: try {
280: running = config.getAttribute(
281: JUnitBaseLaunchConfiguration.ATTR_KEEPRUNNING,
282: false);
283: } catch (CoreException ce) {
284: }
285: fKeepRunning.setSelection(running);
286: }
287:
288: private void updateDeleteWorkspace(ILaunchConfiguration config) {
289: boolean delete = true;
290: try {
291: delete = config.getAttribute(
292: JUnitPdeLaunchConfiguration.DELETE_WORKSPACE_ATTR,
293: true);
294: } catch (CoreException ce) {
295: }
296: fDeleteWorkspace.setSelection(delete);
297: }
298:
299: protected void updateProjectFromConfig(ILaunchConfiguration config) {
300: String projectName = "";
301: try {
302: projectName = config
303: .getAttribute(
304: IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
305: "");
306: } catch (CoreException ce) {
307: }
308: fProjText.setText(projectName);
309: }
310:
311: protected void updateTestTypeFromConfig(ILaunchConfiguration config) {
312: String testTypeName = "";
313: try {
314: testTypeName = config
315: .getAttribute(
316: IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
317: "");
318: } catch (CoreException ce) {
319: }
320: fTestText.setText(testTypeName);
321: }
322:
323: protected void updateApplicationFromConfig(
324: ILaunchConfiguration config) {
325: try {
326: String appName = config.getAttribute(
327: JUnitPdeLaunchConfiguration.APPLICATION_NAME_ATTR,
328: JUnitPdeLaunchConfiguration.fgDefaultApp);
329: selectApplicationName(appName);
330: } catch (CoreException ce) {
331: }
332: }
333:
334: private void selectApplicationName(String name) {
335: String[] items = fApplicationName.getItems();
336: for (int i = 0; i < items.length; i++) {
337: if (items[i].equals(name)) {
338: fApplicationName.select(i);
339: break;
340: }
341: }
342: }
343:
344: /**
345: * @see ILaunchConfigurationTab#performApply(ILaunchConfigurationWorkingCopy)
346: */
347: public void performApply(ILaunchConfigurationWorkingCopy config) {
348: config.setAttribute(
349: IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
350: (String) fProjText.getText());
351: config.setAttribute(
352: IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
353: (String) fTestText.getText());
354: String appName = fApplicationName.getItem(fApplicationName
355: .getSelectionIndex());
356: config.setAttribute(
357: JUnitPdeLaunchConfiguration.APPLICATION_NAME_ATTR,
358: appName);
359: config.setAttribute(
360: JUnitBaseLaunchConfiguration.ATTR_KEEPRUNNING,
361: fKeepRunning.getSelection());
362: config.setAttribute(
363: JUnitPdeLaunchConfiguration.DELETE_WORKSPACE_ATTR,
364: fDeleteWorkspace.getSelection());
365: config.setAttribute(JUnitPdeLaunchConfiguration.WORKSPACE_ATTR,
366: fWorkspaceLocation.getText());
367: }
368:
369: /**
370: * @see ILaunchConfigurationTab#dispose()
371: */
372: public void dispose() {
373: }
374:
375: /**
376: * Show a dialog that lists all main types
377: */
378: protected void handleSearchButtonSelected() {
379: Shell shell = getShell();
380:
381: IJavaProject javaProject = getJavaProject();
382:
383: //TO DO should not use the workbenchWindow as the runnable context
384: SelectionDialog dialog = new TestSelectionDialog(shell,
385: getLaunchConfigurationDialog(), javaProject);
386: dialog.setTitle("Test Selection");
387: dialog.setMessage("Choose a test case or test suite:");
388: if (dialog.open() == SelectionDialog.CANCEL) {
389: return;
390: }
391:
392: Object[] results = dialog.getResult();
393: if ((results == null) || (results.length < 1)) {
394: return;
395: }
396: IType type = (IType) results[0];
397: fTestText.setText(type.getFullyQualifiedName());
398: javaProject = type.getJavaProject();
399: fProjText.setText(javaProject.getElementName());
400: }
401:
402: protected void handleBrowseButtonSelected() {
403: IPath chosen = chooseWorkspaceLocation();
404: if (chosen != null) {
405: fWorkspaceLocation.setText(chosen.toOSString());
406: //TODO updateStatus();
407: }
408: }
409:
410: /**
411: * Browses for a workbench location.
412: */
413: private IPath chooseWorkspaceLocation() {
414: DirectoryDialog dialog = new DirectoryDialog(getControl()
415: .getShell());
416: dialog.setFilterPath(fWorkspaceLocation.getText());
417: dialog.setText("Workspace Location");
418: dialog.setMessage("Select Workspace Location");
419: String res = dialog.open();
420: if (res != null) {
421: return new Path(res);
422: }
423: return null;
424: }
425:
426: /**
427: * Show a dialog that lets the user select a project. This in turn provides
428: * context for the main type, allowing the user to key a main type name, or
429: * constraining the search for main types to the specified project.
430: */
431: protected void handleProjectButtonSelected() {
432: IJavaProject project = chooseJavaProject();
433: if (project == null) {
434: return;
435: }
436:
437: String projectName = project.getElementName();
438: fProjText.setText(projectName);
439: }
440:
441: /**
442: * Realize a Java Project selection dialog and return the first selected project,
443: * or null if there was none.
444: */
445: protected IJavaProject chooseJavaProject() {
446: IJavaProject[] projects;
447: try {
448: projects = JavaCore.create(getWorkspaceRoot())
449: .getJavaProjects();
450: } catch (JavaModelException e) {
451: JUnitPlugin.log(e.getStatus());
452: projects = new IJavaProject[0];
453: }
454:
455: ILabelProvider labelProvider = new JavaElementLabelProvider(
456: JavaElementLabelProvider.SHOW_DEFAULT);
457: ElementListSelectionDialog dialog = new ElementListSelectionDialog(
458: getShell(), labelProvider);
459: dialog.setTitle("Project Selection");
460: dialog
461: .setMessage("Choose a project to constrain the search for main types:");
462: dialog.setElements(projects);
463:
464: IJavaProject javaProject = getJavaProject();
465: if (javaProject != null) {
466: dialog.setInitialSelections(new Object[] { javaProject });
467: }
468: if (dialog.open() == ElementListSelectionDialog.OK) {
469: return (IJavaProject) dialog.getFirstResult();
470: }
471: return null;
472: }
473:
474: /**
475: * Return the IJavaProject corresponding to the project name in the project name
476: * text field, or null if the text does not match a project name.
477: */
478: protected IJavaProject getJavaProject() {
479: String projectName = fProjText.getText().trim();
480: if (projectName.length() < 1) {
481: return null;
482: }
483: return getJavaModel().getJavaProject(projectName);
484: }
485:
486: /**
487: * Convenience method to get the workspace root.
488: */
489: private IWorkspaceRoot getWorkspaceRoot() {
490: return ResourcesPlugin.getWorkspace().getRoot();
491: }
492:
493: /**
494: * Convenience method to get access to the java model.
495: */
496: private IJavaModel getJavaModel() {
497: return JavaCore.create(getWorkspaceRoot());
498: }
499:
500: /**
501: * @see ILaunchConfigurationTab#isValid(ILaunchConfiguration)
502: */
503: public boolean isValid(ILaunchConfiguration config) {
504: setErrorMessage(null);
505: setMessage(null);
506:
507: String name = fProjText.getText().trim();
508: if (name.length() > 0) {
509: if (!ResourcesPlugin.getWorkspace().getRoot().getProject(
510: name).exists()) {
511: setErrorMessage("Project does not exist.");
512: return false;
513: }
514: }
515:
516: name = fTestText.getText().trim();
517: if (name.length() == 0) {
518: setErrorMessage("Test not specified.");
519: return false;
520: }
521:
522: String workspace = fWorkspaceLocation.getText().trim();
523: if (workspace.length() == 0) {
524: setErrorMessage("Workspace location not specified.");
525: return false;
526: }
527:
528: return true;
529: }
530:
531: /**
532: * @see ILaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
533: */
534: public void setDefaults(ILaunchConfigurationWorkingCopy config) {
535: IJavaElement javaElement = getContext();
536: if (javaElement != null) {
537: initializeJavaProject(javaElement, config);
538: } else {
539: // We set empty attributes for project & main type so that when one config is
540: // compared to another, the existence of empty attributes doesn't cause an
541: // incorrect result (the performApply() method can result in empty values
542: // for these attributes being set on a config if there is nothing in the
543: // corresponding text boxes)
544: config
545: .setAttribute(
546: IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
547: ""); //$NON-NLS-1$
548: }
549: initializeTestTypeAndName(javaElement, config);
550: config.setAttribute(JUnitPdeLaunchConfiguration.WORKSPACE_ATTR,
551: JUnitPdeLaunchConfiguration.getDefaultWorkspace());
552: }
553:
554: /**
555: * Set the main type & name attributes on the working copy based on the IJavaElement
556: */
557: protected void initializeTestTypeAndName(IJavaElement javaElement,
558: ILaunchConfigurationWorkingCopy config) {
559: String name = "";
560: try {
561: // we only do a search for compilation units or class files or
562: // or source references
563: if ((javaElement instanceof ICompilationUnit)
564: || (javaElement instanceof ISourceReference)
565: || (javaElement instanceof IClassFile)) {
566:
567: IType[] types = TestSearchEngine.findTests(
568: new BusyIndicatorRunnableContext(),
569: new Object[] { javaElement });
570: if ((types == null) || (types.length < 1)) {
571: return;
572: }
573: // Simply grab the first main type found in the searched element
574: name = types[0].getFullyQualifiedName();
575: }
576: } catch (InterruptedException ie) {
577: } catch (InvocationTargetException ite) {
578: }
579: if (name == null)
580: name = "";
581:
582: config.setAttribute(
583: IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
584: name);
585: if (name.length() > 0) {
586: int index = name.lastIndexOf('.');
587: if (index > 0) {
588: name = name.substring(index + 1);
589: }
590: name = getLaunchConfigurationDialog().generateName(name);
591: config.rename(name);
592: }
593: }
594:
595: /**
596: * @see ILaunchConfigurationTab#getName()
597: */
598: public String getName() {
599: return "Plugin Test";
600: }
601:
602: /**
603: * @see ILaunchConfigurationTab#getImage()
604: */
605: public Image getImage() {
606: return fTestIcon;
607: }
608:
609: protected static Image createImage(String path) {
610: try {
611: ImageDescriptor id = ImageDescriptor
612: .createFromURL(JUnitPdePlugin.makeIconFileURL(path));
613: return id.createImage();
614: } catch (MalformedURLException e) {
615: // fall through
616: }
617: return null;
618: }
619:
620: }
|