es.uah.aut.srg.micobs.ui.wizards.EmptyMICOBSProjectWizard.java Source code

Java tutorial

Introduction

Here is the source code for es.uah.aut.srg.micobs.ui.wizards.EmptyMICOBSProjectWizard.java

Source

/*******************************************************************************
 * Copyright (c) 2013-2015 UAH Space Research Group.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     MICOBS SRG Team - Initial API and implementation
 ******************************************************************************/
package es.uah.aut.srg.micobs.ui.wizards;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import org.eclipse.core.resources.IContainer;
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.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.team.core.TeamException;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.tigris.subversion.subclipse.core.ISVNRemoteFolder;
import org.tigris.subversion.subclipse.core.ISVNRepositoryLocation;
import org.tigris.subversion.subclipse.core.SVNException;
import org.tigris.subversion.subclipse.core.SVNProviderPlugin;
import org.tigris.subversion.subclipse.core.resources.SVNWorkspaceRoot;
import org.tigris.subversion.subclipse.ui.ISVNUIConstants;
import org.tigris.subversion.subclipse.ui.Policy;
import org.tigris.subversion.subclipse.ui.SVNUIPlugin;
import org.tigris.subversion.subclipse.ui.wizards.ConfigurationWizardMainPage;
import org.tigris.subversion.subclipse.ui.wizards.sharing.ISVNRepositoryLocationProvider;
import org.tigris.subversion.subclipse.ui.wizards.sharing.RepositorySelectionPage;

import es.uah.aut.srg.micobs.nature.MICOBSProjectNature;
import es.uah.aut.srg.micobs.plugin.MICOBSPlugin;
import es.uah.aut.srg.micobs.util.impl.MICOBSUtilProvider;
import es.uah.aut.srg.modeling.util.file.FileConverter;
import es.uah.aut.srg.modeling.util.svn.SVNUtil;
import es.uah.aut.srg.modeling.util.ui.GenDirectorySelectionPage;
import es.uah.aut.srg.modeling.util.ui.ISRGNewProjectWizard;

/**
 * Abstract class that implements the basis of a MICOBS project.
 * 
 */
public abstract class EmptyMICOBSProjectWizard extends Wizard implements INewWizard, ISRGNewProjectWizard {

    private EObject model;
    private IProject newProject;
    private IContainer rootFolder;

    private IMICOBSProjectCreationPage projectCreationPage;

    private ISVNRepositoryLocation[] locations;

    private RepositorySelectionPage locationPage;

    private ConfigurationWizardMainPage createLocationPage;

    private GenDirectorySelectionPage directoryPage;

    private boolean finalCommit = false;

    public EmptyMICOBSProjectWizard(String projectWindowTitle) {
        super();
        setWindowTitle(projectWindowTitle);
    }

    public EmptyMICOBSProjectWizard(String projectWindowTitle, boolean finalCommit) {
        super();
        setWindowTitle(projectWindowTitle);
        this.finalCommit = finalCommit;
    }

    protected IWorkbench workbench;

    protected IStructuredSelection selection;

    @Override
    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
        this.workbench = workbench;
        this.selection = currentSelection;

        initializeDefaultPageImageDescriptor();

    }

    /**
     * Returns the selected repository location.
     * 
     * If an error occurs when accessing the repository
     * locations, the method will throw a
     * {@link TeamException}.
     * 
     * @return the selected repository location.
     */
    protected ISVNRepositoryLocation getLocation() throws TeamException {

        // If the import page has a location, use it.
        if (locationPage != null) {
            ISVNRepositoryLocation location = locationPage.getLocation();
            if (location != null)
                return location;
        }

        // Otherwise, get the location from the create location page
        getShell().getDisplay().syncExec(new Runnable() {
            public void run() {
                createLocationPage.finish(new NullProgressMonitor());
            }
        });
        Properties properties = createLocationPage.getProperties();
        ISVNRepositoryLocation location = SVNProviderPlugin.getPlugin().getRepositories()
                .createRepository(properties);
        return location;
    }

    @Override
    public boolean canFinish() {
        IWizardPage page = getContainer().getCurrentPage();
        if (page == directoryPage) {
            return directoryPage.useProjectName() || directoryPage.getDirectoryName() != null;
        } else if (page == projectCreationPage && projectCreationPage.isPageComplete()
                && projectCreationPage.useExistingProject() == true) {
            return true;
        }
        return super.canFinish();
    }

    /**
     * Initializes the default image descriptor of the wizard.
     */
    protected void initializeDefaultPageImageDescriptor() {

        URI iconURI = URI.createPlatformPluginURI("/es.uah.aut.srg.micobs/icons/full/wizban/MICOBSNewWizard.gif",
                true);
        try {
            ImageDescriptor desc = ImageDescriptor.createFromURL(FileConverter.platformPluginURItoURL(iconURI));
            setDefaultPageImageDescriptor(desc);
        } catch (IOException e) {
            MICOBSPlugin.INSTANCE.log(e);
        }
    }

    /**
     * Method that shall be implemented by the derived classes that
     * proves the project creation page.
     * 
     * @param selection the selection if any from which the wizard has been
     *        triggered.
     *        
     * @return the project creation page that has been added.
     */
    public abstract IMICOBSProjectCreationPage addProjectCreationPage(IStructuredSelection selection);

    /**
     * Generates the initial set of files of the project. It shall be
     * implemented by the derived classes.
     * 
     * If an error occurs when generating the files, the method
     * will throw an {@link InvocationTargetException}
     * 
     * @param model the main model of the project.
     * @param rootFolder the container folder of the project.
     * @param progressMonitor the progress monitor that controls the activity.
     */
    protected abstract void generateFiles(EObject model, IContainer rootFolder, IProgressMonitor progressMonitor)
            throws InvocationTargetException;

    /**
     * Returns the main model of the project from the information obtained
     * from the user with the project creation page.
     * @param projectCreationPage the project creation page.
     * @return the main model of the project.
     */
    protected abstract EObject createModel(IMICOBSProjectCreationPage projectCreationPage);

    /**
     * Generates the skeleton of the project. It shall be
     * implemented by the derived classes.
     * 
     * If an error occurs when creating the folders, the method
     * will throw an {@link InvocationTargetException}
     * 
     * @param model the main model of the project.
     * @param rootFolder the container folder of the project.
     * @param progressMonitor the progress monitor that controls the activity.
     */
    protected abstract void createFolders(EObject model, IContainer rootFolder, IProgressMonitor monitor);

    @Override
    public void addPages() {

        projectCreationPage = addProjectCreationPage(selection);
        if (projectCreationPage == null) {
            return;
        }
        addPage(projectCreationPage);

        ImageDescriptor sharingImage = SVNUIPlugin.getPlugin().getImageDescriptor(ISVNUIConstants.IMG_WIZBAN_SHARE);

        IRunnableWithProgress runnable = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                locations = SVNUIPlugin.getPlugin().getRepositoryManager().getKnownRepositoryLocations(monitor);
            }
        };
        try {
            new ProgressMonitorDialog(getShell()).run(true, false, runnable);
        } catch (Exception e) {
            SVNUIPlugin.openError(getShell(), null, null, e, SVNUIPlugin.LOG_TEAM_EXCEPTIONS);
        }
        if (locations.length > 0) {
            locationPage = new RepositorySelectionPage("importPage", Policy.bind("SharingWizard.importTitle"), //$NON-NLS-1$//$NON-NLS-2$
                    sharingImage);
            locationPage.setDescription(Policy.bind("SharingWizard.importTitleDescription")); //$NON-NLS-1$
            addPage(locationPage);
        }
        createLocationPage = new ConfigurationWizardMainPage("createLocationPage", //$NON-NLS-1$
                Policy.bind("SharingWizard.enterInformation"), sharingImage); //$NON-NLS-1$
        createLocationPage.setDescription(Policy.bind("SharingWizard.enterInformationDescription")); //$NON-NLS-1$
        addPage(createLocationPage);
        createLocationPage.setDialogSettings(getDialogSettings());
        ISVNRepositoryLocationProvider repositoryLocationProvider = new ISVNRepositoryLocationProvider() {
            public ISVNRepositoryLocation getLocation() throws TeamException {
                return EmptyMICOBSProjectWizard.this.getLocation();
            }

            public IProject getProject() {
                return EmptyMICOBSProjectWizard.this.newProject;
            }
        };
        directoryPage = new GenDirectorySelectionPage("modulePage", Policy.bind("SharingWizard.enterModuleName"), //$NON-NLS-1$//$NON-NLS-2$
                sharingImage, repositoryLocationProvider, this);
        directoryPage.setDescription(Policy.bind("SharingWizard.enterModuleNameDescription")); //$NON-NLS-1$
        addPage(directoryPage);

    }

    /**
     * Adds the MICOBS and Xtext natures to the project.
     * @param project
     */
    protected void addProjectNature(IProject project) {
        MICOBSProjectNature.addNature(project);
        // And the Xtext nature:
        MICOBSUtilProvider.getMICOBSUtil().addXtextNature(project);
    }

    @Override
    public boolean needsProgressMonitor() {
        return true;
    }

    @Override
    public boolean performFinish() {
        try {
            getContainer().run(true, true, new IRunnableWithProgress() {

                @Override
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    monitor.beginTask("Creating project", 100); //$NON-NLS-1$

                    final Exception except[] = new Exception[1];

                    getShell().getDisplay().asyncExec(new Runnable() {

                        @Override
                        public void run() {
                            WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
                                protected void execute(IProgressMonitor progressMonitor)
                                        throws CoreException, InvocationTargetException, InterruptedException {
                                    model = createModel(projectCreationPage);
                                    newProject = projectCreationPage.getProjectHandle();

                                    if (projectCreationPage.useExistingProject() == false) {
                                        IProjectDescription description = ResourcesPlugin.getWorkspace()
                                                .newProjectDescription(newProject.getName());
                                        description.setLocationURI(projectCreationPage.getProjectLocationURI());

                                        if (!newProject.exists()) {
                                            newProject.create(description,
                                                    new SubProgressMonitor(progressMonitor, 50));
                                        }

                                        newProject.open(IResource.BACKGROUND_REFRESH,
                                                new SubProgressMonitor(progressMonitor, 50));
                                        rootFolder = newProject;
                                        addProjectNature(newProject);
                                    } else {
                                        rootFolder = projectCreationPage.getRootFolder()
                                                .getFolder(new Path(projectCreationPage.getProjectName()));
                                        addProjectNature(newProject);

                                        if (rootFolder instanceof IFolder
                                                && ((IFolder) rootFolder).exists() == false) {
                                            ((IFolder) rootFolder).create(true, true, progressMonitor);
                                        }

                                    }

                                }
                            };

                            try {
                                getContainer().run(false, true, op);
                            } catch (InvocationTargetException e) {
                                except[0] = e;
                            } catch (InterruptedException e) {
                                except[0] = e;
                            }
                        }
                    });

                    if (except[0] != null) {
                        if (except[0] instanceof InvocationTargetException) {
                            throw (InvocationTargetException) except[0];
                        }
                        if (except[0] instanceof InterruptedException) {
                            throw (InterruptedException) except[0];
                        }
                        throw new InvocationTargetException(except[0]);
                    }

                    monitor.worked(10);
                    monitor.subTask("Creating folders");

                    getShell().getDisplay().asyncExec(new Runnable() {

                        @Override
                        public void run() {

                            WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
                                protected void execute(IProgressMonitor progressMonitor)
                                        throws CoreException, InvocationTargetException, InterruptedException {
                                    createFolders(model, rootFolder, progressMonitor);
                                }
                            };

                            try {
                                getContainer().run(false, true, op);
                            } catch (InvocationTargetException e) {
                                except[0] = e;
                            } catch (InterruptedException e) {
                                except[0] = e;
                            }
                        }
                    });

                    if (except[0] != null) {
                        if (except[0] instanceof InvocationTargetException) {
                            throw (InvocationTargetException) except[0];
                        }
                        if (except[0] instanceof InterruptedException) {
                            throw (InterruptedException) except[0];
                        }
                        throw new InvocationTargetException(except[0]);
                    }

                    monitor.worked(10);
                    if (projectCreationPage.useExistingProject() == false) {
                        monitor.subTask("Sharing project");

                        getShell().getDisplay().syncExec(new Runnable() {

                            @Override
                            public void run() {

                                try {
                                    getContainer().run(false, true, new IRunnableWithProgress() {

                                        public void run(IProgressMonitor monitor)
                                                throws InvocationTargetException, InterruptedException {
                                            shareProject(newProject, monitor);
                                        }
                                    });

                                } catch (InvocationTargetException e) {
                                    except[0] = e;
                                } catch (InterruptedException e) {
                                    except[0] = e;
                                }
                            }
                        });

                        if (except[0] != null) {
                            if (except[0] instanceof InvocationTargetException) {
                                throw (InvocationTargetException) except[0];
                            }
                            if (except[0] instanceof InterruptedException) {
                                throw (InterruptedException) except[0];
                            }
                            throw new InvocationTargetException(except[0]);
                        }
                    }
                    monitor.worked(20);
                    monitor.subTask("Generating files");

                    getShell().getDisplay().asyncExec(new Runnable() {

                        @Override
                        public void run() {
                            WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
                                protected void execute(IProgressMonitor progressMonitor)
                                        throws CoreException, InvocationTargetException, InterruptedException {
                                    generateFiles(model, rootFolder, progressMonitor);
                                }
                            };

                            try {
                                getContainer().run(false, true, op);
                            } catch (InvocationTargetException e) {
                                except[0] = e;
                            } catch (InterruptedException e) {
                                except[0] = e;
                            }
                        }
                    });

                    if (except[0] != null) {
                        if (except[0] instanceof InvocationTargetException) {
                            throw (InvocationTargetException) except[0];
                        }
                        if (except[0] instanceof InterruptedException) {
                            throw (InterruptedException) except[0];
                        }
                        throw new InvocationTargetException(except[0]);
                    }

                    monitor.worked(20);
                    monitor.subTask("Refreshing");

                    getShell().getDisplay().asyncExec(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                getContainer().run(false, true, new IRunnableWithProgress() {
                                    public void run(IProgressMonitor monitor)
                                            throws InvocationTargetException, InterruptedException {
                                        try {
                                            newProject.refreshLocal(IProject.DEPTH_INFINITE, monitor);
                                        } catch (CoreException e) {
                                            except[0] = e;
                                        }
                                        if (projectCreationPage.useExistingProject() == false
                                                && finalCommit == true) {
                                            SVNUtil.commitProject(newProject);
                                        }
                                    }
                                });
                            } catch (InvocationTargetException e) {
                                except[0] = e;
                            } catch (InterruptedException e) {
                                except[0] = e;
                            }
                        }
                    });

                    if (except[0] != null) {
                        if (except[0] instanceof InvocationTargetException) {
                            throw (InvocationTargetException) except[0];
                        }
                        if (except[0] instanceof InterruptedException) {
                            throw (InterruptedException) except[0];
                        }
                        throw new InvocationTargetException(except[0]);
                    }
                    monitor.done();
                }
            });
        } catch (InvocationTargetException e) {
            MICOBSPlugin.INSTANCE.log(e);
            return false;
        } catch (InterruptedException e) {
            return false;
        }
        return true;
    }

    /**
     * Shares the project in the selected SVN repository folder.
     * 
     * If an error occurs when accessing the SVN repository, the method
     * will throw an {@link InvocationTargetException}. If the sharing
     * is interrupted by the user, the method will throw an
     * {@link InterruptedException}.
     * 
     * @param project the project that is being created.
     * @param monitor the progress monitor that controls the activity.
     */
    private void shareProject(IProject project, IProgressMonitor monitor)
            throws InterruptedException, InvocationTargetException {

        monitor.beginTask("Sharing project", 100);
        shareCanceled = false;

        // check if the remote directory already exist
        final String remoteDirectoryName = getRemoteDirectoryName();

        monitor.beginTask("Sharing Project", 100); //$NON-NLS-1$
        // Check if the directory exists on the server

        ISVNRepositoryLocation location = null;
        boolean isKnown = false;
        boolean createDirectory = true;

        try {
            location = getLocation();
            isKnown = SVNProviderPlugin.getPlugin().getRepositories().isKnownRepository(location.getLocation(),
                    false);

            // Purge any svn folders that may exists in subfolders
            SVNWorkspaceRoot.getSVNFolderFor(project).unmanage(null);

            ISVNRemoteFolder folder = location.getRemoteFolder(remoteDirectoryName);
            if (folder.exists(new SubProgressMonitor(monitor, 50))) {
                getShell().getDisplay().syncExec(new Runnable() {
                    public void run() {
                        if (!MessageDialog.openQuestion(getShell(), Policy.bind("SharingWizard.couldNotImport"), //$NON-NLS-1$
                                Policy.bind("SharingWizard.couldNotImportLong"))) { //$NON-NLS-1$
                            shareCanceled = true;
                            return;
                        }
                    }
                });
                if (shareCanceled) {
                    throw new InterruptedException();
                }
                createDirectory = false;
            }
        } catch (TeamException e) {
            SVNUIPlugin.openError(getShell(), null, null, e, SVNUIPlugin.PERFORM_SYNC_EXEC);
            throw new InvocationTargetException(e);
        }

        try {
            // Add the location to the provider if it is new
            if (!isKnown) {
                SVNProviderPlugin.getPlugin().getRepositories().addOrUpdateRepository(location);
            }

            // Create the remote module for the project
            SVNWorkspaceRoot.shareProject(location, newProject, remoteDirectoryName, "Initial import.",
                    createDirectory, new SubProgressMonitor(monitor, 50));

            project.refreshLocal(IProject.DEPTH_INFINITE, new SubProgressMonitor(monitor, 50));
        } catch (SVNException e) {
            throw new InvocationTargetException(e);
        } catch (CoreException e) {
            throw new InvocationTargetException(e);
        } finally {
            monitor.done();
        }
    }

    private boolean shareCanceled;

    @Override
    public IWizardPage getNextPage(IWizardPage page) {
        if (page == locationPage) {
            if (locationPage.getLocation() == null) {
                return createLocationPage;
            } else {
                return directoryPage;
            }
        }
        if (page == createLocationPage) {
            return directoryPage;
        }
        if (page == projectCreationPage && projectCreationPage.useExistingProject() == true) {
            return null;
        }

        return super.getNextPage(page);
    }

    @Override
    public String getProjectName() {
        return projectCreationPage.getProjectName();
    }

    /**
     * Returns the name of the remote folder where the project will be
     * shared.
     * @return the name of the remote folder where the project will be
     * shared.
     */
    private String getRemoteDirectoryName() {
        String moduleName = directoryPage.getDirectoryName();
        if (moduleName == null)
            moduleName = this.getProjectName();
        return moduleName;
    }

}