aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.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/NewProjectWizardState.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java412
1 files changed, 412 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java
new file mode 100644
index 000000000..06c0300b7
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizardState.java
@@ -0,0 +1,412 @@
+/*
+ * 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.annotations.Nullable;
+import com.android.ide.common.xml.ManifestData;
+import com.android.ide.common.xml.ManifestData.Activity;
+import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
+import com.android.ide.eclipse.adt.internal.sdk.Sdk;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.internal.project.ProjectProperties;
+import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
+import com.android.utils.Pair;
+import com.android.xml.AndroidManifest;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.ui.IWorkingSet;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The {@link NewProjectWizardState} holds the state used by the various pages
+ * in the {@link NewProjectWizard} and its variations, and it can also be used
+ * to pass project information to the {@link NewProjectCreator}.
+ */
+public class NewProjectWizardState {
+ /** The mode to run the wizard in: creating test, or sample, or plain project */
+ public Mode mode;
+
+ /**
+ * If true, the project should be created from an existing codebase (pointed
+ * to by the {@link #projectLocation} or in the case of sample projects, the
+ * {@link #chosenSample}. Otherwise, create a brand new project from scratch.
+ */
+ public boolean useExisting;
+
+ /**
+ * Whether new projects should be created into the default project location
+ * (e.g. in the Eclipse workspace) or not
+ */
+ public boolean useDefaultLocation = true;
+
+ /** The build target SDK */
+ public IAndroidTarget target;
+ /** True if the user has manually modified the target */
+ public boolean targetModifiedByUser;
+
+ /** The location to store projects into */
+ public File projectLocation = new File(Platform.getLocation().toOSString());
+ /** True if the project location name has been manually edited by the user */
+ public boolean projectLocationModifiedByUser;
+
+ /** The name of the project */
+ public String projectName = ""; //$NON-NLS-1$
+ /** True if the project name has been manually edited by the user */
+ public boolean projectNameModifiedByUser;
+
+ /** The application name */
+ public String applicationName;
+ /** True if the application name has been manually edited by the user */
+ public boolean applicationNameModifiedByUser;
+
+ /** The package path */
+ public String packageName;
+ /** True if the package name has been manually edited by the user */
+ public boolean packageNameModifiedByUser;
+
+ /** True if a new activity should be created */
+ public boolean createActivity;
+
+ /** The name of the new activity to be created */
+ public String activityName;
+ /** True if the activity name has been manually edited by the user */
+ public boolean activityNameModifiedByUser;
+
+ /** The minimum SDK version to use with the project (may be null or blank) */
+ public String minSdk;
+ /** True if the minimum SDK version has been manually edited by the user */
+ public boolean minSdkModifiedByUser;
+ /**
+ * A list of paths to each of the available samples for the current SDK.
+ * The pair is (String: sample display name => File: sample directory).
+ * Note we want a list, not a map since we might have duplicates.
+ * */
+ public List<Pair<String, File>> samples = new ArrayList<Pair<String, File>>();
+ /** Path to the currently chosen sample */
+ public File chosenSample;
+
+ /** The name of the source folder, relative to the project root */
+ public String sourceFolder = SdkConstants.FD_SOURCES;
+ /** The set of chosen working sets to use when creating the project */
+ public IWorkingSet[] workingSets = new IWorkingSet[0];
+
+ /**
+ * A reference to a different project that the current test project will be
+ * testing.
+ */
+ public IProject testedProject;
+ /**
+ * If true, this test project should be testing itself, otherwise it will be
+ * testing the project pointed to by {@link #testedProject}.
+ */
+ public boolean testingSelf;
+
+ // NOTE: These apply only to creating paired projects; when isTest is true
+ // we're using
+ // the normal fields above
+ /**
+ * If true, create a test project along with this plain project which will
+ * be testing the plain project. (This flag only applies when creating
+ * normal projects.)
+ */
+ public boolean createPairProject;
+ /**
+ * The application name of the test application (only applies when
+ * {@link #createPairProject} is true)
+ */
+ public String testApplicationName;
+ /**
+ * True if the testing application name has been modified by the user (only
+ * applies when {@link #createPairProject} is true)
+ */
+ public boolean testApplicationNameModified;
+ /**
+ * The package name of the test application (only applies when
+ * {@link #createPairProject} is true)
+ */
+ public String testPackageName;
+ /**
+ * True if the testing package name has been modified by the user (only
+ * applies when {@link #createPairProject} is true)
+ */
+ public boolean testPackageModified;
+ /**
+ * The project name of the test project (only applies when
+ * {@link #createPairProject} is true)
+ */
+ public String testProjectName;
+ /**
+ * True if the testing project name has been modified by the user (only
+ * applies when {@link #createPairProject} is true)
+ */
+ public boolean testProjectModified;
+ /** Package name of the tested app */
+ public String testTargetPackageName;
+
+ /**
+ * Copy project into workspace? This flag only applies when importing
+ * projects (creating projects from existing source)
+ */
+ public boolean copyIntoWorkspace;
+
+ /**
+ * List of projects to be imported. Null if not importing projects.
+ */
+ @Nullable
+ public List<ImportedProject> importProjects;
+
+ /**
+ * Creates a new {@link NewProjectWizardState}
+ *
+ * @param mode the mode to run the wizard in
+ */
+ public NewProjectWizardState(Mode mode) {
+ this.mode = mode;
+ if (mode == Mode.SAMPLE) {
+ useExisting = true;
+ } else if (mode == Mode.TEST) {
+ createActivity = false;
+ }
+ }
+
+ /**
+ * Extract information (package name, application name, minimum SDK etc) from
+ * the given Android project.
+ *
+ * @param path the path to the project to extract information from
+ */
+ public void extractFromAndroidManifest(Path path) {
+ String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString();
+ if (!(new File(osPath).exists())) {
+ return;
+ }
+
+ ManifestData manifestData = AndroidManifestHelper.parseForData(osPath);
+ if (manifestData == null) {
+ return;
+ }
+
+ String newPackageName = null;
+ Activity activity = null;
+ String newActivityName = null;
+ String minSdkVersion = null;
+ try {
+ newPackageName = manifestData.getPackage();
+ minSdkVersion = manifestData.getMinSdkVersionString();
+
+ // try to get the first launcher activity. If none, just take the first activity.
+ activity = manifestData.getLauncherActivity();
+ if (activity == null) {
+ Activity[] activities = manifestData.getActivities();
+ if (activities != null && activities.length > 0) {
+ activity = activities[0];
+ }
+ }
+ } catch (Exception e) {
+ // ignore exceptions
+ }
+
+ if (newPackageName != null && newPackageName.length() > 0) {
+ packageName = newPackageName;
+ }
+
+ if (activity != null) {
+ newActivityName = AndroidManifest.extractActivityName(activity.getName(),
+ newPackageName);
+ }
+
+ if (newActivityName != null && newActivityName.length() > 0) {
+ activityName = newActivityName;
+ // we are "importing" an existing activity, not creating a new one
+ createActivity = false;
+
+ // If project name and application names are empty, use the activity
+ // name as a default. If the activity name has dots, it's a part of a
+ // package specification and only the last identifier must be used.
+ if (newActivityName.indexOf('.') != -1) {
+ String[] ids = newActivityName.split(AdtConstants.RE_DOT);
+ newActivityName = ids[ids.length - 1];
+ }
+ if (projectName == null || projectName.length() == 0 ||
+ !projectNameModifiedByUser) {
+ projectName = newActivityName;
+ projectNameModifiedByUser = false;
+ }
+ if (applicationName == null || applicationName.length() == 0 ||
+ !applicationNameModifiedByUser) {
+ applicationNameModifiedByUser = false;
+ applicationName = newActivityName;
+ }
+ } else {
+ activityName = ""; //$NON-NLS-1$
+
+ // There is no activity name to use to fill in the project and application
+ // name. However if there's a package name, we can use this as a base.
+ if (newPackageName != null && newPackageName.length() > 0) {
+ // Package name is a java identifier, so it's most suitable for
+ // an application name.
+
+ if (applicationName == null || applicationName.length() == 0 ||
+ !applicationNameModifiedByUser) {
+ applicationName = newPackageName;
+ }
+
+ // For the project name, remove any dots
+ newPackageName = newPackageName.replace('.', '_');
+ if (projectName == null || projectName.length() == 0 ||
+ !projectNameModifiedByUser) {
+ projectName = newPackageName;
+ }
+
+ }
+ }
+
+ if (mode == Mode.ANY && useExisting) {
+ updateSdkTargetToMatchProject(path.toFile());
+ }
+
+ minSdk = minSdkVersion;
+ minSdkModifiedByUser = false;
+ }
+
+ /**
+ * Try to find an SDK Target that matches the current MinSdkVersion.
+ *
+ * There can be multiple targets with the same sdk api version, so don't change
+ * it if it's already at the right version. Otherwise pick the first target
+ * that matches.
+ */
+ public void updateSdkTargetToMatchMinSdkVersion() {
+ IAndroidTarget currentTarget = target;
+ if (currentTarget != null && currentTarget.getVersion().equals(minSdk)) {
+ return;
+ }
+
+ Sdk sdk = Sdk.getCurrent();
+ if (sdk != null) {
+ IAndroidTarget[] targets = sdk.getTargets();
+ for (IAndroidTarget t : targets) {
+ if (t.getVersion().equals(minSdk)) {
+ target = t;
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the SDK to reflect the SDK required by the project at the given
+ * location
+ *
+ * @param location the location of the project
+ */
+ public void updateSdkTargetToMatchProject(File location) {
+ // Select the target matching the manifest's sdk or build properties, if any
+ IAndroidTarget foundTarget = null;
+ // This is the target currently in the UI
+ IAndroidTarget currentTarget = target;
+ String projectPath = location.getPath();
+
+ // If there's a current target defined, we do not allow to change it when
+ // operating in the create-from-sample mode -- since the available sample list
+ // is tied to the current target, so changing it would invalidate the project we're
+ // trying to load in the first place.
+ if (!targetModifiedByUser) {
+ ProjectProperties p = ProjectProperties.load(projectPath,
+ PropertyType.PROJECT);
+ if (p != null) {
+ String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
+ IAndroidTarget desiredTarget = Sdk.getCurrent().getTargetFromHashString(v);
+ // We can change the current target if:
+ // - we found a new desired target
+ // - there is no current target
+ // - or the current target can't run the desired target
+ if (desiredTarget != null &&
+ (currentTarget == null || !desiredTarget.canRunOn(currentTarget))) {
+ foundTarget = desiredTarget;
+ }
+ }
+
+ Sdk sdk = Sdk.getCurrent();
+ IAndroidTarget[] targets = null;
+ if (sdk != null) {
+ targets = sdk.getTargets();
+ }
+ if (targets == null) {
+ targets = new IAndroidTarget[0];
+ }
+
+ if (foundTarget == null && minSdk != null) {
+ // Otherwise try to match the requested min-sdk-version if we find an
+ // exact match, regardless of the currently selected target.
+ for (IAndroidTarget existingTarget : targets) {
+ if (existingTarget != null &&
+ existingTarget.getVersion().equals(minSdk)) {
+ foundTarget = existingTarget;
+ break;
+ }
+ }
+ }
+
+ if (foundTarget == null) {
+ // Or last attempt, try to match a sample project location and use it
+ // if we find an exact match, regardless of the currently selected target.
+ for (IAndroidTarget existingTarget : targets) {
+ if (existingTarget != null &&
+ projectPath.startsWith(existingTarget.getLocation())) {
+ foundTarget = existingTarget;
+ break;
+ }
+ }
+ }
+ }
+
+ if (foundTarget != null) {
+ target = foundTarget;
+ }
+ }
+
+ /**
+ * Type of project being offered/created by the wizard
+ */
+ public enum Mode {
+ /** Create a sample project. Testing options are not presented. */
+ SAMPLE,
+
+ /**
+ * Create a test project, either testing itself or some other project.
+ * Note that even if in the {@link #ANY} mode, a test project can be
+ * created as a *paired* project with the main project, so this flag
+ * only means that we are creating *just* a test project
+ */
+ TEST,
+
+ /**
+ * Create an Android project, which can be a plain project, optionally
+ * with a paired test project, or a sample project (the first page
+ * contains toggles for choosing which
+ */
+ ANY;
+ }
+}