aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java809
1 files changed, 809 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java
new file mode 100644
index 000000000..c8325345a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/ApplicationInfoPage.java
@@ -0,0 +1,809 @@
+/*
+ * Copyright (C) 2011 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.wizards.newproject;
+
+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.sdk.Sdk;
+import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
+import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;
+import com.android.sdklib.IAndroidTarget;
+
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Text;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.net.URI;
+
+/** Page where you choose the application name, activity name, and optional test project info */
+public class ApplicationInfoPage extends WizardPage implements SelectionListener, ModifyListener,
+ ITargetChangeListener {
+ private static final String JDK_15 = "1.5"; //$NON-NLS-1$
+ private final static String DUMMY_PACKAGE = "your.package.namespace";
+
+ /** Suffix added by default to activity names */
+ static final String ACTIVITY_NAME_SUFFIX = "Activity"; //$NON-NLS-1$
+
+ private final NewProjectWizardState mValues;
+
+ private Text mApplicationText;
+ private Text mPackageText;
+ private Text mActivityText;
+ private Button mCreateActivityCheckbox;
+ private Combo mSdkCombo;
+
+ private boolean mIgnore;
+ private Button mCreateTestCheckbox;
+ private Text mTestProjectNameText;
+ private Text mTestApplicationText;
+ private Text mTestPackageText;
+ private Label mTestProjectNameLabel;
+ private Label mTestApplicationLabel;
+ private Label mTestPackageLabel;
+
+ /**
+ * Create the wizard.
+ */
+ ApplicationInfoPage(NewProjectWizardState values) {
+ super("appInfo"); //$NON-NLS-1$
+ mValues = values;
+
+ setTitle("Application Info");
+ setDescription("Configure the new Android Project");
+ AdtPlugin.getDefault().addTargetListener(this);
+ }
+
+ /**
+ * Create contents of the wizard.
+ */
+ @Override
+ @SuppressWarnings("unused") // Eclipse marks SWT constructors with side effects as unused
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ container.setLayout(new GridLayout(2, false));
+
+ Label applicationLabel = new Label(container, SWT.NONE);
+ applicationLabel.setText("Application Name:");
+
+ mApplicationText = new Text(container, SWT.BORDER);
+ mApplicationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mApplicationText.addModifyListener(this);
+
+ Label packageLabel = new Label(container, SWT.NONE);
+ packageLabel.setText("Package Name:");
+
+ mPackageText = new Text(container, SWT.BORDER);
+ mPackageText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mPackageText.addModifyListener(this);
+
+ if (mValues.mode != Mode.TEST) {
+ mCreateActivityCheckbox = new Button(container, SWT.CHECK);
+ mCreateActivityCheckbox.setText("Create Activity:");
+ mCreateActivityCheckbox.addSelectionListener(this);
+
+ mActivityText = new Text(container, SWT.BORDER);
+ mActivityText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mActivityText.addModifyListener(this);
+ }
+
+ Label minSdkLabel = new Label(container, SWT.NONE);
+ minSdkLabel.setText("Minimum SDK:");
+
+ mSdkCombo = new Combo(container, SWT.NONE);
+ GridData gdSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
+ gdSdkCombo.widthHint = 200;
+ mSdkCombo.setLayoutData(gdSdkCombo);
+ mSdkCombo.addSelectionListener(this);
+ mSdkCombo.addModifyListener(this);
+
+ onSdkLoaded();
+
+ setControl(container);
+ new Label(container, SWT.NONE);
+ new Label(container, SWT.NONE);
+
+ mCreateTestCheckbox = new Button(container, SWT.CHECK);
+ mCreateTestCheckbox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+ mCreateTestCheckbox.setText("Create a Test Project");
+ mCreateTestCheckbox.addSelectionListener(this);
+
+ mTestProjectNameLabel = new Label(container, SWT.NONE);
+ mTestProjectNameLabel.setText("Test Project Name:");
+
+ mTestProjectNameText = new Text(container, SWT.BORDER);
+ mTestProjectNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mTestProjectNameText.addModifyListener(this);
+
+ mTestApplicationLabel = new Label(container, SWT.NONE);
+ mTestApplicationLabel.setText("Test Application:");
+
+ mTestApplicationText = new Text(container, SWT.BORDER);
+ mTestApplicationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mTestApplicationText.addModifyListener(this);
+
+ mTestPackageLabel = new Label(container, SWT.NONE);
+ mTestPackageLabel.setText("Test Package:");
+
+ mTestPackageText = new Text(container, SWT.BORDER);
+ mTestPackageText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ mTestPackageText.addModifyListener(this);
+ }
+
+ /** Controls whether the options for creating a paired test project should be shown */
+ private void showTestOptions(boolean visible) {
+ if (mValues.mode == Mode.SAMPLE) {
+ visible = false;
+ }
+
+ mCreateTestCheckbox.setVisible(visible);
+ mTestProjectNameLabel.setVisible(visible);
+ mTestProjectNameText.setVisible(visible);
+ mTestApplicationLabel.setVisible(visible);
+ mTestApplicationText.setVisible(visible);
+ mTestPackageLabel.setVisible(visible);
+ mTestPackageText.setVisible(visible);
+ }
+
+ /** Controls whether the options for creating a paired test project should be enabled */
+ private void enableTestOptions(boolean enabled) {
+ mTestProjectNameLabel.setEnabled(enabled);
+ mTestProjectNameText.setEnabled(enabled);
+ mTestApplicationLabel.setEnabled(enabled);
+ mTestApplicationText.setEnabled(enabled);
+ mTestPackageLabel.setEnabled(enabled);
+ mTestPackageText.setEnabled(enabled);
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+
+ if (visible) {
+ try {
+ mIgnore = true;
+ if (mValues.applicationName != null) {
+ mApplicationText.setText(mValues.applicationName);
+ }
+ if (mValues.packageName != null) {
+ mPackageText.setText(mValues.packageName);
+ } else {
+ mPackageText.setText(DUMMY_PACKAGE);
+ }
+
+ if (mValues.mode != Mode.TEST) {
+ mCreateActivityCheckbox.setSelection(mValues.createActivity);
+ mActivityText.setEnabled(mValues.createActivity);
+ if (mValues.activityName != null) {
+ mActivityText.setText(mValues.activityName);
+ }
+ }
+ if (mValues.minSdk != null && mValues.minSdk.length() > 0) {
+ mSdkCombo.setText(mValues.minSdk);
+ }
+
+ showTestOptions(mValues.mode == Mode.ANY);
+ enableTestOptions(mCreateTestCheckbox.getSelection());
+
+ if (mValues.testProjectName != null) {
+ mTestProjectNameText.setText(mValues.testProjectName);
+ }
+ if (mValues.testApplicationName != null) {
+ mTestApplicationText.setText(mValues.testApplicationName);
+ }
+ if (mValues.testProjectName != null) {
+ mTestPackageText.setText(mValues.testProjectName);
+ }
+ } finally {
+ mIgnore = false;
+ }
+ }
+
+ // Start focus with the package name, since the other fields are typically assigned
+ // reasonable defaults
+ mPackageText.setFocus();
+ mPackageText.selectAll();
+
+ validatePage();
+ }
+
+ protected void setSdkTargets(IAndroidTarget[] targets, IAndroidTarget target) {
+ if (targets == null) {
+ targets = new IAndroidTarget[0];
+ }
+ int selectionIndex = -1;
+ String[] items = new String[targets.length];
+ for (int i = 0, n = targets.length; i < n; i++) {
+ items[i] = targetLabel(targets[i]);
+ if (targets[i] == target) {
+ selectionIndex = i;
+ }
+ }
+ try {
+ mIgnore = true;
+ mSdkCombo.setItems(items);
+ mSdkCombo.setData(targets);
+ if (selectionIndex != -1) {
+ mSdkCombo.select(selectionIndex);
+ }
+ } finally {
+ mIgnore = false;
+ }
+ }
+
+ private String targetLabel(IAndroidTarget target) {
+ // In the minimum SDK chooser, show the targets with api number and description,
+ // such as "11 (Android 3.0)"
+ return String.format("%1$s (%2$s)", target.getVersion().getApiString(),
+ target.getFullName());
+ }
+
+ @Override
+ public void dispose() {
+ AdtPlugin.getDefault().removeTargetListener(this);
+ super.dispose();
+ }
+
+ @Override
+ public boolean isPageComplete() {
+ // This page is only needed when creating new projects
+ if (mValues.useExisting || mValues.mode != Mode.ANY) {
+ return true;
+ }
+
+ // Ensure that we reach this page
+ if (mValues.packageName == null) {
+ return false;
+ }
+
+ return super.isPageComplete();
+ }
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ if (mIgnore) {
+ return;
+ }
+
+ Object source = e.getSource();
+ if (source == mSdkCombo) {
+ mValues.minSdk = mSdkCombo.getText().trim();
+ IAndroidTarget[] targets = (IAndroidTarget[]) mSdkCombo.getData();
+ // An editable combo will treat item selection the same way as a user edit,
+ // so we need to see if the string looks like a labeled version
+ int index = mSdkCombo.getSelectionIndex();
+ if (index != -1) {
+ if (index >= 0 && index < targets.length) {
+ IAndroidTarget target = targets[index];
+ if (targetLabel(target).equals(mValues.minSdk)) {
+ mValues.minSdk = target.getVersion().getApiString();
+ }
+ }
+ }
+
+ // Ensure that we never pick up the (Android x.y) suffix shown in combobox
+ // for readability
+ int separator = mValues.minSdk.indexOf(' ');
+ if (separator != -1) {
+ mValues.minSdk = mValues.minSdk.substring(0, separator);
+ }
+ mValues.minSdkModifiedByUser = true;
+ mValues.updateSdkTargetToMatchMinSdkVersion();
+ } else if (source == mApplicationText) {
+ mValues.applicationName = mApplicationText.getText().trim();
+ mValues.applicationNameModifiedByUser = true;
+
+ if (!mValues.testApplicationNameModified) {
+ mValues.testApplicationName = suggestTestApplicationName(mValues.applicationName);
+ try {
+ mIgnore = true;
+ mTestApplicationText.setText(mValues.testApplicationName);
+ } finally {
+ mIgnore = false;
+ }
+ }
+
+ } else if (source == mPackageText) {
+ mValues.packageName = mPackageText.getText().trim();
+ mValues.packageNameModifiedByUser = true;
+
+ if (!mValues.testPackageModified) {
+ mValues.testPackageName = suggestTestPackage(mValues.packageName);
+ try {
+ mIgnore = true;
+ mTestPackageText.setText(mValues.testPackageName);
+ } finally {
+ mIgnore = false;
+ }
+ }
+ } else if (source == mActivityText) {
+ mValues.activityName = mActivityText.getText().trim();
+ mValues.activityNameModifiedByUser = true;
+ } else if (source == mTestApplicationText) {
+ mValues.testApplicationName = mTestApplicationText.getText().trim();
+ mValues.testApplicationNameModified = true;
+ } else if (source == mTestPackageText) {
+ mValues.testPackageName = mTestPackageText.getText().trim();
+ mValues.testPackageModified = true;
+ } else if (source == mTestProjectNameText) {
+ mValues.testProjectName = mTestProjectNameText.getText().trim();
+ mValues.testProjectModified = true;
+ }
+
+ validatePage();
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (mIgnore) {
+ return;
+ }
+
+ Object source = e.getSource();
+
+ if (source == mCreateActivityCheckbox) {
+ mValues.createActivity = mCreateActivityCheckbox.getSelection();
+ mActivityText.setEnabled(mValues.createActivity);
+ } else if (source == mSdkCombo) {
+ int index = mSdkCombo.getSelectionIndex();
+ IAndroidTarget[] targets = (IAndroidTarget[]) mSdkCombo.getData();
+ if (index != -1) {
+ if (index >= 0 && index < targets.length) {
+ IAndroidTarget target = targets[index];
+ // Even though we are showing the logical version name, we place the
+ // actual api number as the minimum SDK
+ mValues.minSdk = target.getVersion().getApiString();
+ }
+ } else {
+ String text = mSdkCombo.getText();
+ boolean found = false;
+ for (IAndroidTarget target : targets) {
+ if (targetLabel(target).equals(text)) {
+ mValues.minSdk = target.getVersion().getApiString();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ mValues.minSdk = text;
+ }
+ }
+ } else if (source == mCreateTestCheckbox) {
+ mValues.createPairProject = mCreateTestCheckbox.getSelection();
+ enableTestOptions(mValues.createPairProject);
+ if (mValues.createPairProject) {
+ if (mValues.testProjectName == null || mValues.testProjectName.length() == 0) {
+ mValues.testProjectName = suggestTestProjectName(mValues.projectName);
+ }
+ if (mValues.testApplicationName == null ||
+ mValues.testApplicationName.length() == 0) {
+ mValues.testApplicationName =
+ suggestTestApplicationName(mValues.applicationName);
+ }
+ if (mValues.testPackageName == null || mValues.testPackageName.length() == 0) {
+ mValues.testPackageName = suggestTestPackage(mValues.packageName);
+ }
+
+ try {
+ mIgnore = true;
+ mTestProjectNameText.setText(mValues.testProjectName);
+ mTestApplicationText.setText(mValues.testApplicationName);
+ mTestPackageText.setText(mValues.testPackageName);
+ } finally {
+ mIgnore = false;
+ }
+ }
+ }
+
+ validatePage();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ private void validatePage() {
+ IStatus status = validatePackage(mValues.packageName);
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ IStatus validActivity = validateActivity();
+ if (validActivity != null) {
+ status = validActivity;
+ }
+ }
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ IStatus validMinSdk = validateMinSdk();
+ if (validMinSdk != null) {
+ status = validMinSdk;
+ }
+ }
+
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ IStatus validSourceFolder = validateSourceFolder();
+ if (validSourceFolder != null) {
+ status = validSourceFolder;
+ }
+ }
+
+ // If creating a test project to go along with the main project, also validate
+ // the additional test project parameters
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ if (mValues.createPairProject) {
+ IStatus validTestProject = ProjectNamePage.validateProjectName(
+ mValues.testProjectName);
+ if (validTestProject != null) {
+ status = validTestProject;
+ }
+
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ IStatus validTestLocation = validateTestProjectLocation();
+ if (validTestLocation != null) {
+ status = validTestLocation;
+ }
+ }
+
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ IStatus validTestPackage = validatePackage(mValues.testPackageName);
+ if (validTestPackage != null) {
+ status = new Status(validTestPackage.getSeverity(),
+ AdtPlugin.PLUGIN_ID,
+ validTestPackage.getMessage() + " (in test package)");
+ }
+ }
+
+ if (status == null || status.getSeverity() != IStatus.ERROR) {
+ if (mValues.projectName.equals(mValues.testProjectName)) {
+ status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "The main project name and the test project name must be different.");
+ }
+ }
+ }
+ }
+
+ // -- update UI & enable finish if there's no error
+ setPageComplete(status == null || status.getSeverity() != IStatus.ERROR);
+ if (status != null) {
+ setMessage(status.getMessage(),
+ status.getSeverity() == IStatus.ERROR
+ ? IMessageProvider.ERROR : IMessageProvider.WARNING);
+ } else {
+ setErrorMessage(null);
+ setMessage(null);
+ }
+ }
+
+ private IStatus validateTestProjectLocation() {
+ assert mValues.createPairProject;
+
+ // Validate location
+ Path path = new Path(mValues.projectLocation.getPath());
+ if (!mValues.useExisting) {
+ if (!mValues.useDefaultLocation) {
+ // If not using the default value validate the location.
+ URI uri = URIUtil.toURI(path.toOSString());
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IProject handle = workspace.getRoot().getProject(mValues.testProjectName);
+ IStatus locationStatus = workspace.validateProjectLocationURI(handle, uri);
+ if (!locationStatus.isOK()) {
+ return locationStatus;
+ }
+ // The location is valid as far as Eclipse is concerned (i.e. mostly not
+ // an existing workspace project.) Check it either doesn't exist or is
+ // a directory that is empty.
+ File f = path.toFile();
+ if (f.exists() && !f.isDirectory()) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "A directory name must be specified.");
+ } else if (f.isDirectory()) {
+ // However if the directory exists, we should put a
+ // warning if it is not empty. We don't put an error
+ // (we'll ask the user again for confirmation before
+ // using the directory.)
+ String[] l = f.list();
+ if (l != null && l.length != 0) {
+ return new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
+ "The selected output directory is not empty.");
+ }
+ }
+ } else {
+ IPath destPath = path.removeLastSegments(1).append(mValues.testProjectName);
+ File dest = destPath.toFile();
+ if (dest.exists()) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ String.format(
+ "There is already a file or directory named \"%1$s\" in the selected location.",
+ mValues.testProjectName));
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private IStatus validateSourceFolder() {
+ // This check does nothing when creating a new project.
+ // This check is also useless when no activity is present or created.
+ mValues.sourceFolder = SdkConstants.FD_SOURCES;
+ if (!mValues.useExisting || !mValues.createActivity) {
+ return null;
+ }
+
+ String osTarget = mValues.activityName;
+ if (osTarget.indexOf('.') == -1) {
+ osTarget = mValues.packageName + File.separator + osTarget;
+ } else if (osTarget.indexOf('.') == 0) {
+ osTarget = mValues.packageName + osTarget;
+ }
+ osTarget = osTarget.replace('.', File.separatorChar) + SdkConstants.DOT_JAVA;
+
+ File projectDir = mValues.projectLocation;
+ File[] allDirs = projectDir.listFiles(new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ });
+ if (allDirs != null) {
+ boolean found = false;
+ for (File f : allDirs) {
+ Path path = new Path(f.getAbsolutePath());
+ File java_activity = path.append(osTarget).toFile();
+ if (java_activity.isFile()) {
+ mValues.sourceFolder = f.getName();
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ String projectPath = projectDir.getPath();
+ if (allDirs.length > 0) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ String.format("%1$s can not be found under %2$s.", osTarget,
+ projectPath));
+ } else {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ String.format("No source folders can be found in %1$s.",
+ projectPath));
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private IStatus validateMinSdk() {
+ // Validate min SDK field
+ // If the min sdk version is empty, it is always accepted.
+ if (mValues.minSdk == null || mValues.minSdk.length() == 0) {
+ return null;
+ }
+
+ IAndroidTarget target = mValues.target;
+ if (target == null) {
+ return null;
+ }
+
+ // If the current target is a preview, explicitly indicate minSdkVersion
+ // must be set to this target name.
+ if (target.getVersion().isPreview() && !target.getVersion().equals(mValues.minSdk)) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ String.format(
+ "The SDK target is a preview. Min SDK Version must be set to '%s'.",
+ target.getVersion().getCodename()));
+ }
+
+ if (!target.getVersion().equals(mValues.minSdk)) {
+ return new Status(target.getVersion().isPreview() ? IStatus.ERROR : IStatus.WARNING,
+ AdtPlugin.PLUGIN_ID,
+ "The API level for the selected SDK target does not match the Min SDK Version."
+ );
+ }
+
+ return null;
+ }
+
+ public static IStatus validatePackage(String packageFieldContents) {
+ // Validate package
+ if (packageFieldContents == null || packageFieldContents.length() == 0) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Package name must be specified.");
+ } else if (packageFieldContents.equals(DUMMY_PACKAGE)) {
+ // The dummy package name is just a placeholder package (which isn't even valid
+ // because it contains the reserved Java keyword "package") but we want to
+ // make the error message say that a proper package should be entered rather than
+ // what's wrong with this specific package. (And the reason we provide a dummy
+ // package rather than a blank line is to make it more clear to beginners what
+ // we're looking for.
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Package name must be specified.");
+ }
+ // Check it's a valid package string
+ IStatus status = JavaConventions.validatePackageName(packageFieldContents, JDK_15,
+ JDK_15);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ // The Android Activity Manager does not accept packages names with only one
+ // identifier. Check the package name has at least one dot in them (the previous rule
+ // validated that if such a dot exist, it's not the first nor last characters of the
+ // string.)
+ if (packageFieldContents.indexOf('.') == -1) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Package name must have at least two identifiers.");
+ }
+
+ return null;
+ }
+
+ public static IStatus validateClass(String className) {
+ if (className == null || className.length() == 0) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Class name must be specified.");
+ }
+ if (className.indexOf('.') != -1) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Enter just a class name, not a full package name");
+ }
+ return JavaConventions.validateJavaTypeName(className, JDK_15, JDK_15);
+ }
+
+ private IStatus validateActivity() {
+ // Validate activity (if creating an activity)
+ if (!mValues.createActivity) {
+ return null;
+ }
+
+ return validateActivity(mValues.activityName);
+ }
+
+ /**
+ * Validates the given activity name
+ *
+ * @param activityFieldContents the activity name to validate
+ * @return a status for whether the activity name is valid
+ */
+ public static IStatus validateActivity(String activityFieldContents) {
+ // Validate activity field
+ if (activityFieldContents == null || activityFieldContents.length() == 0) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Activity name must be specified.");
+ } else if (ACTIVITY_NAME_SUFFIX.equals(activityFieldContents)) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "Enter a valid activity name");
+ } else if (activityFieldContents.contains("..")) { //$NON-NLS-1$
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ "Package segments in activity name cannot be empty (..)");
+ }
+ // The activity field can actually contain part of a sub-package name
+ // or it can start with a dot "." to indicates it comes from the parent package
+ // name.
+ String packageName = ""; //$NON-NLS-1$
+ int pos = activityFieldContents.lastIndexOf('.');
+ if (pos >= 0) {
+ packageName = activityFieldContents.substring(0, pos);
+ if (packageName.startsWith(".")) { //$NON-NLS-1$
+ packageName = packageName.substring(1);
+ }
+
+ activityFieldContents = activityFieldContents.substring(pos + 1);
+ }
+
+ // the activity field can contain a simple java identifier, or a
+ // package name or one that starts with a dot. So if it starts with a dot,
+ // ignore this dot -- the rest must look like a package name.
+ if (activityFieldContents.length() > 0 && activityFieldContents.charAt(0) == '.') {
+ activityFieldContents = activityFieldContents.substring(1);
+ }
+
+ // Check it's a valid activity string
+ IStatus status = JavaConventions.validateTypeVariableName(activityFieldContents, JDK_15,
+ JDK_15);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ // Check it's a valid package string
+ if (packageName.length() > 0) {
+ status = JavaConventions.validatePackageName(packageName, JDK_15, JDK_15);
+ if (!status.isOK()) {
+ return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+ status.getMessage() + " (in the activity name)");
+ }
+ }
+
+ return null;
+ }
+
+ // ---- Implement ITargetChangeListener ----
+
+ @Override
+ public void onSdkLoaded() {
+ if (mSdkCombo == null) {
+ return;
+ }
+
+ // Update the sdk target selector with the new targets
+
+ // get the targets from the sdk
+ IAndroidTarget[] targets = null;
+ if (Sdk.getCurrent() != null) {
+ targets = Sdk.getCurrent().getTargets();
+ }
+ setSdkTargets(targets, mValues.target);
+ }
+
+ @Override
+ public void onProjectTargetChange(IProject changedProject) {
+ // Ignore
+ }
+
+ @Override
+ public void onTargetLoaded(IAndroidTarget target) {
+ // Ignore
+ }
+
+ public static String suggestTestApplicationName(String applicationName) {
+ if (applicationName == null) {
+ applicationName = ""; //$NON-NLS-1$
+ }
+ if (applicationName.indexOf(' ') != -1) {
+ return applicationName + " Test"; //$NON-NLS-1$
+ } else {
+ return applicationName + "Test"; //$NON-NLS-1$
+ }
+ }
+
+ public static String suggestTestProjectName(String projectName) {
+ if (projectName == null) {
+ projectName = ""; //$NON-NLS-1$
+ }
+ if (projectName.length() > 0 && Character.isUpperCase(projectName.charAt(0))) {
+ return projectName + "Test"; //$NON-NLS-1$
+ } else {
+ return projectName + "-test"; //$NON-NLS-1$
+ }
+ }
+
+
+ public static String suggestTestPackage(String packagePath) {
+ if (packagePath == null) {
+ packagePath = ""; //$NON-NLS-1$
+ }
+ return packagePath + ".test"; //$NON-NLS-1$
+ }
+}