/******************************************************************************* * Copyright (c) 2012, 2013 GoPivotal, Inc. * 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: * GoPivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.wizard.template; import java.lang.reflect.InvocationTargetException; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IWorkspaceDescription; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.internal.ui.util.ExceptionHandler; import org.eclipse.jdt.internal.ui.wizards.NewElementWizard; import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin; import org.springframework.ide.eclipse.wizard.WizardImages; import org.springframework.ide.eclipse.wizard.template.infrastructure.Template; /** * @author Terry Denney * @author Leo Dos Santos * @author Christian Dupuis * @author Martin Lippert * @author Nieraj Singh */ @SuppressWarnings("restriction") // TODO: remove dependency to NewElementWizard? Finish page functionality that // is launched in a workspace job is the only useful dependency to the // NewElementWizard /** * Creates a new spring project based on either a template, or a simple project that is either Java-based or Maven. * <p/> * The different types of projects that this wizard handles is provided by a Wizard section via a wizard section factory. * * */ public class NewSpringProjectWizard extends NewElementWizard implements INewWizard { private final NewSpringProjectWizardMainPage mainPage; private final SpringWizardSectionFactory sectionFactory; private final NewSpringProjectWizardModel model = new NewSpringProjectWizardModel(); private IProject project; public NewSpringProjectWizard() { setWindowTitle("New Spring Legacy Project"); setDefaultPageImageDescriptor(WizardImages.TEMPLATE_WIZARD_ICON); setForcePreviousAndNextButtons(true); setNeedsProgressMonitor(true); sectionFactory = new SpringWizardSectionFactory(this); mainPage = new NewSpringProjectWizardMainPage(model); mainPage.setTitle(NewSpringProjectWizardMessages.NewProject_title); mainPage.setDescription("Create a Spring project by selecting a template or simple project type."); } public NewSpringProjectWizardMainPage getMainPage() { return mainPage; } public NewSpringProjectWizardModel getModel() { return model; } @Override public void addPages() { addPage(mainPage); // Also preload any section pages that require their controls to be // created // before a user clicks "Next", as some sections may need access to the // controls // if the user clicks "Finish" from the first page without ever going to // the next page List<SpringProjectWizardSection> sections = sectionFactory.loadSections(); for (SpringProjectWizardSection section : sections) { List<IWizardPage> pages = section.loadPages(); if (pages != null) { for (IWizardPage page : pages) { addPage(page); } } } } /** * * @param page current page * @return true if the template section contributes more pages to the wizard * given a current page. False otherwise */ public boolean hasPages(IWizardPage page) { SpringProjectWizardSection section = getSection(); if (section != null) { return section.hasNextPage(page); } return false; } // @Override @Override public boolean canFinish() { boolean canFinish = mainPage.isPageComplete(); if (canFinish) { SpringProjectWizardSection section = getSection(); if (section != null) { canFinish = section.canFinish(); } else { // At least one section must be selected canFinish = false; } } return canFinish; } protected SpringProjectWizardSection getSection() { Template template = getModel().selectedTemplate.getValue(); if (template != null) { ProjectWizardDescriptor descriptor = new ProjectWizardDescriptor(template); return sectionFactory.getSection(descriptor); } return null; } @Override public IWizardPage getNextPage(IWizardPage page) { SpringProjectWizardSection section = getSection(); // Always make sure the sections decide the progression of the pages if (section != null) { return section.getNextPage(page); } return null; } @Override public boolean performFinish() { // This will indirectly launch the project creation in a workspace job boolean finish = super.performFinish(); // Once done, see if there is further configuration for the project, in // addition to handling // revealing the project in the workspace and adding it to working sets if (finish) { // Once the project creation job is done, launch any // configuration on the project, which // may involve workspace modification operations, if the section // implementation specifies it SpringProjectWizardSection section = getSection(); if (section != null) { CoreException coreException = null; try { ProjectConfiguration configuration = section.getProjectConfiguration(); // Creating and configuring projects are separate steps for // now // as creating projects may need to be run in the UI thread // to access // wizard page widgets // while configuring the project does not. This is only // required as the wizard // was merged from two prior separate wizards, and the UI // coupling of the project // creation wasn't fully refactored out. IProject project = createProject(configuration); configureProject(project, configuration); } catch (InterruptedException e) { return false; } catch (InvocationTargetException error) { Throwable t = error.getTargetException(); if (t instanceof CoreException) { coreException = (CoreException) t; } else { // CoreExceptions are handled separately, but unexpected // runtime // exceptions and errors may still occur. BeansUIPlugin.getDefault().getLog() .log(new Status(IStatus.ERROR, BeansUIPlugin.PLUGIN_ID, 0, t.toString(), t)); MessageDialog.openError(getShell(), NewSpringProjectWizardMessages.NewProject_errorMessage, NLS.bind(NewSpringProjectWizardMessages.NewProject_internalError, t.getMessage())); } } catch (CoreException ce) { coreException = ce; } if (coreException != null) { handleError(coreException); } } } return finish; } protected IProject createProject(final ProjectConfiguration projectConfiguration) throws InterruptedException, InvocationTargetException, CoreException { // Prevent workspace builds when first creating project to avoid error // markers // from appearing, as the project will later be configured and built // again. enableWorkspaceBuild(false); WorkspaceModifyOperation op = new WorkspaceModifyOperation() { @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { project = projectConfiguration.createProject(monitor); } }; // Do not fork. Run in UI thread as project creation may // require access to widgets in wizard pages getContainer().run(false, true, op); return project; } protected void configureProject(final IProject project, final ProjectConfiguration projectConfiguration) throws InterruptedException, InvocationTargetException, CoreException { enableWorkspaceBuild(true); final IWorkingSet[] workingSets = getWorkingSets(); final WorkspaceModifyOperation op = new WorkspaceModifyOperation() { @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { projectConfiguration.configureProject(monitor); // The project was created , even if there are // errors, still // select and reveal it selectAndReveal(project); if (workingSets != null && workingSets.length > 0) { PlatformUI.getWorkbench().getWorkingSetManager().addToWorkingSets(project, workingSets); } } }; // Run in UI thread as some dialogues may open during configuration getContainer().run(false, false, op); } protected void enableWorkspaceBuild(boolean enable) throws CoreException { IWorkspaceDescription wsd = ResourcesPlugin.getWorkspace().getDescription(); if (!wsd.isAutoBuilding() == enable) { wsd.setAutoBuilding(enable); ResourcesPlugin.getWorkspace().setDescription(wsd); } } protected void handleError(CoreException coreException) { if (coreException != null) { if (coreException.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { String projectName = project != null ? project.getName() : ""; MessageDialog.openError(getShell(), NewSpringProjectWizardMessages.NewProject_errorMessage, NLS.bind(NewSpringProjectWizardMessages.NewProject_caseVariantExistsError, projectName)); } else { // no special message ErrorDialog.openError(getShell(), NewSpringProjectWizardMessages.NewProject_errorMessage, null, coreException.getStatus()); } } } public IWorkingSet[] getWorkingSets() { return mainPage.getSelectedWorkingSets(); } @Override protected void handleFinishException(Shell shell, InvocationTargetException e) { String title = NewWizardMessages.JavaProjectWizard_op_error_title; String message = NewWizardMessages.JavaProjectWizard_op_error_create_message; ExceptionHandler.handle(e, getShell(), title, message); } public void selectAndReveal(final IProject project) { super.selectAndReveal(project); // TODO: Alternative to using the NewElementWizard select and reveal // once NewElementWizard dependency is removed // getContainer().getShell().getDisplay().syncExec(new Runnable() { // // public void run() { // BasicNewResourceWizard.selectAndReveal(project, // getWorkbench().getActiveWorkbenchWindow()); // } // }); } @Override public IJavaElement getCreatedElement() { // Doesnt seem to be needed. return null; } // @Override @Override protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException { } @Override public boolean performCancel() { SpringProjectWizardSection section = getSection(); if (section != null) { section.cancel(); } return true; } }