com.motorola.studio.android.model.ProjectCreationSupport.java Source code

Java tutorial

Introduction

Here is the source code for com.motorola.studio.android.model.ProjectCreationSupport.java

Source

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.motorola.studio.android.model;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.IWorkspaceRoot;
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.SubProgressMonitor;
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.wizard.IWizardContainer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.actions.WorkspaceModifyOperation;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.motorola.studio.android.AndroidPlugin;
import com.motorola.studio.android.adt.ProjectUtils;
import com.motorola.studio.android.adt.SdkUtils;
import com.motorola.studio.android.common.IAndroidConstants;
import com.motorola.studio.android.common.exception.AndroidException;
import com.motorola.studio.android.common.log.StudioLogger;
import com.motorola.studio.android.common.utilities.AndroidStatus;
import com.motorola.studio.android.common.utilities.EclipseUtils;
import com.motorola.studio.android.common.utilities.FileUtil;
import com.motorola.studio.android.i18n.AndroidNLS;
import com.motorola.studio.android.model.AndroidProject.SourceTypes;

/**
 * Project Creation Support. 
 */
public class ProjectCreationSupport {
    /**
     * Only static calls
     */
    private ProjectCreationSupport() {
    }

    private static final String PACKAGE_NAME = "PACKAGE"; //$NON-NLS-1$

    private static final String APP_NAME = "app_name"; //$NON-NLS-1$

    private static final String APPLICATION_NAME = "APPLICATION_NAME"; //$NON-NLS-1$

    private static final String STRING_RSRC_PREFIX = "@string/"; //$NON-NLS-1$

    private static final String MIN_SDK_VERSION = "MIN_SDK_VERSION"; //$NON-NLS-1$

    private static final String BIN_DIR = IAndroidConstants.FD_OUTPUT + IPath.SEPARATOR;

    private static final String RES_DIR = IAndroidConstants.FD_RESOURCES + IPath.SEPARATOR;

    private static final String ASSETS_DIR = IAndroidConstants.FD_ASSETS + IPath.SEPARATOR;

    private static final String DRAWABLE_DIR = IAndroidConstants.FD_DRAWABLE;

    private static final String LAYOUT_DIR = IAndroidConstants.FD_LAYOUT + IPath.SEPARATOR;

    private static final String VALUES_DIR = IAndroidConstants.FD_VALUES + IPath.SEPARATOR;

    private static final String GEN_DIR = IAndroidConstants.FD_GEN_SOURCES + IPath.SEPARATOR;

    private static final String XML_DIR = "xml" + IPath.SEPARATOR;

    private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$

    private static final String MANIFEST_TEMPLATE = TEMPLATES_DIRECTORY + "AndroidManifest.template"; //$NON-NLS-1$

    private static final String ACTIVITY_NAME = "ACTIVITY_NAME"; //$NON-NLS-1$

    private static final String ACTIVITY_TEMPLATE = TEMPLATES_DIRECTORY + "activity.template"; //$NON-NLS-1$

    private static final String LAUNCHER_INTENT_TEMPLATE = TEMPLATES_DIRECTORY + "launcher_intent_filter.template"; //$NON-NLS-1$

    private static final String INTENT_FILTERS = "INTENT_FILTERS"; //$NON-NLS-1$

    private static final String ACTIVITIES = "ACTIVITIES"; //$NON-NLS-1$

    private static final String USES_SDK_TEMPLATE = TEMPLATES_DIRECTORY + "uses-sdk.template"; //$NON-NLS-1$

    private static final String USES_SDK = "USES-SDK"; //$NON-NLS-1$

    private static final String ICON = "ic_launcher.png"; //$NON-NLS-1$

    private static final String JAVA_ACTIVITY_TEMPLATE = "java_file.template"; //$NON-NLS-1$

    private static final String MAIN_LAYOUT_XML = "main.xml"; //$NON-NLS-1$

    private static final String LAYOUT_TEMPLATE = "layout.template"; //$NON-NLS-1$

    private static final String STRING_HELLO_WORLD = "hello"; //$NON-NLS-1$    

    private static final String TEST_USES_LIBRARY = "TEST-USES-LIBRARY"; //$NON-NLS-1$

    private static final String TEST_INSTRUMENTATION = "TEST-INSTRUMENTATION"; //$NON-NLS-1$

    private static final String[] DPIS = { "hdpi", "ldpi", "mdpi" };

    /*
     * Widget Project manifest creation constants
     */

    private static final String WIDGET_TEMPLATE_FOLDER = "templates/widget_project/";

    private static final String WIDGET_MANIFEST_TEMPLATE_PATH = "templates/widget_project/AndroidWidgetManifest.template"; //$NON-NLS-1$

    private static final String WIDGET_ACTIVITY_TEMPLATE_PATH = "templates/widget_project/activity.template"; //$NON-NLS-1$

    private static final String WIDGET_RECEIVER_TEMPLATE_PATH = "templates/widget_project/receiver.template"; //$NON-NLS-1$

    private static final String WIDGET_USES_SDK_TEMPLATE_PATH = "templates/widget_project/uses-sdk.template"; //$NON-NLS-1$

    private static final String RECEIVERS = "RECEIVERS"; //$NON-NLS-1$

    private static final String WIDGET_INITIAL_LAYOUT_XML = "widget_initial_layout.xml"; //$NON-NLS-1$

    private static final String WIDGET_INFO_XML = "widget_info.xml"; //$NON-NLS-1$

    private static final String WIDGET_PROVIDER_SAMPLE_NAME = "WidgetProvider"; //$NON-NLS-1$

    private static final String WIDGET_PROVIDER_SAMPLE_TEMPLATE = "WidgetProvider.template"; //$NON-NLS-1$

    private static final String IMPORT_RESOURCE_CLASS = "IMPORT_RESOURCE_CLASS";

    /**
     * Create a new Android Project
     * @param androidProject
     * @param container
     * @return
     * @throws AndroidException
     */
    public static boolean createProject(final AndroidProject androidProject, IWizardContainer container)
            throws AndroidException {
        boolean created = true;

        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        final IProject project = workspace.getRoot().getProject(androidProject.getName());

        if (!canCreateProject(workspace.getRoot(), androidProject.getName())) {
            throw new AndroidException(AndroidNLS.EXC_ProjectCreationSupport_CannotCreateProjectReadOnlyWorkspace);
        } else {

            final IProjectDescription description = workspace.newProjectDescription(project.getName());

            final Map<String, Object> parameters = new HashMap<String, Object>();
            parameters.put(MIN_SDK_VERSION, androidProject.getMinSdkVersion());

            if ((androidProject.getSourceType() == SourceTypes.NEW)
                    || (androidProject.getSourceType() == SourceTypes.WIDGET)) {
                /*
                 * An activity name can be of the form ".package.Class" or ".Class".
                 * The initial dot is ignored, as it is always added later in the templates.
                 */
                String activityName = androidProject.getActivityName();
                if (activityName.startsWith(".")) { //$NON-NLS-1$
                    activityName = activityName.substring(1);
                }
                parameters.put(ACTIVITY_NAME, androidProject.getActivityName());
                parameters.put(PACKAGE_NAME, androidProject.getPackageName());
                parameters.put(APPLICATION_NAME, STRING_RSRC_PREFIX + APP_NAME);
                parameters.put(IMPORT_RESOURCE_CLASS, "");
            }

            /*
             * create a dictionary of string that will contain name+content.
             * we'll put all the strings into values/strings.xml
             */
            final HashMap<String, String> stringDictionary = new HashMap<String, String>();
            stringDictionary.put(APP_NAME, androidProject.getApplicationName());

            if (!androidProject.isUsingDefaultLocation() && androidProject.isNewProject()) {
                Path destination = new Path(androidProject.getLocation());
                description.setLocation(destination);

                if (!FileUtil.canWrite(destination.toFile())) {
                    String errMsg = NLS.bind(
                            AndroidNLS.EXC_ProjectCreationSupport_CannotCreateProjectReadOnlyDestination,
                            destination.toOSString());
                    throw new AndroidException(errMsg);
                }

                if (!validateNewProjectLocationIsEmpty(destination)) {
                    throw new AndroidException(AndroidNLS.UI_ProjectCreationSupport_NonEmptyFolder);
                }
            }

            if (androidProject.getSourceType() == SourceTypes.EXISTING) {
                Path destination = new Path(androidProject.getLocation());
                description.setLocation(destination);
            }

            /*
             * Create a monitored operation to create the actual project
             */
            WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
                @Override
                protected void execute(IProgressMonitor monitor) throws InvocationTargetException {

                    createProjectAsync(project, androidProject, description, monitor, parameters, stringDictionary);
                }
            };

            /*
             * Run the operation in a different thread
             */
            created = runAsyncOperation(op, container);
        }

        return created;

    }

    /**
     * Create android project.
     * @param project
     * @param androidProject
     * @param description
     * @param monitor
     * @param parameters
     * @param stringDictionary
     * @throws InvocationTargetException
     */
    protected static void createProjectAsync(IProject project, AndroidProject androidProject,
            IProjectDescription description, IProgressMonitor monitor, Map<String, Object> parameters,
            Map<String, String> stringDictionary) throws InvocationTargetException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_CopyingSamplesMonitorTaskTitle, 1000);
        try {
            // Create project and open it
            project.create(description, new SubProgressMonitor(monitor, 100));
            if (monitor.isCanceled()) {
                undoProjectCreation(project);
                throw new OperationCanceledException();
            }
            project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 100));

            ProjectUtils.setupAndroidNatures(project, monitor);

            // Create folders in the project if they don't already exist
            createDefaultDir(project, IAndroidConstants.WS_ROOT, BIN_DIR, new SubProgressMonitor(monitor, 40));
            createDefaultDir(project, IAndroidConstants.WS_ROOT, RES_DIR, new SubProgressMonitor(monitor, 40));
            createDefaultDir(project, IAndroidConstants.WS_ROOT, ASSETS_DIR, new SubProgressMonitor(monitor, 40));
            createDefaultDir(project, IAndroidConstants.WS_ROOT, GEN_DIR, new SubProgressMonitor(monitor, 40));

            switch (androidProject.getSourceType()) {
            case NEW:
                // Create the source folders in the project if they don't already exist
                List<String> sourceFolders = androidProject.getSourceFolders();
                for (String sourceFolder : sourceFolders) {
                    createDefaultDir(project, IAndroidConstants.WS_ROOT, sourceFolder,
                            new SubProgressMonitor(monitor, 40));
                }

                // Create the resource folders in the project if they don't already exist.
                int apiLevel = androidProject.getSdkTarget().getVersion().getApiLevel();
                if (apiLevel < 4) {
                    createDefaultDir(project, RES_DIR, DRAWABLE_DIR + File.separator,
                            new SubProgressMonitor(monitor, 40));
                } else {
                    for (String dpi : DPIS) {
                        createDefaultDir(project, RES_DIR, DRAWABLE_DIR + "-" + dpi + File.separator,
                                new SubProgressMonitor(monitor, 40));
                    }
                }
                createDefaultDir(project, RES_DIR, LAYOUT_DIR, new SubProgressMonitor(monitor, 40));
                createDefaultDir(project, RES_DIR, VALUES_DIR, new SubProgressMonitor(monitor, 40));

                // Create files in the project if they don't already exist
                createManifest(project, parameters, stringDictionary, new SubProgressMonitor(monitor, 80));
                // add the default app icon
                addIcon(project, apiLevel, new SubProgressMonitor(monitor, 100));
                // Create the default package components
                String primarySrcFolder = IAndroidConstants.FD_SOURCES;
                if (!sourceFolders.contains(IAndroidConstants.FD_SOURCES)) {
                    primarySrcFolder = sourceFolders.get(0);
                }
                addInitialCode(project, primarySrcFolder, parameters, stringDictionary,
                        new SubProgressMonitor(monitor, 200));
                // add the string definition file if needed
                if (stringDictionary.size() > 0) {
                    EclipseUtils.createOrUpdateDictionaryFile(project, stringDictionary, null,
                            new SubProgressMonitor(monitor, 100));
                }

                break;
            case EXISTING:
                createDefaultDir(project, IAndroidConstants.WS_ROOT, GEN_DIR, new SubProgressMonitor(monitor, 650));
                break;
            case SAMPLE:
                monitor.setTaskName(AndroidNLS.UI_ProjectCreationSupport_CopyingSamplesMonitorMessage);
                FileUtil.copyDir(androidProject.getSample().getFolder(), project.getLocation().toFile());
                project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 650));
                break;
            case WIDGET:
                // Create the source folders in the project if they don't already exist
                List<String> widgetSourceFolders = androidProject.getSourceFolders();
                for (String sourceFolder : widgetSourceFolders) {
                    createDefaultDir(project, IAndroidConstants.WS_ROOT, sourceFolder,
                            new SubProgressMonitor(monitor, 40));
                }

                // Create the resource folders in the project if they don't already exist.
                int widgetApiLevel = androidProject.getSdkTarget().getVersion().getApiLevel();
                if (widgetApiLevel < 4) {
                    createDefaultDir(project, RES_DIR, DRAWABLE_DIR + File.separator,
                            new SubProgressMonitor(monitor, 40));
                } else {
                    for (String dpi : DPIS) {
                        createDefaultDir(project, RES_DIR, DRAWABLE_DIR + "-" + dpi + File.separator,
                                new SubProgressMonitor(monitor, 40));
                    }
                }
                createDefaultDir(project, RES_DIR, LAYOUT_DIR, new SubProgressMonitor(monitor, 40));
                createDefaultDir(project, RES_DIR, VALUES_DIR, new SubProgressMonitor(monitor, 40));
                createDefaultDir(project, RES_DIR, XML_DIR, new SubProgressMonitor(monitor, 40));

                // Create files in the project if they don't already exist
                createWidgetManifest(project, parameters, stringDictionary, new SubProgressMonitor(monitor, 80));
                // add the default app icon
                addIcon(project, widgetApiLevel, new SubProgressMonitor(monitor, 100));
                // Create the default package components
                String widgetPrimarySrcFolder = IAndroidConstants.FD_SOURCES;
                if (!widgetSourceFolders.contains(IAndroidConstants.FD_SOURCES)) {
                    primarySrcFolder = widgetSourceFolders.get(0);
                }
                addInitialWidgetCode(project, widgetPrimarySrcFolder, parameters, stringDictionary,
                        new SubProgressMonitor(monitor, 200));
                // add the string definition file if needed
                if (stringDictionary.size() > 0) {
                    EclipseUtils.createOrUpdateDictionaryFile(project, stringDictionary, null,
                            new SubProgressMonitor(monitor, 100));
                }

                break;
            }

            // Setup class path
            IJavaProject javaProject = JavaCore.create(project);
            setupSourceFolders(javaProject, androidProject.getSourceFolders(), new SubProgressMonitor(monitor, 40));

            // Set output location
            javaProject.setOutputLocation(project.getFolder(BIN_DIR).getFullPath(),
                    new SubProgressMonitor(monitor, 40));
            SdkUtils.associate(project, androidProject.getSdkTarget());
            ProjectUtils.fixProject(project);
        } catch (CoreException e) {
            undoProjectCreation(project);
            throw new InvocationTargetException(e);
        } catch (IOException e) {
            undoProjectCreation(project);
            throw new InvocationTargetException(e);
        } finally {
            monitor.done();
        }
    }

    /**
     * Add initial code
     * @param project
     * @param sourceFolder
     * @param parameters
     * @param stringDictionary
     * @param monitor
     * @throws CoreException
     * @throws IOException
     */
    private static void addInitialCode(IProject project, String sourceFolder, Map<String, Object> parameters,
            Map<String, String> stringDictionary, IProgressMonitor monitor) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Configuring_Sample_Source_Task, 700);

        try {
            IFolder pkgFolder = project.getFolder(sourceFolder);

            Map<String, Object> processed_parameters = processSampleActivity(parameters);
            String activityName = (String) processed_parameters.get(ACTIVITY_NAME);
            String packageName = (String) processed_parameters.get(PACKAGE_NAME);

            pkgFolder = createPackageFolders(new SubProgressMonitor(monitor, 300), pkgFolder, packageName);

            if (activityName != null) {
                createSampleActivity(new SubProgressMonitor(monitor, 200), pkgFolder, processed_parameters,
                        activityName);
            }

            IFolder layoutfolder = project.getFolder(RES_DIR + LAYOUT_DIR);
            IFile file = layoutfolder.getFile(MAIN_LAYOUT_XML);
            if (!file.exists()) {
                copyTemplateFile(LAYOUT_TEMPLATE, file, parameters, new SubProgressMonitor(monitor, 100));
                if (activityName != null) {
                    stringDictionary.put(STRING_HELLO_WORLD,
                            NLS.bind(AndroidNLS.GEN_ProjectCreationSupport_HelloWorldWithName, activityName));
                } else {
                    stringDictionary.put(STRING_HELLO_WORLD,
                            AndroidNLS.GEN_ProjectCreationSupport_HelloWorldSimple);
                }
                monitor.worked(100);
            }
        } finally {
            monitor.done();
        }
    }

    /**
     * Add initial widget code
     * @param project
     * @param sourceFolder
     * @param parameters
     * @param stringDictionary
     * @param monitor
     * @throws CoreException
     * @throws IOException
     */
    private static void addInitialWidgetCode(IProject project, String sourceFolder, Map<String, Object> parameters,
            Map<String, String> stringDictionary, IProgressMonitor monitor) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Configuring_Sample_Source_Task, 800);

        try {
            IFolder pkgFolder = project.getFolder(sourceFolder);

            Map<String, Object> processed_parameters = processSampleActivity(parameters);
            String activityName = (String) processed_parameters.get(ACTIVITY_NAME);
            String packageName = (String) processed_parameters.get(PACKAGE_NAME);

            pkgFolder = createPackageFolders(new SubProgressMonitor(monitor, 200), pkgFolder, packageName);

            // Create sample activity
            if (activityName != null) {
                createSampleActivity(new SubProgressMonitor(monitor, 100), pkgFolder, processed_parameters,
                        activityName);
            }

            // Create sample widget provider
            createSampleWidgetProvider(new SubProgressMonitor(monitor, 100), pkgFolder, processed_parameters);

            // Layout xml file
            IFolder layoutfolder = project.getFolder(RES_DIR + LAYOUT_DIR);

            IFile file = layoutfolder.getFile(MAIN_LAYOUT_XML);
            if (!file.exists()) {
                copyTemplateFile(LAYOUT_TEMPLATE, file, parameters, new SubProgressMonitor(monitor, 100));
                if (activityName != null) {
                    stringDictionary.put(STRING_HELLO_WORLD,
                            NLS.bind(AndroidNLS.GEN_ProjectCreationSupport_HelloWorldWithName, activityName));
                } else {
                    stringDictionary.put(STRING_HELLO_WORLD,
                            AndroidNLS.GEN_ProjectCreationSupport_HelloWorldSimple);
                }
                monitor.worked(100);
            }

            // Widget initial layout xml file
            IFile initial_layout_file = layoutfolder.getFile(WIDGET_INITIAL_LAYOUT_XML);
            if (!initial_layout_file.exists()) {
                copyWidgetTemplateFile(WIDGET_INITIAL_LAYOUT_XML, initial_layout_file, processed_parameters,
                        new SubProgressMonitor(monitor, 100));
                monitor.worked(100);
            }

            // Widget info xml file
            IFolder xmlFolder = project.getFolder(RES_DIR + XML_DIR);

            IFile widget_info_file = xmlFolder.getFile(WIDGET_INFO_XML);
            if (!widget_info_file.exists()) {
                copyWidgetTemplateFile(WIDGET_INFO_XML, widget_info_file, processed_parameters,
                        new SubProgressMonitor(monitor, 100));
                monitor.worked(100);
            }

        } finally {
            monitor.done();
        }
    }

    private static void createSampleActivity(IProgressMonitor monitor, IFolder pkgFolder,
            Map<String, Object> processed_parameters, String activityName) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Configuring_Sample_Activity_Task, 100);
        try {
            IFile file = pkgFolder.getFile(activityName + IAndroidConstants.DOT_JAVA);
            if (!file.exists()) {
                monitor.worked(10);
                copyTemplateFile(JAVA_ACTIVITY_TEMPLATE, file, processed_parameters,
                        new SubProgressMonitor(monitor, 90));
            }
        } finally {
            monitor.done();
        }
    }

    private static void createSampleWidgetProvider(IProgressMonitor monitor, IFolder pkgFolder,
            Map<String, Object> processed_parameters) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Configuring_Sample_Widget_Provider, 100);
        try {
            IFile file = pkgFolder.getFile(WIDGET_PROVIDER_SAMPLE_NAME + IAndroidConstants.DOT_JAVA);
            if (!file.exists()) {
                monitor.worked(10);
                copyWidgetTemplateFile(WIDGET_PROVIDER_SAMPLE_TEMPLATE, file, processed_parameters,
                        new SubProgressMonitor(monitor, 90));
            }
        } finally {
            monitor.done();
        }
    }

    private static IFolder createPackageFolders(IProgressMonitor monitor, IFolder pkgFolder, String packageName)
            throws CoreException {
        String[] components = packageName.split(IAndroidConstants.RE_DOT);
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Preparing_Java_Packages_Task,
                components.length * 100);
        try {
            for (String component : components) {
                pkgFolder = pkgFolder.getFolder(component);
                if (!pkgFolder.exists()) {
                    pkgFolder.create(true, true, new SubProgressMonitor(monitor, 100));
                }
            }
        } finally {
            monitor.done();
        }

        return pkgFolder;
    }

    private static Map<String, Object> processSampleActivity(Map<String, Object> parameters) {
        String activityName = (String) parameters.get(ACTIVITY_NAME);

        Map<String, Object> processed_parameters = new HashMap<String, Object>(parameters);
        if ((activityName != null) && activityName.contains(".")) //$NON-NLS-1$
        {
            String packageName = (String) parameters.get(PACKAGE_NAME);
            packageName += "." + activityName.substring(0, activityName.lastIndexOf('.')); //$NON-NLS-1$
            activityName = activityName.substring(activityName.lastIndexOf('.'));

            processed_parameters.put(PACKAGE_NAME, packageName);
            processed_parameters.put(ACTIVITY_NAME, activityName);
        }

        return processed_parameters;
    }

    /**
     * Copy template files
     * @param resourceFilename
     * @param destFile
     * @param parameters
     * @param monitor
     * @throws CoreException
     * @throws IOException
     */
    private static void copyTemplateFile(String resourceFilename, IFile destFile, Map<String, Object> parameters,
            IProgressMonitor monitor) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Preparing_Template_File_Task, 150);
        InputStream stream = null;
        try {
            String template = readEmbeddedTextFileADT(TEMPLATES_DIRECTORY + resourceFilename, parameters);
            monitor.worked(50);
            stream = new ByteArrayInputStream(template.getBytes("UTF-8")); //$NON-NLS-1$
            destFile.create(stream, false, new SubProgressMonitor(monitor, 100));

        } finally {
            if (stream != null) {
                stream.close();
            }
            monitor.done();
        }
    }

    /**
     * Copy widget template files
     * @param resourceFilename
     * @param destFile
     * @param parameters
     * @param monitor
     * @throws CoreException
     * @throws IOException
     */
    private static void copyWidgetTemplateFile(String resourceFilename, IFile destFile,
            Map<String, Object> parameters, IProgressMonitor monitor) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Preparing_Template_File_Task, 150);
        InputStream stream = null;
        try {
            String template = readEmbeddedTextFileStudio(WIDGET_TEMPLATE_FOLDER + resourceFilename, parameters);
            monitor.worked(50);
            stream = new ByteArrayInputStream(template.getBytes("UTF-8")); //$NON-NLS-1$
            destFile.create(stream, false, new SubProgressMonitor(monitor, 100));

        } finally {
            if (stream != null) {
                stream.close();
            }
            monitor.done();
        }
    }

    /**
     * Add Icon to the project
     * @param project
     * @param apiLevel 
     * @param monitor
     * @throws CoreException
     */
    private static void addIcon(IProject project, int apiLevel, IProgressMonitor monitor) throws CoreException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Configuring_Project_Icon_Task, 1000);
        try {
            if (apiLevel < 4) {
                IFile imageFile = project
                        .getFile(RES_DIR + IPath.SEPARATOR + DRAWABLE_DIR + IPath.SEPARATOR + ICON);
                if (!imageFile.exists()) {
                    String fileName = ICON.substring(0, ICON.length() - 4) + "_" + DPIS[2]
                            + ICON.substring(ICON.length() - 4);
                    createImageFromTemplate(monitor, imageFile, fileName);
                }
            } else {
                for (String dpi : DPIS) {
                    IFile imageFile = project
                            .getFile(RES_DIR + IPath.SEPARATOR + DRAWABLE_DIR + "-" + dpi + IPath.SEPARATOR + ICON);
                    if (!imageFile.exists()) {
                        String fileName = ICON.substring(0, ICON.length() - 4) + "_" + dpi
                                + ICON.substring(ICON.length() - 4);
                        createImageFromTemplate(monitor, imageFile, fileName);
                    }
                }
            }
        } finally {
            monitor.done();
        }

    }

    private static void createImageFromTemplate(IProgressMonitor monitor, IFile imageFile, String fileName)
            throws CoreException {
        byte[] buffer = AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + fileName);

        if (buffer != null) {
            InputStream stream = null;
            try {
                stream = new ByteArrayInputStream(buffer);
                imageFile.create(stream, IResource.NONE, new SubProgressMonitor(monitor, 1000));
            } finally {
                try {
                    stream.close();
                } catch (IOException e) {
                    StudioLogger.info("Create image from template could not close stream. " + e.getMessage());
                }
            }
        }
    }

    /**
     * Adds the manifest to the project.
     * @param project
     * @param parameters
     * @param stringDictionary
     * @param monitor
     * @throws CoreException
     * @throws IOException
     */
    private static void createManifest(IProject project, Map<String, Object> parameters,
            Map<String, String> stringDictionary, IProgressMonitor monitor) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Creating_Manifest_File_Task, 300);
        try {
            IFile manifestFile = project.getFile(IAndroidConstants.FN_ANDROID_MANIFEST);
            if (!manifestFile.exists()) {
                monitor.setTaskName(AndroidNLS.UI_ProjectCreationSupport_Reading_Template_File_Task);
                String manifestTemplate = readEmbeddedTextFileADT(MANIFEST_TEMPLATE, parameters);
                monitor.worked(10);
                if (parameters.containsKey(ACTIVITY_NAME)) {
                    String activities = readEmbeddedTextFileADT(ACTIVITY_TEMPLATE, parameters);
                    String intent = AdtPlugin.readEmbeddedTextFile(LAUNCHER_INTENT_TEMPLATE);
                    activities = activities.replaceAll(INTENT_FILTERS, intent);
                    manifestTemplate = manifestTemplate.replaceAll(ACTIVITIES, activities);
                    monitor.worked(90);
                } else {
                    manifestTemplate = manifestTemplate.replaceAll(ACTIVITIES, ""); //$NON-NLS-1$
                    monitor.worked(90);
                }

                //We don't currently supports the TEST parameters. So let's just remove the unused tags.
                manifestTemplate = manifestTemplate.replaceAll(TEST_USES_LIBRARY, ""); //$NON-NLS-1$
                manifestTemplate = manifestTemplate.replaceAll(TEST_INSTRUMENTATION, ""); //$NON-NLS-1$

                String minSdkVersion = (String) parameters.get(MIN_SDK_VERSION);
                if ((minSdkVersion != null) && (minSdkVersion.length() > 0)) {
                    String usesSdk = readEmbeddedTextFileADT(USES_SDK_TEMPLATE, parameters);
                    manifestTemplate = manifestTemplate.replaceAll(USES_SDK, usesSdk);
                    monitor.worked(50);
                } else {
                    manifestTemplate = manifestTemplate.replaceAll(USES_SDK, ""); //$NON-NLS-1$
                    monitor.worked(50);
                }

                InputStream stream = null;
                try {
                    stream = new ByteArrayInputStream(manifestTemplate.getBytes("UTF-8")); //$NON-NLS-1$
                    manifestFile.create(stream, IResource.NONE, new SubProgressMonitor(monitor, 150));
                } finally {
                    try {
                        if (stream != null) {
                            stream.close();
                        }
                    } catch (IOException e) {
                        StudioLogger.info("Could not close stream while creating manifest", e.getMessage());
                    }
                }
            }
        } finally {
            monitor.done();
        }
    }

    /**
     * Adds the widget manifest to the project.
     * @param project
     * @param parameters
     * @param stringDictionary
     * @param monitor
     * @throws CoreException
     * @throws IOException
     */
    private static void createWidgetManifest(IProject project, Map<String, Object> parameters,
            Map<String, String> stringDictionary, IProgressMonitor monitor) throws CoreException, IOException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Creating_Manifest_File_Task, 300);
        try {
            IFile manifestFile = project.getFile(IAndroidConstants.FN_ANDROID_MANIFEST);
            if (!manifestFile.exists()) {
                monitor.setTaskName(AndroidNLS.UI_ProjectCreationSupport_Reading_Template_File_Task);

                // Manifest skeleton
                String manifestTemplate = readEmbeddedTextFileStudio(WIDGET_MANIFEST_TEMPLATE_PATH, parameters);
                monitor.worked(10);
                // Activity information
                if (parameters.containsKey(ACTIVITY_NAME)) {
                    String activities = readEmbeddedTextFileStudio(WIDGET_ACTIVITY_TEMPLATE_PATH, parameters);
                    manifestTemplate = manifestTemplate.replaceAll(ACTIVITIES, activities);
                    monitor.worked(70);
                } else {
                    manifestTemplate = manifestTemplate.replaceAll(ACTIVITIES, ""); //$NON-NLS-1$
                    monitor.worked(70);
                }

                // Receiver information
                String receivers = readEmbeddedTextFileStudio(WIDGET_RECEIVER_TEMPLATE_PATH, parameters);
                manifestTemplate = manifestTemplate.replaceAll(RECEIVERS, receivers);
                monitor.worked(70);

                // Min Sdk information
                String minSdkVersion = (String) parameters.get(MIN_SDK_VERSION);
                if ((minSdkVersion != null) && (minSdkVersion.length() > 0)) {
                    String usesSdk = readEmbeddedTextFileStudio(WIDGET_USES_SDK_TEMPLATE_PATH, parameters);
                    manifestTemplate = manifestTemplate.replaceAll(USES_SDK, usesSdk);
                    monitor.worked(50);
                } else {
                    manifestTemplate = manifestTemplate.replaceAll(USES_SDK, ""); //$NON-NLS-1$
                    monitor.worked(50);
                }

                InputStream stream = null;

                try {
                    stream = new ByteArrayInputStream(manifestTemplate.getBytes("UTF-8")); //$NON-NLS-1$
                    manifestFile.create(stream, IResource.NONE, new SubProgressMonitor(monitor, 100));
                } finally {
                    try {
                        if (stream != null) {
                            stream.close();
                        }
                    } catch (IOException e) {
                        StudioLogger.info("Could not close stream while creating manifest for widget",
                                e.getMessage());
                    }
                }
            }
        } finally {
            monitor.done();
        }
    }

    private static String readEmbeddedTextFileADT(String template, Map<String, Object> parameters) {
        String loadedTemplate = AdtPlugin.readEmbeddedTextFile(template);

        for (String key : parameters.keySet()) {
            if (parameters.get(key) instanceof String) {
                loadedTemplate = loadedTemplate.replaceAll(key, (String) parameters.get(key));
            }
        }

        return loadedTemplate;
    }

    private static String readEmbeddedTextFileStudio(String template, Map<String, Object> parameters) {
        String loadedTemplate = EclipseUtils.readEmbeddedResource(AndroidPlugin.getDefault().getBundle(), template);

        for (String key : parameters.keySet()) {
            if (parameters.get(key) instanceof String) {
                loadedTemplate = loadedTemplate.replaceAll(key, (String) parameters.get(key));
            }
        }

        return loadedTemplate;
    }

    /**
     * Setup src folders
     * @param javaProject
     * @param sourceFolder
     * @param monitor
     * @throws JavaModelException
     */
    private static void setupSourceFolders(IJavaProject javaProject, List<String> sourceFolders,
            IProgressMonitor monitor) throws JavaModelException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Preparing_Source_Folders_Task,
                (sourceFolders.size() * 100) + 100);
        try {
            IProject project = javaProject.getProject();
            IClasspathEntry[] entries = javaProject.getRawClasspath();

            for (String sourceFolder : sourceFolders) {
                IFolder srcFolder = project.getFolder(sourceFolder);
                entries = removeClasspathEntry(entries, srcFolder);
                entries = removeClasspathEntry(entries, srcFolder.getParent());
                entries = ProjectUtils.addEntryToClasspath(entries,
                        JavaCore.newSourceEntry(srcFolder.getFullPath()));
                monitor.worked(100);
            }

            javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 100));
        } finally {
            monitor.done();
        }
    }

    /**
     * Remove source folder from classpath 
     * @param entries
     * @param folder
     * @return
     */
    private static IClasspathEntry[] removeClasspathEntry(IClasspathEntry[] entries, IContainer folder) {

        IClasspathEntry[] newClassPath = null;

        if (folder != null) {
            IClasspathEntry removeEntry = JavaCore.newSourceEntry(folder.getFullPath());
            List<IClasspathEntry> entriesList = Arrays.asList(entries);

            if (entriesList.contains(removeEntry)) {
                newClassPath = new IClasspathEntry[entries.length - 1];
                int i = 0;
                for (IClasspathEntry entry : entriesList) {
                    if (!entry.equals(removeEntry)) {
                        newClassPath[i] = entry;
                        i++;
                    }
                }
            } else {
                newClassPath = entries;
            }
        } else {
            newClassPath = entries;
        }
        return newClassPath;
    }

    /**
     * Add default directory to Project
     * @param project
     * @param parentFolder
     * @param folderName
     * @param monitor
     * @throws CoreException
     */
    private static void createDefaultDir(IProject project, String parentFolder, String folderName,
            IProgressMonitor monitor) throws CoreException {
        monitor.beginTask(AndroidNLS.UI_ProjectCreationSupport_Creating_Directory_Task + folderName, 100);

        try {
            monitor.setTaskName(AndroidNLS.UI_ProjectCreationSupport_Verifying_Directory_Task);
            if (folderName.length() > 0) {
                monitor.worked(10);
                IFolder folder = project.getFolder(parentFolder + folderName);
                monitor.worked(10);
                if (!folder.exists()) {
                    monitor.worked(10);
                    if (FileUtil.canWrite(folder.getLocation().toFile())) {
                        monitor.worked(10);
                        monitor.setTaskName(AndroidNLS.UI_ProjectCreationSupport_Creating_Directory_Task);
                        folder.create(true, true, new SubProgressMonitor(monitor, 60));
                    } else {
                        String errMsg = NLS.bind(
                                AndroidNLS.EXC_ProjectCreationSupport_CannotCreateFolderReadOnlyWorkspace,
                                folder.getLocation().toFile().toString());
                        IStatus status = new AndroidStatus(IStatus.ERROR, errMsg);
                        throw new CoreException(status);
                    }
                }
            }
        } finally {
            monitor.done();
        }
    }

    /**
     * Validate new Project Location.
     * @param destination
     * @param display
     * @return
     */
    public static boolean validateNewProjectLocationIsEmpty(IPath destination) {
        File f = new File(destination.toOSString());
        if (f.isDirectory() && (f.list().length > 0)) {
            //            EclipseUtils.showErrorDialog(
            //                    AndroidNLS.UI_ProjectCreationSupport_NonEmptyFolderQuestionDialogTitle,
            //                    AndroidNLS.UI_ProjectCreationSupport_NonEmptyFolderQuestion);
            return false;
        }
        return true;
    }

    /**
     * Run the operation in async thread.
     * @param op
     * @param container
     * 
     * @return true if no errors occur during the operation or false otherwise
     */
    private static boolean runAsyncOperation(WorkspaceModifyOperation op, IWizardContainer container) {
        boolean created = false;

        try {
            container.run(true, true, op);
            created = true;
        } catch (InvocationTargetException ite) {
            Throwable t = ite.getTargetException();
            if (t instanceof CoreException) {
                CoreException core = (CoreException) t;
                if (core.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
                    MessageDialog.openError(container.getShell(), AndroidNLS.UI_GenericErrorDialogTitle,
                            AndroidNLS.ERR_ProjectCreationSupport_CaseVariantExistsError);
                } else {
                    ErrorDialog.openError(container.getShell(), AndroidNLS.UI_GenericErrorDialogTitle, null,
                            core.getStatus());
                }
            } else {
                MessageDialog.openError(container.getShell(), AndroidNLS.UI_GenericErrorDialogTitle,
                        t.getMessage());
            }
        } catch (InterruptedException e) {
            StudioLogger.error(ProjectCreationSupport.class, "Error creating project.", e); //$NON-NLS-1$
        }

        return created;
    }

    /**
     * Checks if a project can be created on workspace
     * 
     * @param root The workspace root
     * @param projectName The project name
     * 
     * @return true if the project can be created or false otherwise
     */
    private static boolean canCreateProject(IWorkspaceRoot root, String projectName) {
        File rootFolder = root.getLocation().toFile();
        File projectFolder = new File(rootFolder, projectName);

        return FileUtil.canWrite(projectFolder);
    }

    /**
     * Undoes a project creation. Removes all files created by the project creation process
     * and keeps any other previous files
     * 
     * @param project The failed project
     * @param existingResources A set containing the path of pre-existing resources before creating
     *                          the project
     */
    private static void undoProjectCreation(IProject project) {
        File projectPath = new File(project.getWorkspace().getRoot().getLocation().toFile(), project.getName());
        Set<String> existingResources = getExistingResources(projectPath);

        try {
            project.delete(false, true, new NullProgressMonitor());
        } catch (CoreException e1) {
            // Do nothing
            StudioLogger.error(ProjectCreationSupport.class, e1.getLocalizedMessage(), e1);
        }

        if (existingResources.isEmpty()) {
            try {
                FileUtil.deleteDirRecursively(project.getLocation().toFile());
            } catch (IOException e) {
                // Do nothing
                StudioLogger.error(ProjectCreationSupport.class, e.getLocalizedMessage(), e);
            }
        } else {
            File root = new File(project.getWorkspace().getRoot().getLocation().toFile(), project.getName());
            removeCreatedResources(root, existingResources);
        }
    }

    /**
     * Retrieves a list of existing sub-resources from a folder
     *  
     * @param folder the File object representing the folder
     * 
     * @return a list of existing sub-resources from the folder
     */
    private static Set<String> getExistingResources(File folder) {
        Set<String> existing = new HashSet<String>();

        if ((folder != null) && folder.exists() && folder.isDirectory()) {
            existing.add(folder.toString());

            File[] children = folder.listFiles();

            if (children != null) {
                for (File child : children) {
                    if (child.isDirectory()) {
                        existing.addAll(getExistingResources(child));
                    } else {
                        existing.add(child.toString());
                    }
                }
            }
        }

        return existing;
    }

    /**
     * Removes the created resources by a failed project creation process
     * 
     * @param startingPoint The project root folder (File object)
     * @param existingResources The set containing the previous existing resources in the project root folder
     */
    private static void removeCreatedResources(File startingPoint, Set<String> existingResources) {
        File[] members = startingPoint.listFiles();

        if (members != null) {
            for (File child : members) {
                if (child.isFile()) {
                    if (!existingResources.contains(child.toString())) {
                        child.delete();
                    }
                } else {
                    removeCreatedResources(child, existingResources);
                }
            }
        }

        if (!existingResources.contains(startingPoint.toString())) {
            startingPoint.delete();
        }
    }
}