blob: 038f0b91f821c660b7b62cfa60fa2fdc1dd8a56c [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.adt.internal.launch.junit;
import com.android.SdkConstants;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.launch.LaunchMessages;
import com.android.ide.eclipse.adt.internal.launch.MainLaunchConfigTab;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.junit.Messages;
import org.eclipse.jdt.internal.junit.launcher.ITestKind;
import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
import org.eclipse.jdt.internal.junit.launcher.JUnitMigrationDelegate;
import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
import org.eclipse.jdt.internal.junit.launcher.TestSelectionDialog;
import org.eclipse.jdt.internal.junit.ui.JUnitMessages;
import org.eclipse.jdt.internal.junit.util.LayoutUtil;
import org.eclipse.jdt.internal.junit.util.TestSearchEngine;
import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.ui.JavaElementComparator;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.SelectionDialog;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
/**
* The launch config UI tab for Android JUnit
* <p/>
* Based on org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationTab
*/
@SuppressWarnings("restriction")
public class AndroidJUnitLaunchConfigurationTab extends AbstractLaunchConfigurationTab {
// Project UI widgets
private Label mProjLabel;
private Text mProjText;
private Button mProjButton;
// Test class UI widgets
private Text mTestText;
private Button mSearchButton;
private String mOriginalTestMethodName;
private Label mTestMethodLabel;
private Text mContainerText;
private IJavaElement mContainerElement;
private final ILabelProvider mJavaElementLabelProvider = new JavaElementLabelProvider();
private Button mContainerSearchButton;
private Button mTestContainerRadioButton;
private Button mTestRadioButton;
private Label mTestLabel;
// Android specific members
private Image mTabIcon = null;
private Combo mInstrumentationCombo;
private Combo mTestSizeCombo;
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final String TAG = "AndroidJUnitLaunchConfigurationTab"; //$NON-NLS-1$
private String[] mInstrumentations = null;
private InstrumentationRunnerValidator mInstrValidator = null;
private ProjectChooserHelper mProjectChooserHelper;
public static final String SMALL_TEST_ANNOTATION = "@SmallTest"; //$NON-NLS-1$
public static final String MEDIUM_TEST_ANNOTATION = "@MediumTest"; //$NON-NLS-1$
public static final String LARGE_TEST_ANNOTATION = "@LargeTest"; //$NON-NLS-1$
private static final List<String> TEST_SIZE_OPTIONS = Arrays.asList(
"All Tests",
SMALL_TEST_ANNOTATION,
MEDIUM_TEST_ANNOTATION,
LARGE_TEST_ANNOTATION
);
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createControl(Composite parent) {
mProjectChooserHelper = new ProjectChooserHelper(parent.getShell(), null /*filter*/);
Composite comp = new Composite(parent, SWT.NONE);
setControl(comp);
GridLayout topLayout = new GridLayout();
topLayout.numColumns = 3;
comp.setLayout(topLayout);
createSingleTestSection(comp);
createTestContainerSelectionGroup(comp);
createSpacer(comp);
createInstrumentationGroup(comp);
createSizeSelector(comp);
Dialog.applyDialogFont(comp);
// TODO: add help link here when available
//PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
// IJUnitHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_JUNIT_MAIN_TAB);
validatePage();
}
private void createSpacer(Composite comp) {
Label label = new Label(comp, SWT.NONE);
GridData gd = new GridData();
gd.horizontalSpan = 3;
label.setLayoutData(gd);
}
private void createSingleTestSection(Composite comp) {
mTestRadioButton = new Button(comp, SWT.RADIO);
mTestRadioButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_oneTest);
GridData gd = new GridData();
gd.horizontalSpan = 3;
mTestRadioButton.setLayoutData(gd);
mTestRadioButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (mTestRadioButton.getSelection()) {
testModeChanged();
}
}
});
mProjLabel = new Label(comp, SWT.NONE);
mProjLabel.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_project);
gd = new GridData();
gd.horizontalIndent = 25;
mProjLabel.setLayoutData(gd);
mProjText = new Text(comp, SWT.SINGLE | SWT.BORDER);
mProjText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mProjText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent evt) {
validatePage();
updateLaunchConfigurationDialog();
mSearchButton.setEnabled(mTestRadioButton.getSelection() &&
mProjText.getText().length() > 0);
}
});
mProjButton = new Button(comp, SWT.PUSH);
mProjButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_browse);
mProjButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent evt) {
handleProjectButtonSelected();
}
});
setButtonGridData(mProjButton);
mTestLabel = new Label(comp, SWT.NONE);
gd = new GridData();
gd.horizontalIndent = 25;
mTestLabel.setLayoutData(gd);
mTestLabel.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_test);
mTestText = new Text(comp, SWT.SINGLE | SWT.BORDER);
mTestText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mTestText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent evt) {
validatePage();
updateLaunchConfigurationDialog();
}
});
mSearchButton = new Button(comp, SWT.PUSH);
mSearchButton.setEnabled(mProjText.getText().length() > 0);
mSearchButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_search);
mSearchButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent evt) {
handleSearchButtonSelected();
}
});
setButtonGridData(mSearchButton);
new Label(comp, SWT.NONE);
mTestMethodLabel = new Label(comp, SWT.NONE);
mTestMethodLabel.setText(""); //$NON-NLS-1$
gd = new GridData();
gd.horizontalSpan = 2;
mTestMethodLabel.setLayoutData(gd);
}
private void createTestContainerSelectionGroup(Composite comp) {
mTestContainerRadioButton = new Button(comp, SWT.RADIO);
mTestContainerRadioButton.setText(
LaunchMessages.AndroidJUnitTab_TestContainerText);
GridData gd = new GridData();
gd.horizontalSpan = 3;
mTestContainerRadioButton.setLayoutData(gd);
mTestContainerRadioButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (mTestContainerRadioButton.getSelection()) {
testModeChanged();
}
}
});
mContainerText = new Text(comp, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalIndent = 25;
gd.horizontalSpan = 2;
mContainerText.setLayoutData(gd);
mContainerText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent evt) {
updateLaunchConfigurationDialog();
}
});
mContainerSearchButton = new Button(comp, SWT.PUSH);
mContainerSearchButton.setText(JUnitMessages.JUnitLaunchConfigurationTab_label_search);
mContainerSearchButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent evt) {
handleContainerSearchButtonSelected();
}
});
setButtonGridData(mContainerSearchButton);
}
private void createInstrumentationGroup(Composite comp) {
Label loaderLabel = new Label(comp, SWT.NONE);
loaderLabel.setText(LaunchMessages.AndroidJUnitTab_LoaderLabel);
GridData gd = new GridData();
gd.horizontalIndent = 0;
loaderLabel.setLayoutData(gd);
mInstrumentationCombo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY);
GridDataFactory.defaultsFor(mInstrumentationCombo)
.span(2, 1)
.applyTo(mInstrumentationCombo);
mInstrumentationCombo.clearSelection();
mInstrumentationCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
validatePage();
updateLaunchConfigurationDialog();
}
});
}
private void createSizeSelector(Composite comp) {
Label l = new Label(comp, SWT.NONE);
l.setText(LaunchMessages.AndroidJUnitTab_SizeLabel);
GridData gd = new GridData();
gd.horizontalIndent = 0;
l.setLayoutData(gd);
mTestSizeCombo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY);
mTestSizeCombo.setItems(TEST_SIZE_OPTIONS.toArray(new String[TEST_SIZE_OPTIONS.size()]));
mTestSizeCombo.select(0);
mTestSizeCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
}
private void handleContainerSearchButtonSelected() {
IJavaElement javaElement = chooseContainer(mContainerElement);
if (javaElement != null) {
setContainerElement(javaElement);
}
}
private void setContainerElement(IJavaElement javaElement) {
mContainerElement = javaElement;
mContainerText.setText(getPresentationName(javaElement));
validatePage();
updateLaunchConfigurationDialog();
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
*/
@Override
public void initializeFrom(ILaunchConfiguration config) {
String projectName = updateProjectFromConfig(config);
String containerHandle = EMPTY_STRING;
try {
containerHandle = config.getAttribute(
JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, EMPTY_STRING);
} catch (CoreException ce) {
// ignore
}
if (containerHandle.length() > 0) {
updateTestContainerFromConfig(config);
} else {
updateTestTypeFromConfig(config);
}
IProject proj = mProjectChooserHelper.getAndroidProject(projectName);
loadInstrumentations(proj);
updateInstrumentationFromConfig(config);
updateTestSizeFromConfig(config);
validatePage();
}
private void updateInstrumentationFromConfig(ILaunchConfiguration config) {
boolean found = false;
try {
String currentInstrumentation = config.getAttribute(
AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME, EMPTY_STRING);
if (mInstrumentations != null) {
// look for the name of the instrumentation in the combo.
for (int i = 0; i < mInstrumentations.length; i++) {
if (currentInstrumentation.equals(mInstrumentations[i])) {
found = true;
mInstrumentationCombo.select(i);
break;
}
}
}
} catch (CoreException ce) {
// ignore
}
if (!found) {
mInstrumentationCombo.clearSelection();
}
}
private void updateTestSizeFromConfig(ILaunchConfiguration config) {
try {
String testSize = config.getAttribute(
AndroidJUnitLaunchConfigDelegate.ATTR_TEST_SIZE, EMPTY_STRING);
int index = TEST_SIZE_OPTIONS.indexOf(testSize);
if (index >= 0 && mTestSizeCombo != null) {
mTestSizeCombo.select(index);
}
} catch (CoreException e) {
// ignore
}
}
private String updateProjectFromConfig(ILaunchConfiguration config) {
String projectName = EMPTY_STRING;
try {
projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
EMPTY_STRING);
} catch (CoreException ce) {
// ignore
}
mProjText.setText(projectName);
return projectName;
}
private void updateTestTypeFromConfig(ILaunchConfiguration config) {
String testTypeName = EMPTY_STRING;
mOriginalTestMethodName = EMPTY_STRING;
try {
testTypeName = config.getAttribute(
IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, ""); //$NON-NLS-1$
mOriginalTestMethodName = config.getAttribute(
JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME, ""); //$NON-NLS-1$
} catch (CoreException ce) {
// ignore
}
mTestRadioButton.setSelection(true);
setEnableSingleTestGroup(true);
setEnableContainerTestGroup(false);
mTestContainerRadioButton.setSelection(false);
mTestText.setText(testTypeName);
mContainerText.setText(EMPTY_STRING);
setTestMethodLabel(mOriginalTestMethodName);
}
private void setTestMethodLabel(String testMethodName) {
if (!EMPTY_STRING.equals(testMethodName)) {
mTestMethodLabel.setText(
JUnitMessages.JUnitLaunchConfigurationTab_label_method +
mOriginalTestMethodName);
} else {
mTestMethodLabel.setText(EMPTY_STRING);
}
}
private void updateTestContainerFromConfig(ILaunchConfiguration config) {
String containerHandle = EMPTY_STRING;
IJavaElement containerElement = null;
try {
containerHandle = config.getAttribute(
JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, EMPTY_STRING);
if (containerHandle.length() > 0) {
containerElement = JavaCore.create(containerHandle);
}
} catch (CoreException ce) {
// ignore
}
if (containerElement != null) {
mContainerElement = containerElement;
}
mTestContainerRadioButton.setSelection(true);
setEnableSingleTestGroup(false);
setEnableContainerTestGroup(true);
mTestRadioButton.setSelection(false);
if (mContainerElement != null) {
mContainerText.setText(getPresentationName(mContainerElement));
}
mTestText.setText(EMPTY_STRING);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
*/
@Override
public void performApply(ILaunchConfigurationWorkingCopy config) {
if (mTestContainerRadioButton.getSelection() && mContainerElement != null) {
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
mContainerElement.getJavaProject().getElementName());
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
mContainerElement.getHandleIdentifier());
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
EMPTY_STRING);
//workaround for Eclipse bug 65399
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
EMPTY_STRING);
} else {
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
mProjText.getText());
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
mTestText.getText());
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
EMPTY_STRING);
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
mOriginalTestMethodName);
}
try {
mapResources(config);
} catch (CoreException e) {
// TODO: does the real error need to be extracted out of CoreException
AdtPlugin.log(e, "Error occurred saving configuration"); //$NON-NLS-1$
}
AndroidJUnitLaunchConfigDelegate.setJUnitDefaults(config);
config.setAttribute(AndroidJUnitLaunchConfigDelegate.ATTR_INSTR_NAME,
getSelectedInstrumentation());
config.setAttribute(AndroidJUnitLaunchConfigDelegate.ATTR_TEST_SIZE,
getSelectedTestSize());
}
private void mapResources(ILaunchConfigurationWorkingCopy config) throws CoreException {
JUnitMigrationDelegate.mapResources(config);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#dispose()
*/
@Override
public void dispose() {
super.dispose();
mTabIcon = null;
mJavaElementLabelProvider.dispose();
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getImage()
*/
@Override
public Image getImage() {
// reuse icon from the Android App Launch config tab
if (mTabIcon == null) {
mTabIcon = IconFactory.getInstance().getIcon(MainLaunchConfigTab.LAUNCH_TAB_IMAGE);
}
return mTabIcon;
}
/**
* Show a dialog that lists all main types
*/
private void handleSearchButtonSelected() {
Shell shell = getShell();
IJavaProject javaProject = getJavaProject();
IType[] types = new IType[0];
boolean[] radioSetting = new boolean[2];
try {
// fix for Eclipse bug 66922 Wrong radio behaviour when switching
// remember the selected radio button
radioSetting[0] = mTestRadioButton.getSelection();
radioSetting[1] = mTestContainerRadioButton.getSelection();
types = TestSearchEngine.findTests(getLaunchConfigurationDialog(), javaProject,
getTestKind());
} catch (InterruptedException e) {
setErrorMessage(e.getMessage());
return;
} catch (InvocationTargetException e) {
AdtPlugin.log(e.getTargetException(), "Error finding test types"); //$NON-NLS-1$
return;
} finally {
mTestRadioButton.setSelection(radioSetting[0]);
mTestContainerRadioButton.setSelection(radioSetting[1]);
}
SelectionDialog dialog = new TestSelectionDialog(shell, types);
dialog.setTitle(JUnitMessages.JUnitLaunchConfigurationTab_testdialog_title);
dialog.setMessage(JUnitMessages.JUnitLaunchConfigurationTab_testdialog_message);
if (dialog.open() == Window.CANCEL) {
return;
}
Object[] results = dialog.getResult();
if ((results == null) || (results.length < 1)) {
return;
}
IType type = (IType) results[0];
if (type != null) {
mTestText.setText(type.getFullyQualifiedName('.'));
javaProject = type.getJavaProject();
mProjText.setText(javaProject.getElementName());
}
}
private ITestKind getTestKind() {
// harddcode this to JUnit 3
return TestKindRegistry.getDefault().getKind(TestKindRegistry.JUNIT3_TEST_KIND_ID);
}
/**
* Show a dialog that lets the user select a Android project. This in turn provides
* context for the main type, allowing the user to key a main type name, or
* constraining the search for main types to the specified project.
*/
private void handleProjectButtonSelected() {
IJavaProject project = mProjectChooserHelper.chooseJavaProject(getProjectName(),
"Please select a project to launch");
if (project == null) {
return;
}
String projectName = project.getElementName();
mProjText.setText(projectName);
loadInstrumentations(project.getProject());
}
/**
* Return the IJavaProject corresponding to the project name in the project name
* text field, or null if the text does not match a Android project name.
*/
private IJavaProject getJavaProject() {
String projectName = getProjectName();
return getJavaModel().getJavaProject(projectName);
}
/**
* Returns the name of the currently specified project. Null if no project is selected.
*/
private String getProjectName() {
String projectName = mProjText.getText().trim();
if (projectName.length() < 1) {
return null;
}
return projectName;
}
/**
* Convenience method to get the workspace root.
*/
private IWorkspaceRoot getWorkspaceRoot() {
return ResourcesPlugin.getWorkspace().getRoot();
}
/**
* Convenience method to get access to the java model.
*/
private IJavaModel getJavaModel() {
return JavaCore.create(getWorkspaceRoot());
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
*/
@Override
public boolean isValid(ILaunchConfiguration config) {
validatePage();
return getErrorMessage() == null;
}
private void testModeChanged() {
boolean isSingleTestMode = mTestRadioButton.getSelection();
setEnableSingleTestGroup(isSingleTestMode);
setEnableContainerTestGroup(!isSingleTestMode);
if (!isSingleTestMode && mContainerText.getText().length() == 0) {
String projText = mProjText.getText();
if (Path.EMPTY.isValidSegment(projText)) {
IJavaProject javaProject = getJavaModel().getJavaProject(projText);
if (javaProject != null && javaProject.exists()) {
setContainerElement(javaProject);
}
}
}
validatePage();
updateLaunchConfigurationDialog();
}
private void validatePage() {
setErrorMessage(null);
setMessage(null);
if (mTestContainerRadioButton.getSelection()) {
if (mContainerElement == null) {
setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_noContainer);
return;
}
validateJavaProject(mContainerElement.getJavaProject());
return;
}
String projectName = mProjText.getText().trim();
if (projectName.length() == 0) {
setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_projectnotdefined);
return;
}
IStatus status = ResourcesPlugin.getWorkspace().validatePath(IPath.SEPARATOR + projectName,
IResource.PROJECT);
if (!status.isOK() || !Path.ROOT.isValidSegment(projectName)) {
setErrorMessage(Messages.format(
JUnitMessages.JUnitLaunchConfigurationTab_error_invalidProjectName,
projectName));
return;
}
IProject project = getWorkspaceRoot().getProject(projectName);
if (!project.exists()) {
setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_projectnotexists);
return;
}
IJavaProject javaProject = JavaCore.create(project);
validateJavaProject(javaProject);
try {
if (!project.hasNature(AdtConstants.NATURE_DEFAULT)) {
setErrorMessage(
LaunchMessages.NonAndroidProjectError);
return;
}
String className = mTestText.getText().trim();
if (className.length() == 0) {
setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_testnotdefined);
return;
}
if (javaProject.findType(className) == null) {
setErrorMessage(Messages.format(
JUnitMessages.JUnitLaunchConfigurationTab_error_test_class_not_found,
new String[] { className, projectName }));
return;
}
} catch (CoreException e) {
AdtPlugin.log(e, "validatePage failed"); //$NON-NLS-1$
}
validateInstrumentation();
}
private void validateJavaProject(IJavaProject javaProject) {
if (!TestSearchEngine.hasTestCaseType(javaProject)) {
setErrorMessage(JUnitMessages.JUnitLaunchConfigurationTab_error_testcasenotonpath);
return;
}
}
private void validateInstrumentation() {
String instrumentation = getSelectedInstrumentation();
if (instrumentation == null) {
setErrorMessage(LaunchMessages.AndroidJUnitTab_NoRunnerError);
return;
}
String result = mInstrValidator.validateInstrumentationRunner(instrumentation);
if (result != InstrumentationRunnerValidator.INSTRUMENTATION_OK) {
setErrorMessage(result);
return;
}
}
private String getSelectedInstrumentation() {
int selectionIndex = mInstrumentationCombo.getSelectionIndex();
if (mInstrumentations != null && selectionIndex >= 0 &&
selectionIndex < mInstrumentations.length) {
return mInstrumentations[selectionIndex];
}
return null;
}
private String getSelectedTestSize() {
if (mTestSizeCombo != null) {
int index = mTestSizeCombo.getSelectionIndex();
return TEST_SIZE_OPTIONS.get(index);
} else {
return null;
}
}
private void setEnableContainerTestGroup(boolean enabled) {
mContainerSearchButton.setEnabled(enabled);
mContainerText.setEnabled(enabled);
}
private void setEnableSingleTestGroup(boolean enabled) {
mProjLabel.setEnabled(enabled);
mProjText.setEnabled(enabled);
mProjButton.setEnabled(enabled);
mTestLabel.setEnabled(enabled);
mTestText.setEnabled(enabled);
mSearchButton.setEnabled(enabled && mProjText.getText().length() > 0);
mTestMethodLabel.setEnabled(enabled);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
*/
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
IJavaElement javaElement = getContext();
if (javaElement != null) {
initializeJavaProject(javaElement, config);
} else {
// We set empty attributes for project & main type so that when one config is
// compared to another, the existence of empty attributes doesn't cause an
// incorrect result (the performApply() method can result in empty values
// for these attributes being set on a config if there is nothing in the
// corresponding text boxes)
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, EMPTY_STRING);
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
EMPTY_STRING);
}
initializeTestAttributes(javaElement, config);
}
private void initializeTestAttributes(IJavaElement javaElement,
ILaunchConfigurationWorkingCopy config) {
if (javaElement != null && javaElement.getElementType() < IJavaElement.COMPILATION_UNIT) {
initializeTestContainer(javaElement, config);
} else {
initializeTestType(javaElement, config);
}
}
private void initializeTestContainer(IJavaElement javaElement,
ILaunchConfigurationWorkingCopy config) {
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER,
javaElement.getHandleIdentifier());
initializeName(config, javaElement.getElementName());
}
private void initializeName(ILaunchConfigurationWorkingCopy config, String name) {
if (name == null) {
name = EMPTY_STRING;
}
if (name.length() > 0) {
int index = name.lastIndexOf('.');
if (index > 0) {
name = name.substring(index + 1);
}
name = getLaunchConfigurationDialog().generateName(name);
config.rename(name);
}
}
/**
* Sets the main type & name attributes on the working copy based on the IJavaElement
*/
private void initializeTestType(IJavaElement javaElement,
ILaunchConfigurationWorkingCopy config) {
String name = EMPTY_STRING;
String testKindId = null;
try {
// only do a search for compilation units or class files or source references
if (javaElement instanceof ISourceReference) {
ITestKind testKind = TestKindRegistry.getContainerTestKind(javaElement);
testKindId = testKind.getId();
IType[] types = TestSearchEngine.findTests(getLaunchConfigurationDialog(),
javaElement, testKind);
if ((types == null) || (types.length < 1)) {
return;
}
// Simply grab the first main type found in the searched element
name = types[0].getFullyQualifiedName('.');
}
} catch (InterruptedException ie) {
// ignore
} catch (InvocationTargetException ite) {
// ignore
}
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, name);
if (testKindId != null) {
config.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
testKindId);
}
initializeName(config, name);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
*/
@Override
public String getName() {
return JUnitMessages.JUnitLaunchConfigurationTab_tab_label;
}
private IJavaElement chooseContainer(IJavaElement initElement) {
@SuppressWarnings("rawtypes")
Class[] acceptedClasses = new Class[] { IJavaProject.class,
IPackageFragment.class };
TypedElementSelectionValidator validator = new TypedElementSelectionValidator(
acceptedClasses, false) {
@Override
public boolean isSelectedValid(Object element) {
return true;
}
};
acceptedClasses = new Class[] { IJavaModel.class, IPackageFragmentRoot.class,
IJavaProject.class, IPackageFragment.class };
ViewerFilter filter = new TypedViewerFilter(acceptedClasses) {
@Override
public boolean select(Viewer viewer, Object parent, Object element) {
if (element instanceof IPackageFragmentRoot &&
((IPackageFragmentRoot) element).isArchive()) {
return false;
}
try {
if (element instanceof IPackageFragment &&
!((IPackageFragment) element).hasChildren()) {
return false;
}
} catch (JavaModelException e) {
return false;
}
return super.select(viewer, parent, element);
}
};
AndroidJavaElementContentProvider provider = new AndroidJavaElementContentProvider();
ILabelProvider labelProvider = new JavaElementLabelProvider(
JavaElementLabelProvider.SHOW_DEFAULT);
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(),
labelProvider, provider);
dialog.setValidator(validator);
dialog.setComparator(new JavaElementComparator());
dialog.setTitle(JUnitMessages.JUnitLaunchConfigurationTab_folderdialog_title);
dialog.setMessage(JUnitMessages.JUnitLaunchConfigurationTab_folderdialog_message);
dialog.addFilter(filter);
dialog.setInput(JavaCore.create(getWorkspaceRoot()));
dialog.setInitialSelection(initElement);
dialog.setAllowMultiple(false);
if (dialog.open() == Window.OK) {
Object element = dialog.getFirstResult();
return (IJavaElement) element;
}
return null;
}
private String getPresentationName(IJavaElement element) {
return mJavaElementLabelProvider.getText(element);
}
/**
* Returns the current Java element context from which to initialize
* default settings, or <code>null</code> if none.
*
* @return Java element context.
*/
private IJavaElement getContext() {
IWorkbenchWindow activeWorkbenchWindow =
PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (activeWorkbenchWindow == null) {
return null;
}
IWorkbenchPage page = activeWorkbenchWindow.getActivePage();
if (page != null) {
ISelection selection = page.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
if (!ss.isEmpty()) {
Object obj = ss.getFirstElement();
if (obj instanceof IJavaElement) {
return (IJavaElement) obj;
}
if (obj instanceof IResource) {
IJavaElement je = JavaCore.create((IResource) obj);
if (je == null) {
IProject pro = ((IResource) obj).getProject();
je = JavaCore.create(pro);
}
if (je != null) {
return je;
}
}
}
}
IEditorPart part = page.getActiveEditor();
if (part != null) {
IEditorInput input = part.getEditorInput();
return (IJavaElement) input.getAdapter(IJavaElement.class);
}
}
return null;
}
private void initializeJavaProject(IJavaElement javaElement,
ILaunchConfigurationWorkingCopy config) {
IJavaProject javaProject = javaElement.getJavaProject();
String name = null;
if (javaProject != null && javaProject.exists()) {
name = javaProject.getElementName();
}
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, name);
}
private void setButtonGridData(Button button) {
GridData gridData = new GridData();
button.setLayoutData(gridData);
LayoutUtil.setButtonDimensionHint(button);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId()
*/
@Override
public String getId() {
return "com.android.ide.eclipse.adt.launch.AndroidJUnitLaunchConfigurationTab"; //$NON-NLS-1$
}
/**
* Loads the UI with the instrumentations of the specified project, and stores the
* instrumentations in <code>mInstrumentations</code>.
*
* @param project the {@link IProject} to load the instrumentations from.
*/
private void loadInstrumentations(IProject project) {
try {
mInstrValidator = new InstrumentationRunnerValidator(project);
mInstrumentations = mInstrValidator.getInstrumentationNames();
if (mInstrumentations.length > 0) {
mInstrumentationCombo.removeAll();
for (String instrumentation : mInstrumentations) {
mInstrumentationCombo.add(instrumentation);
}
// the selection will be set when we update the ui from the current
// config object.
return;
}
} catch (CoreException e) {
AdtPlugin.logAndPrintError(e, project.getName(),
LaunchMessages.AndroidJUnitTab_LoadInstrError_s,
SdkConstants.FN_ANDROID_MANIFEST_XML);
}
// if we reach this point, either project is null, or we got an exception during
// the parsing. In either case, we empty the instrumentation list.
mInstrValidator = null;
mInstrumentations = null;
mInstrumentationCombo.removeAll();
}
/**
* Overrides the {@link StandardJavaElementContentProvider} to only display Android projects
*/
private static class AndroidJavaElementContentProvider
extends StandardJavaElementContentProvider {
/**
* Override parent to return only Android projects if at the root. Otherwise, use parent
* functionality.
*/
@Override
public Object[] getChildren(Object element) {
if (element instanceof IJavaModel) {
return BaseProjectHelper.getAndroidProjects((IJavaModel) element, null /*filter*/);
}
return super.getChildren(element);
}
}
}