aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
diff options
context:
space:
mode:
authorBob Badour <bbadour@google.com>2020-05-06 14:54:04 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-05-06 14:54:04 +0000
commitd58f8ba3b1869530926bd5f167103dfa161787a1 (patch)
treefd845444b59dfc72656b7781596e0b1a0662c4c7 /eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
parente36f051d414b814cf80b289770c1f7e58f6655ea (diff)
parentd3c69fa48e25645a343d97ac392300583e38b30a (diff)
downloadsdk-d58f8ba3b1869530926bd5f167103dfa161787a1.tar.gz
Merge "Revert "Remove unused project."" am: fc7cda06f5 am: d3c69fa48e
Change-Id: I2920d1fca1593e86805ec8a728121cf2513e2bc5
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java1061
1 files changed, 1061 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
new file mode 100644
index 000000000..038f0b91f
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
@@ -0,0 +1,1061 @@
+/*
+ * 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);
+ }
+ }
+}