/*******************************************************************************
* Copyright (c) 2002, 2009 Rational Software Corporation and others.
* 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:
* IBM Rational Software - Initial API and implementation
* Intel corp - rework for New Project Model
*******************************************************************************/
package org.eclipse.cdt.ui.wizards;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation;
import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.newui.Messages;
import org.eclipse.cdt.internal.ui.wizards.ICDTCommonProjectWizard;
public abstract class CDTCommonProjectWizard extends BasicNewResourceWizard
implements IExecutableExtension, IWizardWithMemory, ICDTCommonProjectWizard
{
private static final String PREFIX= "CProjectWizard"; //$NON-NLS-1$
private static final String OP_ERROR= "CProjectWizard.op_error"; //$NON-NLS-1$
private static final String title= CUIPlugin.getResourceString(OP_ERROR + ".title"); //$NON-NLS-1$
private static final String message= CUIPlugin.getResourceString(OP_ERROR + ".message"); //$NON-NLS-1$
private static final String[] EMPTY_ARR = new String[0];
protected IConfigurationElement fConfigElement;
protected CDTMainWizardPage fMainPage;
protected IProject newProject;
private String wz_title;
private String wz_desc;
private boolean existingPath = false;
private String lastProjectName = null;
private URI lastProjectLocation = null;
private CWizardHandler savedHandler = null;
public CDTCommonProjectWizard() {
this(Messages.NewModelProjectWizard_0,Messages.NewModelProjectWizard_1);
}
public CDTCommonProjectWizard(String title, String desc) {
super();
setDialogSettings(CUIPlugin.getDefault().getDialogSettings());
setNeedsProgressMonitor(true);
setForcePreviousAndNextButtons(true);
setWindowTitle(title);
wz_title = title;
wz_desc = desc;
}
@Override
public void addPages() {
fMainPage= new CDTMainWizardPage(CUIPlugin.getResourceString(PREFIX));
fMainPage.setTitle(wz_title);
fMainPage.setDescription(wz_desc);
addPage(fMainPage);
}
/**
* @return true if user has changed settings since project creation
*/
private boolean isChanged() {
if (savedHandler != fMainPage.h_selected)
return true;
if (!fMainPage.getProjectName().equals(lastProjectName))
return true;
URI projectLocation = fMainPage.getProjectLocation();
if (projectLocation == null) {
if (lastProjectLocation != null)
return true;
} else if (!projectLocation.equals(lastProjectLocation))
return true;
return savedHandler.isChanged();
}
public IProject getProject(boolean defaults) {
return getProject(defaults, true);
}
public IProject getProject(boolean defaults, boolean onFinish) {
if (newProject != null && isChanged())
clearProject();
if (newProject == null) {
existingPath = false;
try {
IFileStore fs;
URI p = fMainPage.getProjectLocation();
if (p == null) {
fs = EFS.getStore(ResourcesPlugin.getWorkspace().getRoot().getLocationURI());
fs = fs.getChild(fMainPage.getProjectName());
} else
fs = EFS.getStore(p);
IFileInfo f = fs.fetchInfo();
if (f.exists() && f.isDirectory()) {
if (fs.getChild(".project").fetchInfo().exists()) { //$NON-NLS-1$
if (!MessageDialog.openConfirm(getShell(), Messages.CDTCommonProjectWizard_0, Messages.CDTCommonProjectWizard_1))
return null;
}
existingPath = true;
}
} catch (CoreException e) {
CUIPlugin.log(e.getStatus());
}
savedHandler = fMainPage.h_selected;
savedHandler.saveState();
lastProjectName = fMainPage.getProjectName();
lastProjectLocation = fMainPage.getProjectLocation();
// start creation process
invokeRunnable(getRunnable(defaults, onFinish));
}
return newProject;
}
/**
* Remove created project either after error
* or if user returned back from config page.
*/
private void clearProject() {
if (lastProjectName == null) return;
try {
ResourcesPlugin.getWorkspace().getRoot().getProject(lastProjectName).delete(!existingPath, true, null);
} catch (CoreException ignore) {}
newProject = null;
lastProjectName = null;
lastProjectLocation = null;
}
private boolean invokeRunnable(IRunnableWithProgress runnable) {
IRunnableWithProgress op= new WorkspaceModifyDelegatingOperation(runnable);
try {
getContainer().run(true, true, op);
} catch (InvocationTargetException e) {
CUIPlugin.errorDialog(getShell(), title, message, e.getTargetException(), true);
clearProject();
return false;
} catch (InterruptedException e) {
clearProject();
return false;
}
return true;
}
@Override
public boolean performFinish() {
boolean needsPost = (newProject != null && !isChanged());
// create project if it is not created yet
if (getProject(fMainPage.isCurrent(), true) == null)
return false;
fMainPage.h_selected.postProcess(newProject, needsPost);
try {
setCreated();
} catch (CoreException e) {
e.printStackTrace();
return false;
}
BasicNewProjectResourceWizard.updatePerspective(fConfigElement);
selectAndReveal(newProject);
return true;
}
protected boolean setCreated() throws CoreException {
ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager();
ICProjectDescription des = mngr.getProjectDescription(newProject, false);
if(des == null ) {
return false;
}
if(des.isCdtProjectCreating()){
des = mngr.getProjectDescription(newProject, true);
des.setCdtProjectCreated();
mngr.setProjectDescription(newProject, des, false, null);
return true;
}
return false;
}
@Override
public boolean performCancel() {
clearProject();
return true;
}
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
fConfigElement= config;
}
private IRunnableWithProgress getRunnable(boolean _defaults, final boolean onFinish) {
final boolean defaults = _defaults;
return new IRunnableWithProgress() {
public void run(IProgressMonitor imonitor) throws InvocationTargetException, InterruptedException {
final Exception except[] = new Exception[1];
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
IRunnableWithProgress op= new WorkspaceModifyDelegatingOperation(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
final IProgressMonitor fMonitor;
if (monitor == null) {
fMonitor= new NullProgressMonitor();
} else {
fMonitor = monitor;
}
fMonitor.beginTask(CUIPlugin.getResourceString("CProjectWizard.op_description"), 100); //$NON-NLS-1$
fMonitor.worked(10);
try {
newProject = createIProject(lastProjectName, lastProjectLocation, new SubProgressMonitor(fMonitor, 40));
if (newProject != null)
fMainPage.h_selected.createProject(newProject, defaults, onFinish, new SubProgressMonitor(fMonitor, 40));
fMonitor.worked(10);
} catch (CoreException e) { CUIPlugin.log(e); }
finally {
fMonitor.done();
}
}
});
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]);
}
}
};
}
public IProject createIProject(final String name, final URI location) throws CoreException{
return createIProject(name, location, new NullProgressMonitor());
}
/**
* @since 5.1
*/
protected IProgressMonitor continueCreationMonitor;
/**
* @param monitor
* @since 5.1
*
*/
public IProject createIProject(final String name, final URI location, IProgressMonitor monitor) throws CoreException{
monitor.beginTask(Messages.CDTCommonProjectWizard_creatingProject, 100);
if (newProject != null) return newProject;
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot root = workspace.getRoot();
final IProject newProjectHandle = root.getProject(name);
if (!newProjectHandle.exists()) {
// IWorkspaceDescription workspaceDesc = workspace.getDescription();
// workspaceDesc.setAutoBuilding(false);
// workspace.setDescription(workspaceDesc);
IProjectDescription description = workspace.newProjectDescription(newProjectHandle.getName());
if(location != null)
description.setLocationURI(location);
newProject = CCorePlugin.getDefault().createCDTProject(description, newProjectHandle, new SubProgressMonitor(monitor,25));
} else {
IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
newProjectHandle.refreshLocal(IResource.DEPTH_INFINITE, monitor);
}
};
workspace.run(runnable, root, IWorkspace.AVOID_UPDATE, new SubProgressMonitor(monitor,25));
newProject = newProjectHandle;
}
// Open the project if we have to
if (!newProject.isOpen()) {
newProject.open(new SubProgressMonitor(monitor,25));
}
continueCreationMonitor = new SubProgressMonitor(monitor,25);
IProject proj = continueCreation(newProject);
monitor.done();
return proj;
}
protected abstract IProject continueCreation(IProject prj);
public abstract String[] getNatures();
@Override
public void dispose() {
fMainPage.dispose();
}
@Override
public boolean canFinish() {
if (fMainPage.h_selected != null) {
if(!fMainPage.h_selected.canFinish())
return false;
String s = fMainPage.h_selected.getErrorMessage();
if (s != null) return false;
}
return super.canFinish();
}
/**
* Returns last project name used for creation
*/
public String getLastProjectName() {
return lastProjectName;
}
public URI getLastProjectLocation() {
return lastProjectLocation;
}
public IProject getLastProject() {
return newProject;
}
// Methods below should provide data for language check
public String[] getLanguageIDs (){
String[] contentTypeIds = getContentTypeIDs();
if(contentTypeIds.length > 0) {
IContentTypeManager manager = Platform.getContentTypeManager();
List<String> languageIDs = new ArrayList<String>();
for(int i = 0; i < contentTypeIds.length; ++i) {
IContentType contentType = manager.getContentType(contentTypeIds[i]);
if(null != contentType) {
ILanguage language = LanguageManager.getInstance().getLanguage(contentType);
if(!languageIDs.contains(language.getId())) {
languageIDs.add(language.getId());
}
}
}
return languageIDs.toArray(new String[languageIDs.size()]);
}
return EMPTY_ARR;
}
public String[] getContentTypeIDs (){
return EMPTY_ARR;
}
public String[] getExtensions (){
String[] contentTypeIds = getContentTypeIDs();
if(contentTypeIds.length > 0) {
IContentTypeManager manager = Platform.getContentTypeManager();
List<String> extensions = new ArrayList<String>();
for(int i = 0; i < contentTypeIds.length; ++i) {
IContentType contentType = manager.getContentType(contentTypeIds[i]);
if(null != contentType) {
String[] thisTypeExtensions = contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
extensions.addAll(Arrays.asList(thisTypeExtensions));
}
}
return extensions.toArray(new String[extensions.size()]);
}
return EMPTY_ARR;
}
}