Improve error handling in EGit UI
[egit.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / clone / GitCloneWizard.java
bloba01f1ed69dd27c73078f4456b81781d428a1242d
1 /*******************************************************************************
2 * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
5 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
7 * All rights reserved. This program and the accompanying materials
8 * are made available under the terms of the Eclipse Public License v1.0
9 * which accompanies this distribution, and is available at
10 * http://www.eclipse.org/legal/epl-v10.html
11 *******************************************************************************/
12 package org.eclipse.egit.ui.internal.clone;
14 import java.io.File;
15 import java.lang.reflect.InvocationTargetException;
16 import java.util.Collection;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.core.runtime.jobs.Job;
22 import org.eclipse.egit.core.op.CloneOperation;
23 import org.eclipse.egit.ui.Activator;
24 import org.eclipse.egit.ui.UIIcons;
25 import org.eclipse.egit.ui.UIText;
26 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
27 import org.eclipse.egit.ui.internal.repository.RepositoriesView;
28 import org.eclipse.jface.dialogs.ErrorDialog;
29 import org.eclipse.jface.dialogs.MessageDialog;
30 import org.eclipse.jface.operation.IRunnableWithProgress;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.wizard.Wizard;
33 import org.eclipse.jgit.lib.Ref;
34 import org.eclipse.jgit.transport.URIish;
35 import org.eclipse.osgi.util.NLS;
36 import org.eclipse.ui.IImportWizard;
37 import org.eclipse.ui.IViewPart;
38 import org.eclipse.ui.IWorkbench;
39 import org.eclipse.ui.PlatformUI;
41 /**
42 * Import Git Repository Wizard. A front end to a git clone operation.
44 public class GitCloneWizard extends Wizard implements IImportWizard {
45 private RepositorySelectionPage cloneSource;
47 private SourceBranchPage validSource;
49 private CloneDestinationPage cloneDestination;
51 private GitProjectsImportPage importProject;
53 public void init(IWorkbench arg0, IStructuredSelection arg1) {
54 setWindowTitle(UIText.GitCloneWizard_title);
55 setDefaultPageImageDescriptor(UIIcons.WIZBAN_IMPORT_REPO);
56 setNeedsProgressMonitor(true);
57 cloneSource = new RepositorySelectionPage(true, null);
58 validSource = new SourceBranchPage(cloneSource);
59 cloneDestination = new CloneDestinationPage(cloneSource, validSource);
60 importProject = new GitProjectsImportPage() {
61 @Override
62 public void setVisible(boolean visible) {
63 if (visible) {
64 if (cloneDestination.alreadyClonedInto == null) {
65 if (performClone(false))
66 cloneDestination.alreadyClonedInto = cloneDestination
67 .getDestinationFile().getAbsolutePath();
69 setProjectsList(cloneDestination.alreadyClonedInto);
71 super.setVisible(visible);
76 @Override
77 public boolean performCancel() {
78 if (cloneDestination.alreadyClonedInto != null) {
79 if (MessageDialog
80 .openQuestion(getShell(), UIText.GitCloneWizard_abortingCloneTitle,
81 UIText.GitCloneWizard_abortingCloneMsg)) {
82 deleteRecursively(new File(cloneDestination.alreadyClonedInto));
85 return true;
88 private void deleteRecursively(File f) {
89 for (File i : f.listFiles()) {
90 if (i.isDirectory()) {
91 deleteRecursively(i);
92 } else {
93 if (!i.delete()) {
94 i.deleteOnExit();
98 if (!f.delete())
99 f.deleteOnExit();
102 @Override
103 public void addPages() {
104 addPage(cloneSource);
105 addPage(validSource);
106 addPage(cloneDestination);
107 addPage(importProject);
110 @Override
111 public boolean canFinish() {
112 return cloneDestination.isPageComplete()
113 && !cloneDestination.showImportWizard.getSelection()
114 || importProject.isPageComplete();
117 @Override
118 public boolean performFinish() {
119 if (!cloneDestination.showImportWizard.getSelection())
120 return performClone(true);
121 return importProject.createProjects();
124 boolean performClone(boolean background) {
125 final URIish uri = cloneSource.getSelection().getURI();
126 final boolean allSelected = validSource.isAllSelected();
127 final Collection<Ref> selectedBranches = validSource
128 .getSelectedBranches();
129 final File workdir = cloneDestination.getDestinationFile();
130 final String branch = cloneDestination.getInitialBranch();
131 final String remoteName = cloneDestination.getRemote();
133 workdir.mkdirs();
134 if (!workdir.isDirectory()) {
135 final String errorMessage = NLS.bind(
136 UIText.GitCloneWizard_errorCannotCreate, workdir.getPath());
137 ErrorDialog.openError(getShell(), getWindowTitle(),
138 UIText.GitCloneWizard_failed, new Status(IStatus.ERROR,
139 Activator.getPluginId(), 0, errorMessage, null));
140 // let's give user a chance to fix this minor problem
141 return false;
144 final RepositoriesView view;
145 IViewPart vp = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
146 .getActivePage().findView(RepositoriesView.VIEW_ID);
147 if (vp != null) {
148 view = (RepositoriesView) vp;
149 } else {
150 view = null;
153 final CloneOperation op = new CloneOperation(uri, allSelected,
154 selectedBranches, workdir, branch, remoteName);
155 importProject.setGitDir(op.getGitDir());
156 if (background) {
157 final Job job = new Job(NLS.bind(UIText.GitCloneWizard_jobName, uri
158 .toString())) {
159 @Override
160 protected IStatus run(final IProgressMonitor monitor) {
161 try {
162 op.run(monitor);
163 RepositorySelectionPage.saveUriInPrefs(uri.toString());
164 RepositoriesView.addDir(op.getGitDir());
165 if (view != null)
166 view.scheduleRefresh();
168 return Status.OK_STATUS;
169 } catch (InterruptedException e) {
170 return Status.CANCEL_STATUS;
171 } catch (InvocationTargetException e) {
172 Throwable thr = e.getCause();
173 return new Status(IStatus.ERROR, Activator
174 .getPluginId(), 0, thr.getMessage(), thr);
179 job.setUser(true);
180 job.schedule();
181 return true;
182 } else {
183 try {
184 // Perform clone in ModalContext thread with progress
185 // reporting on the wizard.
186 getContainer().run(true, true, new IRunnableWithProgress() {
187 public void run(IProgressMonitor monitor)
188 throws InvocationTargetException,
189 InterruptedException {
190 op.run(monitor);
193 RepositorySelectionPage.saveUriInPrefs(uri.toString());
194 RepositoriesView.addDir(op.getGitDir());
195 if (view != null)
196 view.scheduleRefresh();
197 return true;
198 } catch (InterruptedException e) {
199 MessageDialog.openInformation(getShell(),
200 UIText.GitCloneWizard_CloneFailedHeading,
201 UIText.GitCloneWizard_CloneCanceledMessage);
202 return false;
203 } catch (Exception e) {
204 Activator.handleError(UIText.GitCloneWizard_CloneFailedHeading,
205 e, true);
206 return false;