diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java | 1520 |
1 files changed, 0 insertions, 1520 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java deleted file mode 100644 index d168c7503..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreator.java +++ /dev/null @@ -1,1520 +0,0 @@ -/* - * Copyright (C) 2007 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 static com.android.SdkConstants.FN_PROJECT_PROPERTIES; -import static com.android.sdklib.internal.project.ProjectProperties.PROPERTY_LIBRARY; - -import static org.eclipse.core.resources.IResource.DEPTH_ZERO; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.ide.common.res2.ValueXmlHelper; -import com.android.ide.common.xml.ManifestData; -import com.android.ide.common.xml.XmlFormatStyle; -import com.android.ide.eclipse.adt.AdtConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.AdtUtils; -import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences; -import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter; -import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; -import com.android.ide.eclipse.adt.internal.project.AndroidNature; -import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; -import com.android.ide.eclipse.adt.internal.project.ProjectHelper; -import com.android.ide.eclipse.adt.internal.sdk.ProjectState; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode; -import com.android.io.StreamException; -import com.android.resources.Density; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy; - -import org.eclipse.core.filesystem.EFS; -import org.eclipse.core.filesystem.IFileInfo; -import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.filesystem.IFileSystem; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceStatus; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jdt.core.IAccessRule; -import org.eclipse.jdt.core.IClasspathAttribute; -import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableContext; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IWorkingSet; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.WorkspaceModifyOperation; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * The actual project creator invoked from the New Project Wizard - * <p/> - * Note: this class is public so that it can be accessed from unit tests. - * It is however an internal class. Its API may change without notice. - * It should semantically be considered as a private final class. - */ -public class NewProjectCreator { - - private static final String PARAM_SDK_TOOLS_DIR = "ANDROID_SDK_TOOLS"; //$NON-NLS-1$ - private static final String PARAM_ACTIVITY = "ACTIVITY_NAME"; //$NON-NLS-1$ - private static final String PARAM_APPLICATION = "APPLICATION_NAME"; //$NON-NLS-1$ - private static final String PARAM_PACKAGE = "PACKAGE"; //$NON-NLS-1$ - private static final String PARAM_IMPORT_RESOURCE_CLASS = "IMPORT_RESOURCE_CLASS"; //$NON-NLS-1$ - private static final String PARAM_PROJECT = "PROJECT_NAME"; //$NON-NLS-1$ - private static final String PARAM_STRING_NAME = "STRING_NAME"; //$NON-NLS-1$ - private static final String PARAM_STRING_CONTENT = "STRING_CONTENT"; //$NON-NLS-1$ - private static final String PARAM_IS_NEW_PROJECT = "IS_NEW_PROJECT"; //$NON-NLS-1$ - private static final String PARAM_SAMPLE_LOCATION = "SAMPLE_LOCATION"; //$NON-NLS-1$ - private static final String PARAM_SOURCE = "SOURCE"; //$NON-NLS-1$ - private static final String PARAM_SRC_FOLDER = "SRC_FOLDER"; //$NON-NLS-1$ - private static final String PARAM_SDK_TARGET = "SDK_TARGET"; //$NON-NLS-1$ - private static final String PARAM_IS_LIBRARY = "IS_LIBRARY"; //$NON-NLS-1$ - private static final String PARAM_MIN_SDK_VERSION = "MIN_SDK_VERSION"; //$NON-NLS-1$ - // Warning: The expanded string PARAM_TEST_TARGET_PACKAGE must not contain the - // string "PACKAGE" since it collides with the replacement of PARAM_PACKAGE. - private static final String PARAM_TEST_TARGET_PACKAGE = "TEST_TARGET_PCKG"; //$NON-NLS-1$ - private static final String PARAM_TARGET_SELF = "TARGET_SELF"; //$NON-NLS-1$ - private static final String PARAM_TARGET_MAIN = "TARGET_MAIN"; //$NON-NLS-1$ - private static final String PARAM_TARGET_EXISTING = "TARGET_EXISTING"; //$NON-NLS-1$ - private static final String PARAM_REFERENCE_PROJECT = "REFERENCE_PROJECT"; //$NON-NLS-1$ - - private static final String PH_ACTIVITIES = "ACTIVITIES"; //$NON-NLS-1$ - private static final String PH_USES_SDK = "USES-SDK"; //$NON-NLS-1$ - private static final String PH_INTENT_FILTERS = "INTENT_FILTERS"; //$NON-NLS-1$ - private static final String PH_STRINGS = "STRINGS"; //$NON-NLS-1$ - private static final String PH_TEST_USES_LIBRARY = "TEST-USES-LIBRARY"; //$NON-NLS-1$ - private static final String PH_TEST_INSTRUMENTATION = "TEST-INSTRUMENTATION"; //$NON-NLS-1$ - - private static final String BIN_DIRECTORY = - SdkConstants.FD_OUTPUT + AdtConstants.WS_SEP; - private static final String BIN_CLASSES_DIRECTORY = - SdkConstants.FD_OUTPUT + AdtConstants.WS_SEP + - SdkConstants.FD_CLASSES_OUTPUT + AdtConstants.WS_SEP; - private static final String RES_DIRECTORY = - SdkConstants.FD_RESOURCES + AdtConstants.WS_SEP; - private static final String ASSETS_DIRECTORY = - SdkConstants.FD_ASSETS + AdtConstants.WS_SEP; - private static final String DRAWABLE_DIRECTORY = - SdkConstants.FD_RES_DRAWABLE + AdtConstants.WS_SEP; - private static final String DRAWABLE_XHDPI_DIRECTORY = - SdkConstants.FD_RES_DRAWABLE + '-' + Density.XHIGH.getResourceValue() + - AdtConstants.WS_SEP; - private static final String DRAWABLE_HDPI_DIRECTORY = - SdkConstants.FD_RES_DRAWABLE + '-' + Density.HIGH.getResourceValue() + - AdtConstants.WS_SEP; - private static final String DRAWABLE_MDPI_DIRECTORY = - SdkConstants.FD_RES_DRAWABLE + '-' + Density.MEDIUM.getResourceValue() + - AdtConstants.WS_SEP; - private static final String DRAWABLE_LDPI_DIRECTORY = - SdkConstants.FD_RES_DRAWABLE + '-' + Density.LOW.getResourceValue() + - AdtConstants.WS_SEP; - private static final String LAYOUT_DIRECTORY = - SdkConstants.FD_RES_LAYOUT + AdtConstants.WS_SEP; - private static final String VALUES_DIRECTORY = - SdkConstants.FD_RES_VALUES + AdtConstants.WS_SEP; - private static final String GEN_SRC_DIRECTORY = - SdkConstants.FD_GEN_SOURCES + AdtConstants.WS_SEP; - - private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$ - private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY - + "AndroidManifest.template"; //$NON-NLS-1$ - private static final String TEMPLATE_ACTIVITIES = TEMPLATES_DIRECTORY - + "activity.template"; //$NON-NLS-1$ - private static final String TEMPLATE_USES_SDK = TEMPLATES_DIRECTORY - + "uses-sdk.template"; //$NON-NLS-1$ - private static final String TEMPLATE_INTENT_LAUNCHER = TEMPLATES_DIRECTORY - + "launcher_intent_filter.template"; //$NON-NLS-1$ - private static final String TEMPLATE_TEST_USES_LIBRARY = TEMPLATES_DIRECTORY - + "test_uses-library.template"; //$NON-NLS-1$ - private static final String TEMPLATE_TEST_INSTRUMENTATION = TEMPLATES_DIRECTORY - + "test_instrumentation.template"; //$NON-NLS-1$ - - - - private static final String TEMPLATE_STRINGS = TEMPLATES_DIRECTORY - + "strings.template"; //$NON-NLS-1$ - private static final String TEMPLATE_STRING = TEMPLATES_DIRECTORY - + "string.template"; //$NON-NLS-1$ - private static final String PROJECT_ICON = "ic_launcher.png"; //$NON-NLS-1$ - private static final String ICON_XHDPI = "ic_launcher_xhdpi.png"; //$NON-NLS-1$ - private static final String ICON_HDPI = "ic_launcher_hdpi.png"; //$NON-NLS-1$ - private static final String ICON_MDPI = "ic_launcher_mdpi.png"; //$NON-NLS-1$ - private static final String ICON_LDPI = "ic_launcher_ldpi.png"; //$NON-NLS-1$ - - private static final String STRINGS_FILE = "strings.xml"; //$NON-NLS-1$ - - private static final String STRING_RSRC_PREFIX = SdkConstants.STRING_PREFIX; - private static final String STRING_APP_NAME = "app_name"; //$NON-NLS-1$ - private static final String STRING_HELLO_WORLD = "hello"; //$NON-NLS-1$ - - private static final String[] DEFAULT_DIRECTORIES = new String[] { - BIN_DIRECTORY, BIN_CLASSES_DIRECTORY, RES_DIRECTORY, ASSETS_DIRECTORY }; - private static final String[] RES_DIRECTORIES = new String[] { - DRAWABLE_DIRECTORY, LAYOUT_DIRECTORY, VALUES_DIRECTORY }; - private static final String[] RES_DENSITY_ENABLED_DIRECTORIES = new String[] { - DRAWABLE_XHDPI_DIRECTORY, - DRAWABLE_HDPI_DIRECTORY, DRAWABLE_MDPI_DIRECTORY, DRAWABLE_LDPI_DIRECTORY, - LAYOUT_DIRECTORY, VALUES_DIRECTORY }; - - private static final String JAVA_ACTIVITY_TEMPLATE = "java_file.template"; //$NON-NLS-1$ - private static final String LAYOUT_TEMPLATE = "layout.template"; //$NON-NLS-1$ - private static final String MAIN_LAYOUT_XML = "main.xml"; //$NON-NLS-1$ - - private final NewProjectWizardState mValues; - private final IRunnableContext mRunnableContext; - - /** - * Creates a new {@linkplain NewProjectCreator} - * @param values the wizard state with initial project parameters - * @param runnableContext the context to run project creation in - */ - public NewProjectCreator(NewProjectWizardState values, IRunnableContext runnableContext) { - mValues = values; - mRunnableContext = runnableContext; - } - - /** - * Before actually creating the project for a new project (as opposed to using an - * existing project), we check if the target location is a directory that either does - * not exist or is empty. - * - * If it's not empty, ask the user for confirmation. - * - * @param destination The destination folder where the new project is to be created. - * @return True if the destination doesn't exist yet or is an empty directory or is - * accepted by the user. - */ - private boolean validateNewProjectLocationIsEmpty(IPath destination) { - File f = new File(destination.toOSString()); - if (f.isDirectory() && f.list().length > 0) { - return AdtPlugin.displayPrompt("New Android Project", - "You are going to create a new Android Project in an existing, non-empty, directory. Are you sure you want to proceed?"); - } - return true; - } - - /** - * Structure that describes all the information needed to create a project. - * This is collected from the pages by {@link NewProjectCreator#createAndroidProjects()} - * and then used by - * {@link NewProjectCreator#createProjectAsync(IProgressMonitor, ProjectInfo, ProjectInfo)}. - */ - private static class ProjectInfo { - private final IProject mProject; - private final IProjectDescription mDescription; - private final Map<String, Object> mParameters; - private final HashMap<String, String> mDictionary; - - public ProjectInfo(IProject project, - IProjectDescription description, - Map<String, Object> parameters, - HashMap<String, String> dictionary) { - mProject = project; - mDescription = description; - mParameters = parameters; - mDictionary = dictionary; - } - - public IProject getProject() { - return mProject; - } - - public IProjectDescription getDescription() { - return mDescription; - } - - public Map<String, Object> getParameters() { - return mParameters; - } - - public HashMap<String, String> getDictionary() { - return mDictionary; - } - } - - /** - * Creates the android project. - * @return True if the project could be created. - */ - public boolean createAndroidProjects() { - if (mValues.importProjects != null && !mValues.importProjects.isEmpty()) { - return importProjects(); - } - - final ProjectInfo mainData = collectMainPageInfo(); - final ProjectInfo testData = collectTestPageInfo(); - - // Create a monitored operation to create the actual project - WorkspaceModifyOperation op = new WorkspaceModifyOperation() { - @Override - protected void execute(IProgressMonitor monitor) throws InvocationTargetException { - createProjectAsync(monitor, mainData, testData, null, true); - } - }; - - // Run the operation in a different thread - runAsyncOperation(op); - return true; - } - - /** - * Creates the a plain Java project without typical android directories or an Android Nature. - * This is intended for use by unit tests and not as a general-purpose Java project creator. - * @return True if the project could be created. - */ - @VisibleForTesting - public boolean createJavaProjects() { - if (mValues.importProjects != null && !mValues.importProjects.isEmpty()) { - return importProjects(); - } - - final ProjectInfo mainData = collectMainPageInfo(); - final ProjectInfo testData = collectTestPageInfo(); - - // Create a monitored operation to create the actual project - WorkspaceModifyOperation op = new WorkspaceModifyOperation() { - @Override - protected void execute(IProgressMonitor monitor) throws InvocationTargetException { - createProjectAsync(monitor, mainData, testData, null, false); - } - }; - - // Run the operation in a different thread - runAsyncOperation(op); - return true; - } - - /** - * Imports a list of projects - */ - private boolean importProjects() { - assert mValues.importProjects != null && !mValues.importProjects.isEmpty(); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - - final List<ProjectInfo> projectData = new ArrayList<ProjectInfo>(); - for (ImportedProject p : mValues.importProjects) { - - // Compute the project name and the package name from the manifest - ManifestData manifest = p.getManifest(); - if (manifest == null) { - continue; - } - String packageName = manifest.getPackage(); - String projectName = p.getProjectName(); - String minSdk = manifest.getMinSdkVersionString(); - - final IProject project = workspace.getRoot().getProject(projectName); - final IProjectDescription description = - workspace.newProjectDescription(project.getName()); - - final Map<String, Object> parameters = new HashMap<String, Object>(); - parameters.put(PARAM_PROJECT, projectName); - parameters.put(PARAM_PACKAGE, packageName); - parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder()); - parameters.put(PARAM_IS_NEW_PROJECT, Boolean.FALSE); - parameters.put(PARAM_SRC_FOLDER, SdkConstants.FD_SOURCES); - - parameters.put(PARAM_SDK_TARGET, p.getTarget()); - - // TODO: Find out if these end up getting used in the import-path through the code! - parameters.put(PARAM_MIN_SDK_VERSION, minSdk); - parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME); - final HashMap<String, String> dictionary = new HashMap<String, String>(); - dictionary.put(STRING_APP_NAME, mValues.applicationName); - - if (mValues.copyIntoWorkspace) { - parameters.put(PARAM_SOURCE, p.getLocation()); - - // TODO: Make sure it isn't *already* in the workspace! - //IPath defaultLocation = Platform.getLocation(); - //if ((!mValues.useDefaultLocation || mValues.useExisting) - // && !defaultLocation.isPrefixOf(path)) { - //IPath workspaceLocation = Platform.getLocation().append(projectName); - //description.setLocation(workspaceLocation); - // DON'T SET THE LOCATION: It's IMPLIED and in fact it will generate - // an error if you set it! - } else { - // Create in place - description.setLocation(new Path(p.getLocation().getPath())); - } - - projectData.add(new ProjectInfo(project, description, parameters, dictionary)); - } - - // Create a monitored operation to create the actual project - WorkspaceModifyOperation op = new WorkspaceModifyOperation() { - @Override - protected void execute(IProgressMonitor monitor) throws InvocationTargetException { - createProjectAsync(monitor, null, null, projectData, true); - } - }; - - // Run the operation in a different thread - runAsyncOperation(op); - return true; - } - - /** - * Collects all the parameters needed to create the main project. - * @return A new {@link ProjectInfo} on success. Returns null if the project cannot be - * created because parameters are incorrect or should not be created because there - * is no main page. - */ - private ProjectInfo collectMainPageInfo() { - if (mValues.mode == Mode.TEST) { - return null; - } - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - final IProject project = workspace.getRoot().getProject(mValues.projectName); - final IProjectDescription description = workspace.newProjectDescription(project.getName()); - - final Map<String, Object> parameters = new HashMap<String, Object>(); - parameters.put(PARAM_PROJECT, mValues.projectName); - parameters.put(PARAM_PACKAGE, mValues.packageName); - parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME); - parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder()); - parameters.put(PARAM_IS_NEW_PROJECT, mValues.mode == Mode.ANY && !mValues.useExisting); - parameters.put(PARAM_SAMPLE_LOCATION, mValues.chosenSample); - parameters.put(PARAM_SRC_FOLDER, mValues.sourceFolder); - parameters.put(PARAM_SDK_TARGET, mValues.target); - parameters.put(PARAM_MIN_SDK_VERSION, mValues.minSdk); - - if (mValues.createActivity) { - parameters.put(PARAM_ACTIVITY, mValues.activityName); - } - - // create a dictionary of string that will contain name+content. - // we'll put all the strings into values/strings.xml - final HashMap<String, String> dictionary = new HashMap<String, String>(); - dictionary.put(STRING_APP_NAME, mValues.applicationName); - - IPath path = new Path(mValues.projectLocation.getPath()); - IPath defaultLocation = Platform.getLocation(); - if ((!mValues.useDefaultLocation || mValues.useExisting) - && !defaultLocation.isPrefixOf(path)) { - description.setLocation(path); - } - - if (mValues.mode == Mode.ANY && !mValues.useExisting && !mValues.useDefaultLocation && - !validateNewProjectLocationIsEmpty(path)) { - return null; - } - - return new ProjectInfo(project, description, parameters, dictionary); - } - - /** - * Collects all the parameters needed to create the test project. - * - * @return A new {@link ProjectInfo} on success. Returns null if the project cannot be - * created because parameters are incorrect or should not be created because there - * is no test page. - */ - private ProjectInfo collectTestPageInfo() { - if (mValues.mode != Mode.TEST && !mValues.createPairProject) { - return null; - } - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - String projectName = - mValues.mode == Mode.TEST ? mValues.projectName : mValues.testProjectName; - final IProject project = workspace.getRoot().getProject(projectName); - final IProjectDescription description = workspace.newProjectDescription(project.getName()); - - final Map<String, Object> parameters = new HashMap<String, Object>(); - - String pkg = - mValues.mode == Mode.TEST ? mValues.packageName : mValues.testPackageName; - - parameters.put(PARAM_PACKAGE, pkg); - parameters.put(PARAM_APPLICATION, STRING_RSRC_PREFIX + STRING_APP_NAME); - parameters.put(PARAM_SDK_TOOLS_DIR, AdtPlugin.getOsSdkToolsFolder()); - parameters.put(PARAM_IS_NEW_PROJECT, !mValues.useExisting); - parameters.put(PARAM_SRC_FOLDER, mValues.sourceFolder); - parameters.put(PARAM_SDK_TARGET, mValues.target); - parameters.put(PARAM_MIN_SDK_VERSION, mValues.minSdk); - - // Test-specific parameters - String testedPkg = mValues.createPairProject - ? mValues.packageName : mValues.testTargetPackageName; - if (testedPkg == null) { - assert mValues.testingSelf; - testedPkg = pkg; - } - - parameters.put(PARAM_TEST_TARGET_PACKAGE, testedPkg); - - if (mValues.testingSelf) { - parameters.put(PARAM_TARGET_SELF, true); - } else { - parameters.put(PARAM_TARGET_EXISTING, true); - parameters.put(PARAM_REFERENCE_PROJECT, mValues.testedProject); - } - - if (mValues.createPairProject) { - parameters.put(PARAM_TARGET_MAIN, true); - } - - // create a dictionary of string that will contain name+content. - // we'll put all the strings into values/strings.xml - final HashMap<String, String> dictionary = new HashMap<String, String>(); - dictionary.put(STRING_APP_NAME, mValues.testApplicationName); - - // Use the same logic to determine test project location as in - // ApplicationInfoPage#validateTestProjectLocation - IPath path = new Path(mValues.projectLocation.getPath()); - path = path.removeLastSegments(1).append(mValues.testProjectName); - IPath defaultLocation = Platform.getLocation(); - if ((!mValues.useDefaultLocation || mValues.useExisting) - && !path.equals(defaultLocation)) { - description.setLocation(path); - } - - if (!mValues.useExisting && !mValues.useDefaultLocation && - !validateNewProjectLocationIsEmpty(path)) { - return null; - } - - return new ProjectInfo(project, description, parameters, dictionary); - } - - /** - * Runs the operation in a different thread and display generated - * exceptions. - * - * @param op The asynchronous operation to run. - */ - private void runAsyncOperation(WorkspaceModifyOperation op) { - try { - mRunnableContext.run(true /* fork */, true /* cancelable */, op); - } catch (InvocationTargetException e) { - - AdtPlugin.log(e, "New Project Wizard failed"); - - // The runnable threw an exception - Throwable t = e.getTargetException(); - if (t instanceof CoreException) { - CoreException core = (CoreException) t; - if (core.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { - // The error indicates the file system is not case sensitive - // and there's a resource with a similar name. - MessageDialog.openError(AdtPlugin.getShell(), - "Error", "Error: Case Variant Exists"); - } else { - ErrorDialog.openError(AdtPlugin.getShell(), - "Error", core.getMessage(), core.getStatus()); - } - } else { - // Some other kind of exception - String msg = t.getMessage(); - Throwable t1 = t; - while (msg == null && t1.getCause() != null) { - msg = t1.getMessage(); - t1 = t1.getCause(); - } - if (msg == null) { - msg = t.toString(); - } - MessageDialog.openError(AdtPlugin.getShell(), "Error", msg); - } - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * Creates the actual project(s). This is run asynchronously in a different thread. - * - * @param monitor An existing monitor. - * @param mainData Data for main project. Can be null. - * @param isAndroidProject true if the project is to be set up as a full Android project; false - * for a plain Java project. - * @throws InvocationTargetException to wrap any unmanaged exception and - * return it to the calling thread. The method can fail if it fails - * to create or modify the project or if it is canceled by the user. - */ - private void createProjectAsync(IProgressMonitor monitor, - ProjectInfo mainData, - ProjectInfo testData, - List<ProjectInfo> importData, - boolean isAndroidProject) - throws InvocationTargetException { - monitor.beginTask("Create Android Project", 100); - try { - IProject mainProject = null; - - if (mainData != null) { - mainProject = createEclipseProject( - new SubProgressMonitor(monitor, 50), - mainData.getProject(), - mainData.getDescription(), - mainData.getParameters(), - mainData.getDictionary(), - null, - isAndroidProject); - - if (mainProject != null) { - final IJavaProject javaProject = JavaCore.create(mainProject); - Display.getDefault().syncExec(new WorksetAdder(javaProject, - mValues.workingSets)); - } - } - - if (testData != null) { - Map<String, Object> parameters = testData.getParameters(); - if (parameters.containsKey(PARAM_TARGET_MAIN) && mainProject != null) { - parameters.put(PARAM_REFERENCE_PROJECT, mainProject); - } - - IProject testProject = createEclipseProject( - new SubProgressMonitor(monitor, 50), - testData.getProject(), - testData.getDescription(), - parameters, - testData.getDictionary(), - null, - isAndroidProject); - if (testProject != null) { - final IJavaProject javaProject = JavaCore.create(testProject); - Display.getDefault().syncExec(new WorksetAdder(javaProject, - mValues.workingSets)); - } - } - - if (importData != null) { - for (final ProjectInfo data : importData) { - ProjectPopulator projectPopulator = null; - if (mValues.copyIntoWorkspace) { - projectPopulator = new ProjectPopulator() { - @Override - public void populate(IProject project) { - // Copy - IFileSystem fileSystem = EFS.getLocalFileSystem(); - File source = (File) data.getParameters().get(PARAM_SOURCE); - IFileStore sourceDir = new ReadWriteFileStore( - fileSystem.getStore(source.toURI())); - IFileStore destDir = new ReadWriteFileStore( - fileSystem.getStore(AdtUtils.getAbsolutePath(project))); - try { - sourceDir.copy(destDir, EFS.OVERWRITE, null); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } - } - }; - } - IProject project = createEclipseProject( - new SubProgressMonitor(monitor, 50), - data.getProject(), - data.getDescription(), - data.getParameters(), - data.getDictionary(), - projectPopulator, - isAndroidProject); - if (project != null) { - final IJavaProject javaProject = JavaCore.create(project); - Display.getDefault().syncExec(new WorksetAdder(javaProject, - mValues.workingSets)); - ProjectHelper.enforcePreferredCompilerCompliance(javaProject); - } - } - } - } catch (CoreException e) { - throw new InvocationTargetException(e); - } catch (IOException e) { - throw new InvocationTargetException(e); - } catch (StreamException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - - /** Handler which can write contents into a project */ - public interface ProjectPopulator { - /** - * Add contents into the given project - * - * @param project the project to write into - * @throws InvocationTargetException if anything goes wrong - */ - public void populate(IProject project) throws InvocationTargetException; - } - - /** - * Creates the actual project, sets its nature and adds the required folders - * and files to it. This is run asynchronously in a different thread. - * - * @param monitor An existing monitor. - * @param project The project to create. - * @param description A description of the project. - * @param parameters Template parameters. - * @param dictionary String definition. - * @param isAndroidProject true if the project is to be set up as a full Android project; false - * for a plain Java project. - * @return The project newly created - * @throws StreamException - */ - private IProject createEclipseProject( - @NonNull IProgressMonitor monitor, - @NonNull IProject project, - @NonNull IProjectDescription description, - @NonNull Map<String, Object> parameters, - @Nullable Map<String, String> dictionary, - @Nullable ProjectPopulator projectPopulator, - boolean isAndroidProject) - throws CoreException, IOException, StreamException { - - // get the project target - IAndroidTarget target = (IAndroidTarget) parameters.get(PARAM_SDK_TARGET); - boolean legacy = isAndroidProject && target.getVersion().getApiLevel() < 4; - - // Create project and open it - project.create(description, new SubProgressMonitor(monitor, 10)); - if (monitor.isCanceled()) throw new OperationCanceledException(); - - project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 10)); - - // Add the Java and android nature to the project - AndroidNature.setupProjectNatures(project, monitor, isAndroidProject); - - // Create folders in the project if they don't already exist - addDefaultDirectories(project, AdtConstants.WS_ROOT, DEFAULT_DIRECTORIES, monitor); - String[] sourceFolders; - if (isAndroidProject) { - sourceFolders = new String[] { - (String) parameters.get(PARAM_SRC_FOLDER), - GEN_SRC_DIRECTORY - }; - } else { - sourceFolders = new String[] { - (String) parameters.get(PARAM_SRC_FOLDER) - }; - } - addDefaultDirectories(project, AdtConstants.WS_ROOT, sourceFolders, monitor); - - // Create the resource folders in the project if they don't already exist. - if (legacy) { - addDefaultDirectories(project, RES_DIRECTORY, RES_DIRECTORIES, monitor); - } else { - addDefaultDirectories(project, RES_DIRECTORY, RES_DENSITY_ENABLED_DIRECTORIES, monitor); - } - - if (projectPopulator != null) { - try { - projectPopulator.populate(project); - } catch (InvocationTargetException ite) { - AdtPlugin.log(ite, null); - } - } - - // Setup class path: mark folders as source folders - IJavaProject javaProject = JavaCore.create(project); - setupSourceFolders(javaProject, sourceFolders, monitor); - - if (((Boolean) parameters.get(PARAM_IS_NEW_PROJECT)).booleanValue()) { - // Create files in the project if they don't already exist - addManifest(project, parameters, dictionary, monitor); - - // add the default app icon - addIcon(project, legacy, monitor); - - // Create the default package components - addSampleCode(project, sourceFolders[0], parameters, dictionary, monitor); - - // add the string definition file if needed - if (dictionary != null && dictionary.size() > 0) { - addStringDictionaryFile(project, dictionary, monitor); - } - - // add the default proguard config - File libFolder = new File((String) parameters.get(PARAM_SDK_TOOLS_DIR), - SdkConstants.FD_LIB); - addLocalFile(project, - new File(libFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), - // Write ProGuard config files with the extension .pro which - // is what is used in the ProGuard documentation and samples - SdkConstants.FN_PROJECT_PROGUARD_FILE, - monitor); - - // Set output location - javaProject.setOutputLocation(project.getFolder(BIN_CLASSES_DIRECTORY).getFullPath(), - monitor); - } - - File sampleDir = (File) parameters.get(PARAM_SAMPLE_LOCATION); - if (sampleDir != null) { - // Copy project - copySampleCode(project, sampleDir, parameters, dictionary, monitor); - } - - // Create the reference to the target project - if (parameters.containsKey(PARAM_REFERENCE_PROJECT)) { - IProject refProject = (IProject) parameters.get(PARAM_REFERENCE_PROJECT); - if (refProject != null) { - IProjectDescription desc = project.getDescription(); - - // Add out reference to the existing project reference. - // We just created a project with no references so we don't need to expand - // the currently-empty current list. - desc.setReferencedProjects(new IProject[] { refProject }); - - project.setDescription(desc, IResource.KEEP_HISTORY, - new SubProgressMonitor(monitor, 10)); - - IClasspathEntry entry = JavaCore.newProjectEntry( - refProject.getFullPath(), //path - new IAccessRule[0], //accessRules - false, //combineAccessRules - new IClasspathAttribute[0], //extraAttributes - false //isExported - - ); - ProjectHelper.addEntryToClasspath(javaProject, entry); - } - } - - if (isAndroidProject) { - Sdk.getCurrent().initProject(project, target); - } - - // Fix the project to make sure all properties are as expected. - // Necessary for existing projects and good for new ones to. - ProjectHelper.fixProject(project); - - Boolean isLibraryProject = (Boolean) parameters.get(PARAM_IS_LIBRARY); - if (isLibraryProject != null && isLibraryProject.booleanValue() - && Sdk.getCurrent() != null && project.isOpen()) { - ProjectState state = Sdk.getProjectState(project); - if (state != null) { - // make a working copy of the properties - ProjectPropertiesWorkingCopy properties = - state.getProperties().makeWorkingCopy(); - - properties.setProperty(PROPERTY_LIBRARY, Boolean.TRUE.toString()); - try { - properties.save(); - IResource projectProp = project.findMember(FN_PROJECT_PROPERTIES); - if (projectProp != null) { - projectProp.refreshLocal(DEPTH_ZERO, new NullProgressMonitor()); - } - } catch (Exception e) { - String msg = String.format( - "Failed to save %1$s for project %2$s", - SdkConstants.FN_PROJECT_PROPERTIES, project.getName()); - AdtPlugin.log(e, msg); - } - } - } - - return project; - } - - /** - * Creates a new project - * - * @param monitor An existing monitor. - * @param project The project to create. - * @param target the build target to associate with the project - * @param projectPopulator a handler for writing the template contents - * @param isLibrary whether this project should be marked as a library project - * @param projectLocation the location to write the project into - * @param workingSets Eclipse working sets, if any, to add the project to - * @throws CoreException if anything goes wrong - */ - public static void create( - @NonNull IProgressMonitor monitor, - @NonNull final IProject project, - @NonNull IAndroidTarget target, - @Nullable final ProjectPopulator projectPopulator, - boolean isLibrary, - @NonNull String projectLocation, - @NonNull final IWorkingSet[] workingSets) - throws CoreException { - final NewProjectCreator creator = new NewProjectCreator(null, null); - - final Map<String, String> dictionary = null; - final Map<String, Object> parameters = new HashMap<String, Object>(); - parameters.put(PARAM_SDK_TARGET, target); - parameters.put(PARAM_SRC_FOLDER, SdkConstants.FD_SOURCES); - parameters.put(PARAM_IS_NEW_PROJECT, false); - parameters.put(PARAM_SAMPLE_LOCATION, null); - parameters.put(PARAM_IS_LIBRARY, isLibrary); - - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - final IProjectDescription description = workspace.newProjectDescription(project.getName()); - - if (projectLocation != null) { - IPath path = new Path(projectLocation); - IPath parent = new Path(path.toFile().getParent()); - IPath workspaceLocation = Platform.getLocation(); - if (!workspaceLocation.equals(parent)) { - description.setLocation(path); - } - } - - IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() { - @Override - public void run(IProgressMonitor submonitor) throws CoreException { - try { - creator.createEclipseProject(submonitor, project, description, parameters, - dictionary, projectPopulator, true); - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Unexpected error while creating project", e)); - } catch (StreamException e) { - throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Unexpected error while creating project", e)); - } - if (workingSets != null && workingSets.length > 0) { - IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); - if (javaProject != null) { - Display.getDefault().syncExec(new WorksetAdder(javaProject, - workingSets)); - } - } - } - }; - - ResourcesPlugin.getWorkspace().run(workspaceRunnable, monitor); - } - - /** - * Adds default directories to the project. - * - * @param project The Java Project to update. - * @param parentFolder The path of the parent folder. Must end with a - * separator. - * @param folders Folders to be added. - * @param monitor An existing monitor. - * @throws CoreException if the method fails to create the directories in - * the project. - */ - private void addDefaultDirectories(IProject project, String parentFolder, - String[] folders, IProgressMonitor monitor) throws CoreException { - for (String name : folders) { - if (name.length() > 0) { - IFolder folder = project.getFolder(parentFolder + name); - if (!folder.exists()) { - folder.create(true /* force */, true /* local */, - new SubProgressMonitor(monitor, 10)); - } - } - } - } - - /** - * Adds the manifest to the project. - * - * @param project The Java Project to update. - * @param parameters Template Parameters. - * @param dictionary String List to be added to a string definition - * file. This map will be filled by this method. - * @param monitor An existing monitor. - * @throws CoreException if the method fails to update the project. - * @throws IOException if the method fails to create the files in the - * project. - */ - private void addManifest(IProject project, Map<String, Object> parameters, - Map<String, String> dictionary, IProgressMonitor monitor) - throws CoreException, IOException { - - // get IFile to the manifest and check if it's not already there. - IFile file = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML); - if (!file.exists()) { - - // Read manifest template - String manifestTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_MANIFEST); - - // Replace all keyword parameters - manifestTemplate = replaceParameters(manifestTemplate, parameters); - - if (manifestTemplate == null) { - // Inform the user there will be not manifest. - AdtPlugin.logAndPrintError(null, "Create Project" /*TAG*/, - "Failed to generate the Android manifest. Missing template %s", - TEMPLATE_MANIFEST); - // Abort now, there's no need to continue - return; - } - - if (parameters.containsKey(PARAM_ACTIVITY)) { - // now get the activity template - String activityTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_ACTIVITIES); - - // If the activity name doesn't contain any dot, it's in the form - // "ClassName" and we need to expand it to ".ClassName" in the XML. - String name = (String) parameters.get(PARAM_ACTIVITY); - if (name.indexOf('.') == -1) { - // Duplicate the parameters map to avoid changing the caller - parameters = new HashMap<String, Object>(parameters); - parameters.put(PARAM_ACTIVITY, "." + name); //$NON-NLS-1$ - } - - // Replace all keyword parameters to make main activity. - String activities = replaceParameters(activityTemplate, parameters); - - // set the intent. - String intent = AdtPlugin.readEmbeddedTextFile(TEMPLATE_INTENT_LAUNCHER); - - if (activities != null) { - if (intent != null) { - // set the intent to the main activity - activities = activities.replaceAll(PH_INTENT_FILTERS, intent); - } - - // set the activity(ies) in the manifest - manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, activities); - } - } else { - // remove the activity(ies) from the manifest - manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, ""); //$NON-NLS-1$ - } - - // Handle the case of the test projects - if (parameters.containsKey(PARAM_TEST_TARGET_PACKAGE)) { - // Set the uses-library needed by the test project - String usesLibrary = AdtPlugin.readEmbeddedTextFile(TEMPLATE_TEST_USES_LIBRARY); - if (usesLibrary != null) { - manifestTemplate = manifestTemplate.replaceAll( - PH_TEST_USES_LIBRARY, usesLibrary); - } - - // Set the instrumentation element needed by the test project - String instru = AdtPlugin.readEmbeddedTextFile(TEMPLATE_TEST_INSTRUMENTATION); - if (instru != null) { - manifestTemplate = manifestTemplate.replaceAll( - PH_TEST_INSTRUMENTATION, instru); - } - - // Replace PARAM_TEST_TARGET_PACKAGE itself now - manifestTemplate = replaceParameters(manifestTemplate, parameters); - - } else { - // remove the unused entries - manifestTemplate = manifestTemplate.replaceAll(PH_TEST_USES_LIBRARY, ""); //$NON-NLS-1$ - manifestTemplate = manifestTemplate.replaceAll(PH_TEST_INSTRUMENTATION, ""); //$NON-NLS-1$ - } - - String minSdkVersion = (String) parameters.get(PARAM_MIN_SDK_VERSION); - if (minSdkVersion != null && minSdkVersion.length() > 0) { - String usesSdkTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_USES_SDK); - if (usesSdkTemplate != null) { - String usesSdk = replaceParameters(usesSdkTemplate, parameters); - manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, usesSdk); - } - } else { - manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, ""); - } - - // Reformat the file according to the user's formatting settings - manifestTemplate = reformat(XmlFormatStyle.MANIFEST, manifestTemplate); - - // Save in the project as UTF-8 - InputStream stream = new ByteArrayInputStream( - manifestTemplate.getBytes("UTF-8")); //$NON-NLS-1$ - file.create(stream, false /* force */, new SubProgressMonitor(monitor, 10)); - } - } - - /** - * Adds the string resource file. - * - * @param project The Java Project to update. - * @param strings The list of strings to be added to the string file. - * @param monitor An existing monitor. - * @throws CoreException if the method fails to update the project. - * @throws IOException if the method fails to create the files in the - * project. - */ - private void addStringDictionaryFile(IProject project, - Map<String, String> strings, IProgressMonitor monitor) - throws CoreException, IOException { - - // create the IFile object and check if the file doesn't already exist. - IFile file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP - + VALUES_DIRECTORY + AdtConstants.WS_SEP + STRINGS_FILE); - if (!file.exists()) { - // get the Strings.xml template - String stringDefinitionTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_STRINGS); - - // get the template for one string - String stringTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_STRING); - - // get all the string names - Set<String> stringNames = strings.keySet(); - - // loop on it and create the string definitions - StringBuilder stringNodes = new StringBuilder(); - for (String key : stringNames) { - // get the value from the key - String value = strings.get(key); - - // Escape values if necessary - value = ValueXmlHelper.escapeResourceString(value); - - // place them in the template - String stringDef = stringTemplate.replace(PARAM_STRING_NAME, key); - stringDef = stringDef.replace(PARAM_STRING_CONTENT, value); - - // append to the other string - if (stringNodes.length() > 0) { - stringNodes.append('\n'); - } - stringNodes.append(stringDef); - } - - // put the string nodes in the Strings.xml template - stringDefinitionTemplate = stringDefinitionTemplate.replace(PH_STRINGS, - stringNodes.toString()); - - // reformat the file according to the user's formatting settings - stringDefinitionTemplate = reformat(XmlFormatStyle.RESOURCE, stringDefinitionTemplate); - - // write the file as UTF-8 - InputStream stream = new ByteArrayInputStream( - stringDefinitionTemplate.getBytes("UTF-8")); //$NON-NLS-1$ - file.create(stream, false /* force */, new SubProgressMonitor(monitor, 10)); - } - } - - /** Reformats the given contents with the current formatting settings */ - private String reformat(XmlFormatStyle style, String contents) { - if (AdtPrefs.getPrefs().getUseCustomXmlFormatter()) { - EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create(); - return EclipseXmlPrettyPrinter.prettyPrint(contents, formatPrefs, style, - null /*lineSeparator*/); - } else { - return contents; - } - } - - /** - * Adds default application icon to the project. - * - * @param project The Java Project to update. - * @param legacy whether we're running in legacy mode (no density support) - * @param monitor An existing monitor. - * @throws CoreException if the method fails to update the project. - */ - private void addIcon(IProject project, boolean legacy, IProgressMonitor monitor) - throws CoreException { - if (legacy) { // density support - // do medium density icon only, in the default drawable folder. - IFile file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP - + DRAWABLE_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON); - if (!file.exists()) { - addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_MDPI), monitor); - } - } else { - // do all 4 icons. - IFile file; - - // extra high density - file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP - + DRAWABLE_XHDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON); - if (!file.exists()) { - addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_XHDPI), monitor); - } - - // high density - file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP - + DRAWABLE_HDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON); - if (!file.exists()) { - addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_HDPI), monitor); - } - - // medium density - file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP - + DRAWABLE_MDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON); - if (!file.exists()) { - addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_MDPI), monitor); - } - - // low density - file = project.getFile(RES_DIRECTORY + AdtConstants.WS_SEP - + DRAWABLE_LDPI_DIRECTORY + AdtConstants.WS_SEP + PROJECT_ICON); - if (!file.exists()) { - addFile(file, AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON_LDPI), monitor); - } - } - } - - /** - * Creates a file from a data source. - * @param dest the file to write - * @param source the content of the file. - * @param monitor the progress monitor - * @throws CoreException - */ - private void addFile(IFile dest, byte[] source, IProgressMonitor monitor) throws CoreException { - if (source != null) { - // Save in the project - InputStream stream = new ByteArrayInputStream(source); - dest.create(stream, false /* force */, new SubProgressMonitor(monitor, 10)); - } - } - - /** - * Creates the package folder and copies the sample code in the project. - * - * @param project The Java Project to update. - * @param parameters Template Parameters. - * @param dictionary String List to be added to a string definition - * file. This map will be filled by this method. - * @param monitor An existing monitor. - * @throws CoreException if the method fails to update the project. - * @throws IOException if the method fails to create the files in the - * project. - */ - private void addSampleCode(IProject project, String sourceFolder, - Map<String, Object> parameters, Map<String, String> dictionary, - IProgressMonitor monitor) throws CoreException, IOException { - // create the java package directories. - IFolder pkgFolder = project.getFolder(sourceFolder); - String packageName = (String) parameters.get(PARAM_PACKAGE); - - // The PARAM_ACTIVITY key will be absent if no activity should be created, - // in which case activityName will be null. - String activityName = (String) parameters.get(PARAM_ACTIVITY); - - Map<String, Object> java_activity_parameters = new HashMap<String, Object>(parameters); - java_activity_parameters.put(PARAM_IMPORT_RESOURCE_CLASS, ""); //$NON-NLS-1$ - - if (activityName != null) { - - String resourcePackageClass = null; - - // An activity name can be of the form ".package.Class", ".Class" or FQDN. - // The initial dot is ignored, as it is always added later in the templates. - int lastDotIndex = activityName.lastIndexOf('.'); - - if (lastDotIndex != -1) { - - // Resource class - if (lastDotIndex > 0) { - resourcePackageClass = packageName + '.' + SdkConstants.FN_RESOURCE_BASE; - } - - // Package name - if (activityName.startsWith(".")) { //$NON-NLS-1$ - packageName += activityName.substring(0, lastDotIndex); - } else { - packageName = activityName.substring(0, lastDotIndex); - } - - // Activity Class name - activityName = activityName.substring(lastDotIndex + 1); - } - - java_activity_parameters.put(PARAM_ACTIVITY, activityName); - java_activity_parameters.put(PARAM_PACKAGE, packageName); - if (resourcePackageClass != null) { - String importResourceClass = "\nimport " + resourcePackageClass + ";"; //$NON-NLS-1$ // $NON-NLS-2$ - java_activity_parameters.put(PARAM_IMPORT_RESOURCE_CLASS, importResourceClass); - } - } - - String[] components = packageName.split(AdtConstants.RE_DOT); - for (String component : components) { - pkgFolder = pkgFolder.getFolder(component); - if (!pkgFolder.exists()) { - pkgFolder.create(true /* force */, true /* local */, - new SubProgressMonitor(monitor, 10)); - } - } - - if (activityName != null) { - // create the main activity Java file - String activityJava = activityName + SdkConstants.DOT_JAVA; - IFile file = pkgFolder.getFile(activityJava); - if (!file.exists()) { - copyFile(JAVA_ACTIVITY_TEMPLATE, file, java_activity_parameters, monitor, false); - } - - // create the layout file (if we're creating an - IFolder layoutfolder = project.getFolder(RES_DIRECTORY).getFolder(LAYOUT_DIRECTORY); - file = layoutfolder.getFile(MAIN_LAYOUT_XML); - if (!file.exists()) { - copyFile(LAYOUT_TEMPLATE, file, parameters, monitor, true); - dictionary.put(STRING_HELLO_WORLD, String.format("Hello World, %1$s!", - activityName)); - } - } - } - - private void copySampleCode(IProject project, File sampleDir, - Map<String, Object> parameters, Map<String, String> dictionary, - IProgressMonitor monitor) throws CoreException { - // Copy the sampleDir into the project directory recursively - IFileSystem fileSystem = EFS.getLocalFileSystem(); - IFileStore sourceDir = new ReadWriteFileStore( - fileSystem.getStore(sampleDir.toURI())); - IFileStore destDir = new ReadWriteFileStore( - fileSystem.getStore(AdtUtils.getAbsolutePath(project))); - sourceDir.copy(destDir, EFS.OVERWRITE, null); - } - - /** - * In a sample we never duplicate source files as read-only. - * This creates a store that read files attributes and doesn't set the r-o flag. - */ - private static class ReadWriteFileStore extends FileStoreAdapter { - - public ReadWriteFileStore(IFileStore store) { - super(store); - } - - // Override when reading attributes - @Override - public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException { - IFileInfo info = super.fetchInfo(options, monitor); - info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); - return info; - } - - // Override when writing attributes - @Override - public void putInfo(IFileInfo info, int options, IProgressMonitor storeMonitor) - throws CoreException { - info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); - super.putInfo(info, options, storeMonitor); - } - - @Deprecated - @Override - public IFileStore getChild(IPath path) { - IFileStore child = super.getChild(path); - if (!(child instanceof ReadWriteFileStore)) { - child = new ReadWriteFileStore(child); - } - return child; - } - - @Override - public IFileStore getChild(String name) { - return new ReadWriteFileStore(super.getChild(name)); - } - } - - /** - * Adds a file to the root of the project - * @param project the project to add the file to. - * @param destName the name to write the file as - * @param source the file to add. It'll keep the same filename once copied into the project. - * @param monitor the monitor to report progress to - * @throws FileNotFoundException if the file to be added does not exist - * @throws CoreException if writing the file does not work - */ - public static void addLocalFile(IProject project, File source, String destName, - IProgressMonitor monitor) throws FileNotFoundException, CoreException { - IFile dest = project.getFile(destName); - if (dest.exists() == false) { - FileInputStream stream = new FileInputStream(source); - dest.create(stream, false /* force */, new SubProgressMonitor(monitor, 10)); - } - } - - /** - * Adds the given folder to the project's class path. - * - * @param javaProject The Java Project to update. - * @param sourceFolders Template Parameters. - * @param monitor An existing monitor. - * @throws JavaModelException if the classpath could not be set. - */ - private void setupSourceFolders(IJavaProject javaProject, String[] sourceFolders, - IProgressMonitor monitor) throws JavaModelException { - IProject project = javaProject.getProject(); - - // get the list of entries. - IClasspathEntry[] entries = javaProject.getRawClasspath(); - - // remove the project as a source folder (This is the default) - entries = removeSourceClasspath(entries, project); - - // add the source folders. - for (String sourceFolder : sourceFolders) { - IFolder srcFolder = project.getFolder(sourceFolder); - - // remove it first in case. - entries = removeSourceClasspath(entries, srcFolder); - entries = ProjectHelper.addEntryToClasspath(entries, - JavaCore.newSourceEntry(srcFolder.getFullPath())); - } - - javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 10)); - } - - - /** - * Removes the corresponding source folder from the class path entries if - * found. - * - * @param entries The class path entries to read. A copy will be returned. - * @param folder The parent source folder to remove. - * @return A new class path entries array. - */ - private IClasspathEntry[] removeSourceClasspath(IClasspathEntry[] entries, IContainer folder) { - if (folder == null) { - return entries; - } - IClasspathEntry source = JavaCore.newSourceEntry(folder.getFullPath()); - int n = entries.length; - for (int i = n - 1; i >= 0; i--) { - if (entries[i].equals(source)) { - IClasspathEntry[] newEntries = new IClasspathEntry[n - 1]; - if (i > 0) System.arraycopy(entries, 0, newEntries, 0, i); - if (i < n - 1) System.arraycopy(entries, i + 1, newEntries, i, n - i - 1); - n--; - entries = newEntries; - } - } - return entries; - } - - - /** - * Copies the given file from our resource folder to the new project. - * Expects the file to the US-ASCII or UTF-8 encoded. - * - * @throws CoreException from IFile if failing to create the new file. - * @throws MalformedURLException from URL if failing to interpret the URL. - * @throws FileNotFoundException from RandomAccessFile. - * @throws IOException from RandomAccessFile.length() if can't determine the - * length. - */ - private void copyFile(String resourceFilename, IFile destFile, - Map<String, Object> parameters, IProgressMonitor monitor, boolean reformat) - throws CoreException, IOException { - - // Read existing file. - String template = AdtPlugin.readEmbeddedTextFile( - TEMPLATES_DIRECTORY + resourceFilename); - - // Replace all keyword parameters - template = replaceParameters(template, parameters); - - if (reformat) { - // Guess the formatting style based on the file location - XmlFormatStyle style = EclipseXmlPrettyPrinter - .getForFile(destFile.getProjectRelativePath()); - if (style != null) { - template = reformat(style, template); - } - } - - // Save in the project as UTF-8 - InputStream stream = new ByteArrayInputStream(template.getBytes("UTF-8")); //$NON-NLS-1$ - destFile.create(stream, false /* force */, new SubProgressMonitor(monitor, 10)); - } - - /** - * Replaces placeholders found in a string with values. - * - * @param str the string to search for placeholders. - * @param parameters a map of <placeholder, Value> to search for in the string - * @return A new String object with the placeholder replaced by the values. - */ - private String replaceParameters(String str, Map<String, Object> parameters) { - - if (parameters == null) { - AdtPlugin.log(IStatus.ERROR, - "NPW replace parameters: null parameter map. String: '%s'", str); //$NON-NLS-1$ - return str; - } else if (str == null) { - AdtPlugin.log(IStatus.ERROR, - "NPW replace parameters: null template string"); //$NON-NLS-1$ - return str; - } - - for (Entry<String, Object> entry : parameters.entrySet()) { - if (entry != null && entry.getValue() instanceof String) { - Object value = entry.getValue(); - if (value == null) { - AdtPlugin.log(IStatus.ERROR, - "NPW replace parameters: null value for key '%s' in template '%s'", //$NON-NLS-1$ - entry.getKey(), - str); - } else { - str = str.replaceAll(entry.getKey(), (String) value); - } - } - } - - return str; - } - - private static class WorksetAdder implements Runnable { - private final IJavaProject mProject; - private final IWorkingSet[] mWorkingSets; - - private WorksetAdder(IJavaProject project, IWorkingSet[] workingSets) { - mProject = project; - mWorkingSets = workingSets; - } - - @Override - public void run() { - if (mWorkingSets.length > 0 && mProject != null - && mProject.exists()) { - PlatformUI.getWorkbench().getWorkingSetManager() - .addToWorkingSets(mProject, mWorkingSets); - } - } - } -} |