se.aceone.mediatek.linkit.importWizards.ImportLinkIt10ProjectWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for se.aceone.mediatek.linkit.importWizards.ImportLinkIt10ProjectWizardPage.java

Source

/*
 * LinkIt Tool Chain, an eclipse plugin for LinkIt SDK 1.0 and 2.0
 * 
 * Copyright  2015 Henrik Olsson (henols@gmail.com)
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package se.aceone.mediatek.linkit.importWizards;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IPathVariableManager;
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.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.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.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;

import se.aceone.mediatek.linkit.Activator;
import se.aceone.mediatek.linkit.common.LinkItConst;
import se.aceone.mediatek.linkit.tools.Common;
import se.aceone.mediatek.linkit.tools.CompilerRVCT;
import se.aceone.mediatek.linkit.tools.LinkIt10Helper;
import se.aceone.mediatek.linkit.tools.LinkIt10HelperLib;
import se.aceone.mediatek.linkit.tools.LinkItHelper;
import se.aceone.mediatek.linkit.xml.config.Packageinfo;
import se.aceone.mediatek.linkit.xml.config.Packageinfo.Output;
import se.aceone.mediatek.linkit.xml.proj.VisualStudioProject;

public class ImportLinkIt10ProjectWizardPage extends WizardPage {

    public ImportLinkIt10ProjectWizardPage() {
        super("Import LinkIt 1.0 Project"); //$NON-NLS-1$
        setPageComplete(false);
        setTitle("Import LinkIt 1.0 Project");
        setDescription("Import an exsiting LinkIt 1.0 Project");

    }

    private FileFilter projectFilter = new FileFilter() {
        // Only accept those files that are .project
        public boolean accept(File pathName) {
            String name = pathName.getName();
            return name.endsWith(".vcproj") && !(name.startsWith("~") || name.startsWith("."));
        }
    };

    // Keep track of the directory that we browsed to last time
    // the wizard was invoked.
    private static String previouslyBrowsedDirectory = ""; //$NON-NLS-1$

    // widgets
    private Text projectNameField;

    private Text locationPathField;

    private Button browseButton;

    private Button copyResorces;

    private IProjectDescription description;

    private Listener locationModifyListener = new Listener() {
        public void handleEvent(Event e) {
            setPageComplete(validatePage());
        }
    };

    // constants
    private static final int SIZING_TEXT_FIELD_WIDTH = 250;

    /**
     * (non-Javadoc) Method declared on IDialogPage.
     */
    public void createControl(Composite parent) {

        initializeDialogUnits(parent);

        Composite composite = new Composite(parent, SWT.NULL);

        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setFont(parent.getFont());

        createProjectNameGroup(composite);
        createProjectLocationGroup(composite);

        createCopyResourceGroup(composite);

        validatePage();
        // Show description on opening
        setErrorMessage(null);
        setMessage(null);
        setControl(composite);
    }

    /**
     * Creates the project location specification controls.
     *
     * @param parent
     *            the parent composite
     */
    private final void createProjectLocationGroup(Composite parent) {

        // project specification group
        Composite projectGroup = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        projectGroup.setLayout(layout);
        projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        projectGroup.setFont(parent.getFont());

        // new project label
        Label projectContentsLabel = new Label(projectGroup, SWT.NONE);
        projectContentsLabel.setText(DataTransferMessages.WizardExternalProjectImportPage_projectContentsLabel);
        projectContentsLabel.setFont(parent.getFont());

        createUserSpecifiedProjectLocationGroup(projectGroup);
    }

    /**
     * Creates the project name specification controls.
     *
     * @param parent
     *            the parent composite
     */
    private final void createProjectNameGroup(Composite parent) {

        Font dialogFont = parent.getFont();

        // project specification group
        Composite projectGroup = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        projectGroup.setFont(dialogFont);
        projectGroup.setLayout(layout);
        projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // new project label
        Label projectLabel = new Label(projectGroup, SWT.NONE);
        projectLabel.setText(DataTransferMessages.WizardExternalProjectImportPage_nameLabel);
        projectLabel.setFont(dialogFont);

        // new project name entry field
        projectNameField = new Text(projectGroup, SWT.BORDER | SWT.READ_ONLY);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = SIZING_TEXT_FIELD_WIDTH;
        projectNameField.setLayoutData(data);
        projectNameField.setFont(dialogFont);
        projectNameField.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
    }

    private final void createCopyResourceGroup(Composite parent) {

        Font dialogFont = parent.getFont();

        // browse button
        this.copyResorces = new Button(parent, SWT.CHECK);
        this.copyResorces.setText("Copy resources to workspace");
        this.copyResorces.setFont(dialogFont);
        setButtonLayoutData(this.copyResorces);

        locationPathField.addListener(SWT.Modify, locationModifyListener);
    }

    /**
     * Creates the project location specification controls.
     *
     * @param projectGroup
     *            the parent composite
     */
    private void createUserSpecifiedProjectLocationGroup(Composite projectGroup) {

        Font dialogFont = projectGroup.getFont();

        // project location entry field
        this.locationPathField = new Text(projectGroup, SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = SIZING_TEXT_FIELD_WIDTH;
        this.locationPathField.setLayoutData(data);
        this.locationPathField.setFont(dialogFont);

        // browse button
        this.browseButton = new Button(projectGroup, SWT.PUSH);
        this.browseButton.setText(DataTransferMessages.DataTransfer_browse);
        this.browseButton.setFont(dialogFont);
        setButtonLayoutData(this.browseButton);

        this.browseButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                handleLocationBrowseButtonPressed();
            }
        });

        locationPathField.addListener(SWT.Modify, locationModifyListener);
    }

    /**
     * Returns the current project location path as entered by the user, or its anticipated initial value.
     *
     * @return the project location path, its anticipated initial value, or <code>null</code> if no project location
     *         path is known
     */
    public IPath getLocationPath() {
        return new Path(getProjectLocationFieldValue());
    }

    /**
     * Creates a project resource handle for the current project name field value.
     * <p>
     * This method does not create the project resource; this is the responsibility of <code>IProject::create</code>
     * invoked by the new project resource wizard.
     * </p>
     *
     * @return the new project resource handle
     */
    public IProject getProjectHandle() {
        return ResourcesPlugin.getWorkspace().getRoot().getProject(getProjectName());
    }

    /**
     * Returns the current project name as entered by the user, or its anticipated initial value.
     *
     * @return the project name, its anticipated initial value, or <code>null</code> if no project name is known
     */
    public String getProjectName() {
        return getProjectNameFieldValue();
    }

    public boolean copyResources() {
        return copyResorces.getSelection();
    }

    /**
     * Returns the value of the project name field with leading and trailing spaces removed.
     * 
     * @return the project name in the field
     */
    private String getProjectNameFieldValue() {
        if (projectNameField == null) {
            return ""; //$NON-NLS-1$
        }

        return projectNameField.getText().trim();
    }

    /**
     * Returns the value of the project location field with leading and trailing spaces removed.
     * 
     * @return the project location directory in the field
     */
    private String getProjectLocationFieldValue() {
        return locationPathField.getText().trim();
    }

    /**
     * Open an appropriate directory browser
     */
    private void handleLocationBrowseButtonPressed() {
        DirectoryDialog dialog = new DirectoryDialog(locationPathField.getShell(), SWT.SHEET);
        dialog.setMessage(DataTransferMessages.WizardExternalProjectImportPage_directoryLabel);

        String dirName = getProjectLocationFieldValue();
        if (dirName.length() == 0) {
            dirName = previouslyBrowsedDirectory;
        }

        if (dirName.length() == 0) {
            dialog.setFilterPath(getWorkspace().getRoot().getLocation().toOSString());
        } else {
            File path = new File(dirName);
            if (path.exists()) {
                dialog.setFilterPath(new Path(dirName).toOSString());
            }
        }

        String selectedDirectory = dialog.open();
        if (selectedDirectory != null) {
            previouslyBrowsedDirectory = selectedDirectory;
            locationPathField.setText(previouslyBrowsedDirectory);
            setProjectName(projectFile(previouslyBrowsedDirectory));
        }
    }

    /**
     * Returns whether this page's controls currently all contain valid values.
     *
     * @return <code>true</code> if all controls are valid, and <code>false</code> if at least one is invalid
     */
    private boolean validatePage() {

        String locationFieldContents = getProjectLocationFieldValue();

        if (locationFieldContents.equals("")) { //$NON-NLS-1$
            setErrorMessage(null);
            setMessage(DataTransferMessages.WizardExternalProjectImportPage_projectLocationEmpty);
            return false;
        }

        IPath path = new Path(""); //$NON-NLS-1$
        if (!path.isValidPath(locationFieldContents)) {
            setErrorMessage(DataTransferMessages.WizardExternalProjectImportPage_locationError);
            return false;
        }

        File projectFile = projectFile(locationFieldContents);
        if (projectFile == null) {
            setErrorMessage(NLS.bind(DataTransferMessages.WizardExternalProjectImportPage_notAProject,
                    locationFieldContents));
            return false;
        }
        setProjectName(projectFile);

        if (getProjectHandle().exists()) {
            setErrorMessage(DataTransferMessages.WizardExternalProjectImportPage_projectExistsMessage);
            return false;
        }

        setErrorMessage(null);
        setMessage(null);
        return true;
    }

    private IWorkspace getWorkspace() {
        IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
        return workspace;
    }

    /**
     * Return whether or not the specifed location is a prefix of the root.
     */
    private boolean isPrefixOfRoot(IPath locationPath) {
        return Platform.getLocation().isPrefixOf(locationPath);
    }

    /**
     * Set the project name using either the name of the parent of the file or the name entry in the xml for the file
     */
    private void setProjectName(File projectFile) {

        // If there is no file or the user has already specified forget it
        if (projectFile == null) {
            return;
        }
        VisualStudioProject visualStudioProject = null;
        try {
            JAXBContext context = JAXBContext.newInstance(VisualStudioProject.class);
            Unmarshaller nmarshaller = context.createUnmarshaller();
            visualStudioProject = (VisualStudioProject) nmarshaller.unmarshal(projectFile);

        } catch (Exception exception) {
            // no good couldn't get the name
            exception.printStackTrace();
        }

        if (visualStudioProject == null) {
            this.description = null;
            this.projectNameField.setText(""); //$NON-NLS-1$
        } else {
            this.projectNameField.setText(visualStudioProject.getName());
        }
    }

    private boolean isStaticLib(File projectFile) {

        // If there is no file or the user has already specified forget it
        if (projectFile == null) {
            return false;
        }
        Packageinfo config = null;
        try {
            JAXBContext context = JAXBContext.newInstance(Packageinfo.class);
            Unmarshaller nmarshaller = context.createUnmarshaller();
            config = (Packageinfo) nmarshaller.unmarshal(projectFile);

        } catch (Exception exception) {
            // no good couldn't get the name
            exception.printStackTrace();
        }

        if (config == null) {
            return false;
        }
        Output output = config.getOutput();
        return output != null && output.getType() != null && output.getType().intValue() == 3;
    }

    /**
     * Return a.project file from the specified location. If there isn't one return null.
     */
    private File projectFile(String locationFieldContents) {
        File directory = new File(locationFieldContents);
        if (directory.isFile()) {
            return null;
        }

        File[] files = directory.listFiles(this.projectFilter);
        if (files != null && files.length == 1) {
            return files[0];
        }

        return null;
    }

    /**
     * Creates a new project resource with the selected name.
     * <p>
     * In normal usage, this method is invoked after the user has pressed Finish on the wizard; the enablement of the
     * Finish button implies that all controls on the pages currently contain valid values.
     * </p>
     *
     * @return the created project resource, or <code>null</code> if the project was not created
     */
    IProject createExistingProject() {

        String projectName = projectNameField.getText();
        final IWorkspace workspace = ResourcesPlugin.getWorkspace();
        final IProject project = workspace.getRoot().getProject(projectName);
        final IPath locationPath = getLocationPath();
        final boolean copyResources = copyResources();
        this.description = workspace.newProjectDescription(projectName);
        // If it is under the root use the default location
        if (isPrefixOfRoot(locationPath) || copyResources) {
            this.description.setLocation(null);
        } else {
            this.description.setLocation(locationPath);
        }

        // create the new project operation
        WorkspaceModifyOperation op = new WorkspaceModifyOperation() {

            protected void execute(IProgressMonitor monitor) throws CoreException {
                monitor.beginTask("", 2000); //$NON-NLS-1$
                project.create(description, new SubProgressMonitor(monitor, 1000));
                if (monitor.isCanceled()) {
                    throw new OperationCanceledException();
                }

                IPath configPath = locationPath.append("config.xml");
                LinkItHelper helper;
                se.aceone.mediatek.linkit.tools.Compiler compiler = new CompilerRVCT();
                boolean staticLib = isStaticLib(new File(configPath.toOSString()));
                if (staticLib) {
                    helper = new LinkIt10HelperLib(project, compiler);
                } else {
                    helper = new LinkIt10Helper(project, compiler);
                }
                // helper = new LinkIt10HelperRVTC(project);

                if (!helper.checkEnvironment()) {
                    Common.log(new Status(IStatus.ERROR, LinkItConst.CORE_PLUGIN_ID,
                            "Enviroment for LinkIt SDK 1.0 are not configuerd."));
                    throw new OperationCanceledException("Enviroment for LinkIt SDK 1.0 are not configuerd.");
                }

                project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1000));
                if (copyResources) {
                    copyProjectToWorkspace(project, locationPath, monitor);
                }
                IPathVariableManager manager = project.getWorkspace().getPathVariableManager();
                if (manager.getURIValue(LinkIt10Helper.LINK_IT_SDK10) == null) {
                    manager.setURIValue(LinkIt10Helper.LINK_IT_SDK10, URIUtil.toURI(helper.getEnvironmentPath()));
                }

                if (monitor.isCanceled()) {
                    throw new OperationCanceledException();
                }

                project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1000));

                // Creates the .cproject file with the configurations
                ICProjectDescription projectDescription = helper.setCProjectDescription(project, true, monitor);

                // Add the C C++ AVR and other needed Natures to the project
                helper.addTheNatures(project);

                // Set the environment variables
                // ICProjectDescription projectDescription = CoreModel.getDefault().getProjectDescription(project);

                ICConfigurationDescription defaultConfigDescription = projectDescription
                        .getConfigurationByName(LinkItConst.LINKIT_CONFIGURATION_NAME);
                projectDescription.setActiveConfiguration(defaultConfigDescription);

                ICResourceDescription resourceDescription = defaultConfigDescription
                        .getResourceDescription(new Path(""), true);

                String devBoard = "__LINKIT_SDK__";
                try {
                    helper.setEnvironmentVariables(resourceDescription, devBoard);
                } catch (IOException e) {
                    String message = "Failed to set environmet variables " + project.getName();
                    Common.log(new Status(IStatus.ERROR, LinkItConst.CORE_PLUGIN_ID, message, e));
                    throw new OperationCanceledException(message);
                }

                helper.buildPathVariables(project, resourceDescription);

                if (!staticLib && !project.getFolder("LinkIt").exists()) {
                    helper.createNewFolder(project, "LinkIt", null);
                }
                helper.setIncludePaths(projectDescription, resourceDescription);

                helper.setMacros(projectDescription, devBoard);

                helper.setSourcePaths(projectDescription, false);

                projectDescription.setActiveConfiguration(defaultConfigDescription);
                projectDescription.setCdtProjectCreated();
                CoreModel.getDefault().getProjectDescriptionManager().setProjectDescription(project,
                        projectDescription, true, monitor);

                monitor.done();

            }
        };

        // run the new project creation operation
        try {
            getContainer().run(true, true, op);
        } catch (InterruptedException e) {
            return null;
        } catch (InvocationTargetException e) {
            // ie.- one of the steps resulted in a core exception
            Throwable t = e.getTargetException();
            if (t instanceof CoreException) {
                if (((CoreException) t).getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
                    MessageDialog.open(MessageDialog.ERROR, getShell(),
                            DataTransferMessages.WizardExternalProjectImportPage_errorMessage,
                            NLS.bind(DataTransferMessages.WizardExternalProjectImportPage_caseVariantExistsError,
                                    projectName),
                            SWT.SHEET);
                } else {
                    ErrorDialog.openError(getShell(),
                            DataTransferMessages.WizardExternalProjectImportPage_errorMessage, null,
                            ((CoreException) t).getStatus());
                }
            }
            return null;
        }

        return project;
    }

    private void copyProjectToWorkspace(IContainer resource, IPath locationPath, IProgressMonitor monitor)
            throws CoreException {
        File locPath = locationPath.toFile();
        if (locPath.isDirectory()) {
            File[] listFiles = locPath.listFiles();
            for (File child : listFiles) {
                String name = child.getName();
                if (!name.startsWith(".")) {
                    if (child.isDirectory()) {
                        IFolder folder = resource.getFolder(new Path(name));
                        folder.create(true, true, monitor);
                        IPath path = new Path(child.getAbsolutePath());
                        copyProjectToWorkspace(folder, path, monitor);
                    } else if (child.isFile()) {
                        IFile file = resource.getFile(new Path(name));
                        try {
                            file.create(new FileInputStream(child), true, monitor);
                        } catch (FileNotFoundException e) {
                            throw new CoreException(
                                    new Status(IStatus.ERROR, Activator.ID, "Failed to copy file", e));
                        }
                    }
                }
            }
        }
    }

    /*
     * see @DialogPage.setVisible(boolean)
     */
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible) {
            this.locationPathField.setFocus();
        }
    }

}