/*******************************************************************************
* Copyright (c) 2010-2013 SAP AG 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:
* Mathias Kinzler (SAP AG) - initial implementation
* Stefan Lay (SAP AG) - improvements
*******************************************************************************/
package org.eclipse.egit.ui.internal.clone;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.egit.core.op.ConnectProviderOperation;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIIcons;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.clone.GitCloneSourceProviderExtension.CloneSourceProvider;
import org.eclipse.egit.ui.internal.provisional.wizards.GitRepositoryInfo;
import org.eclipse.egit.ui.internal.provisional.wizards.IRepositorySearchResult;
import org.eclipse.egit.ui.internal.provisional.wizards.NoRepositoryInfoException;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.NewProjectAction;
/**
* A wizard which allows to optionally clone a repository and to import projects from a repository.
*/
public class GitImportWizard extends AbstractGitCloneWizard implements IImportWizard {
private static final String GIT_IMPORT_SECTION = "GitImportWizard"; //$NON-NLS-1$
private GitSelectRepositoryPage selectRepoPage = new GitSelectRepositoryPage(
false);
private GitSelectWizardPage importWithDirectoriesPage = new GitSelectWizardPage(){
@Override
public void setVisible(boolean visible) {
if (existingRepo == null && visible && (cloneDestination.cloneSettingsChanged())) {
setCallerRunsCloneOperation(true);
try {
final GitRepositoryInfo repositoryInfo = currentSearchResult.getGitRepositoryInfo();
performClone(repositoryInfo);
importWithDirectoriesPage.getControl().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
runCloneOperation(getContainer(), repositoryInfo);
cloneDestination.saveSettingsForClonedRepo();
}});
} catch (URISyntaxException e) {
Activator.error(UIText.GitImportWizard_errorParsingURI, e);
} catch (NoRepositoryInfoException e) {
Activator.error(UIText.GitImportWizard_noRepositoryInfo, e);
} catch (Exception e) {
Activator.error(e.getMessage(), e);
}
}
super.setVisible(visible);
}
};
private GitProjectsImportPage projectsImportPage = new GitProjectsImportPage() {
@Override
public void setVisible(boolean visible) {
if (visible)
setProjectsList(importWithDirectoriesPage.getPath());
super.setVisible(visible);
}
};
private GitCreateGeneralProjectPage createGeneralProjectPage = new GitCreateGeneralProjectPage() {
@Override
public void setVisible(boolean visible) {
if (visible)
setPath(importWithDirectoriesPage.getPath());
super.setVisible(visible);
}
};
private Repository existingRepo;
/**
* The default constructor
*/
public GitImportWizard() {
this(null);
}
/**
* Construct the import wizard based on given repository search result. The
* wizard skips the repository location page in this case.
*
* @param searchResult
* the search result to initialize the import wizard with.
*/
public GitImportWizard(IRepositorySearchResult searchResult) {
super(searchResult);
setWindowTitle(UIText.GitImportWizard_WizardTitle);
setDefaultPageImageDescriptor(UIIcons.WIZBAN_IMPORT_REPO);
setDialogSettings(getImportWizardDialogSettings());
}
@Override
protected void addPreClonePages() {
if (!hasSearchResult())
addPage(selectRepoPage);
}
@Override
protected void addPostClonePages() {
addPage(importWithDirectoriesPage);
addPage(projectsImportPage);
addPage(createGeneralProjectPage);
}
@Override
protected List<CloneSourceProvider> getCloneSourceProviders() {
List<CloneSourceProvider> cloneSourceProvider = super.getCloneSourceProviders();
cloneSourceProvider.add(0, CloneSourceProvider.LOCAL);
return cloneSourceProvider;
}
@Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
// nothing to do
}
@Override
public IWizardPage getNextPage(IWizardPage page) {
if (page == selectRepoPage) {
existingRepo = selectRepoPage.getRepository();
importWithDirectoriesPage.setRepository(selectRepoPage
.getRepository());
return importWithDirectoriesPage;
} else if (page == cloneDestination) {
existingRepo = null;
importWithDirectoriesPage.setRepository(getTargetRepository());
return importWithDirectoriesPage;
} else if (page == importWithDirectoriesPage)
switch (importWithDirectoriesPage.getWizardSelection()) {
case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD:
return projectsImportPage;
case GitSelectWizardPage.NEW_WIZARD:
return null;
case GitSelectWizardPage.GENERAL_WIZARD:
return createGeneralProjectPage;
}
else if (page == createGeneralProjectPage
|| page == projectsImportPage)
return null;
return super.getNextPage(page);
}
private Repository getTargetRepository() {
if (existingRepo != null)
return existingRepo;
else
try {
return org.eclipse.egit.core.Activator
.getDefault()
.getRepositoryCache()
.lookupRepository(
new File(cloneDestination.getDestinationFile(),
Constants.DOT_GIT));
} catch (IOException e) {
Activator
.error("Error looking up repository at " + cloneDestination.getDestinationFile(), e); //$NON-NLS-1$
return null;
}
}
@Override
public boolean performFinish() {
try {
getContainer().run(true, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
importProjects(monitor);
}
});
} catch (InvocationTargetException e) {
Activator
.handleError(e.getCause().getMessage(), e.getCause(), true);
return false;
} catch (InterruptedException e) {
Activator.handleError(
UIText.GitCreateProjectViaWizardWizard_AbortedMessage, e,
true);
return false;
}
return true;
}
@Override
public boolean canFinish() {
switch (importWithDirectoriesPage.getWizardSelection()) {
case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD:
return projectsImportPage.isPageComplete();
case GitSelectWizardPage.NEW_WIZARD:
return true;
case GitSelectWizardPage.GENERAL_WIZARD:
return createGeneralProjectPage.isPageComplete();
}
return super.canFinish();
}
private void importProjects(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
switch (importWithDirectoriesPage.getWizardSelection()) {
case GitSelectWizardPage.EXISTING_PROJECTS_WIZARD: {
final Set<ProjectRecord> projectsToCreate = new HashSet<>();
final List<IWorkingSet> workingSets = new ArrayList<>();
// get the data from the pages in the UI thread
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
projectsToCreate.addAll(projectsImportPage
.getCheckedProjects());
IWorkingSet[] workingSetArray = projectsImportPage
.getSelectedWorkingSets();
workingSets.addAll(Arrays.asList(workingSetArray));
projectsImportPage.saveWidgetValues();
}
});
ProjectUtils.createProjects(projectsToCreate,
workingSets.toArray(new IWorkingSet[workingSets.size()]),
monitor);
break;
}
case GitSelectWizardPage.NEW_WIZARD: {
final File[] repoDir = new File[1];
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
repoDir[0] = getTargetRepository().getDirectory();
}
});
final List<IProject> previousProjects = Arrays
.asList(ResourcesPlugin.getWorkspace().getRoot()
.getProjects());
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
new NewProjectAction(PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()).run();
}
});
IWorkspaceRunnable wsr = new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor actMonitor)
throws CoreException {
IProject[] currentProjects = ResourcesPlugin.getWorkspace()
.getRoot().getProjects();
SubMonitor progress = SubMonitor.convert(actMonitor,
currentProjects.length);
for (IProject current : currentProjects)
if (!previousProjects.contains(current)) {
ConnectProviderOperation cpo = new ConnectProviderOperation(
current, repoDir[0]);
cpo.execute(progress.newChild(1));
} else {
progress.worked(1);
}
}
};
try {
ResourcesPlugin.getWorkspace().run(wsr, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
break;
}
case GitSelectWizardPage.GENERAL_WIZARD: {
final String[] projectName = new String[1];
final boolean[] defaultLocation = new boolean[1];
final String[] path = new String[1];
final File[] repoDir = new File[1];
// get the data from the page in the UI thread
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
projectName[0] = createGeneralProjectPage.getProjectName();
defaultLocation[0] = createGeneralProjectPage
.isDefaultLocation();
path[0] = importWithDirectoriesPage.getPath();
repoDir[0] = getTargetRepository().getDirectory();
}
});
try {
IWorkspaceRunnable wsr = new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor actMonitor)
throws CoreException {
final IProjectDescription desc = ResourcesPlugin
.getWorkspace().newProjectDescription(
projectName[0]);
desc.setLocation(new Path(path[0]));
SubMonitor progress = SubMonitor.convert(actMonitor, 4);
IProject prj = ResourcesPlugin.getWorkspace().getRoot()
.getProject(desc.getName());
prj.create(desc, progress.newChild(1));
prj.open(progress.newChild(1));
ConnectProviderOperation cpo = new ConnectProviderOperation(
prj, repoDir[0]);
cpo.execute(progress.newChild(1));
ResourcesPlugin.getWorkspace().getRoot().refreshLocal(
IResource.DEPTH_ONE, progress.newChild(1));
}
};
ResourcesPlugin.getWorkspace().run(wsr, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
break;
}
}
}
static IDialogSettings getImportWizardDialogSettings() {
IDialogSettings settings = Activator.getDefault().getDialogSettings();
IDialogSettings wizardSettings = settings
.getSection(GitImportWizard.GIT_IMPORT_SECTION);
if (wizardSettings == null) {
wizardSettings = settings
.addNewSection(GitImportWizard.GIT_IMPORT_SECTION);
}
return wizardSettings;
}
}