Egit Push uses wrong URI/RefSpec
[egit/spearce.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / push / ConfirmationPage.java
blob1ff362c9070a5135c0d49d028ad6b06cef8a1bb0
1 /*******************************************************************************
2 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org.eclipse.egit.ui.internal.push;
11 import java.io.IOException;
12 import java.lang.reflect.InvocationTargetException;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.List;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.Status;
20 import org.eclipse.egit.core.op.PushOperation;
21 import org.eclipse.egit.core.op.PushOperationResult;
22 import org.eclipse.egit.core.op.PushOperationSpecification;
23 import org.eclipse.egit.ui.Activator;
24 import org.eclipse.egit.ui.UIText;
25 import org.eclipse.egit.ui.internal.components.RefSpecPage;
26 import org.eclipse.egit.ui.internal.components.RepositorySelection;
27 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
28 import org.eclipse.egit.ui.internal.components.SelectionChangeListener;
29 import org.eclipse.jface.dialogs.ErrorDialog;
30 import org.eclipse.jface.operation.IRunnableWithProgress;
31 import org.eclipse.jface.wizard.WizardPage;
32 import org.eclipse.osgi.util.NLS;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Button;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.jgit.lib.Repository;
40 import org.eclipse.jgit.transport.RefSpec;
41 import org.eclipse.jgit.transport.RemoteRefUpdate;
42 import org.eclipse.jgit.transport.Transport;
43 import org.eclipse.jgit.transport.URIish;
45 class ConfirmationPage extends WizardPage {
46 static Collection<RemoteRefUpdate> copyUpdates(
47 final Collection<RemoteRefUpdate> refUpdates) throws IOException {
48 final Collection<RemoteRefUpdate> copy = new ArrayList<RemoteRefUpdate>(
49 refUpdates.size());
50 for (final RemoteRefUpdate rru : refUpdates)
51 copy.add(new RemoteRefUpdate(rru, null));
52 return copy;
55 private final Repository local;
57 private final RepositorySelectionPage repoPage;
59 private final RefSpecPage refSpecPage;
61 private RepositorySelection displayedRepoSelection;
63 private List<RefSpec> displayedRefSpecs;
65 private PushOperationResult confirmedResult;
67 private PushResultTable resultPanel;
69 private Button requireUnchangedButton;
71 private Button showOnlyIfChanged;
73 public ConfirmationPage(final Repository local,
74 final RepositorySelectionPage repoPage,
75 final RefSpecPage refSpecPage) {
76 super(ConfirmationPage.class.getName());
77 this.local = local;
78 this.repoPage = repoPage;
79 this.refSpecPage = refSpecPage;
81 setTitle(UIText.ConfirmationPage_title);
82 setDescription(UIText.ConfirmationPage_description);
84 final SelectionChangeListener listener = new SelectionChangeListener() {
85 public void selectionChanged() {
86 checkPreviousPagesSelections();
89 repoPage.addSelectionListener(listener);
90 refSpecPage.addSelectionListener(listener);
93 public void createControl(final Composite parent) {
94 final Composite panel = new Composite(parent, SWT.NONE);
95 panel.setLayout(new GridLayout());
97 resultPanel = new PushResultTable(panel);
98 final Control tableControl = resultPanel.getControl();
99 tableControl
100 .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
102 requireUnchangedButton = new Button(panel, SWT.CHECK);
103 requireUnchangedButton
104 .setText(UIText.ConfirmationPage_requireUnchangedButton);
106 showOnlyIfChanged = new Button(panel, SWT.CHECK);
107 showOnlyIfChanged.setText(UIText.ConfirmationPage_showOnlyIfChanged);
109 setControl(panel);
112 @Override
113 public void setVisible(final boolean visible) {
114 if (visible)
115 revalidate();
116 super.setVisible(visible);
119 boolean isConfirmed() {
120 return confirmedResult != null;
123 PushOperationResult getConfirmedResult() {
124 return confirmedResult;
127 boolean isRequireUnchangedSelected() {
128 return requireUnchangedButton.getSelection();
131 boolean isShowOnlyIfChangedSelected() {
132 return showOnlyIfChanged.getSelection();
135 private void checkPreviousPagesSelections() {
136 if (!repoPage.selectionEquals(displayedRepoSelection)
137 || !refSpecPage.specsSelectionEquals(displayedRefSpecs)) {
138 // Allow user to finish by skipping confirmation...
139 setPageComplete(true);
140 } else {
141 // ... but if user doesn't skip confirmation, allow only when no
142 // critical errors occurred
143 setPageComplete(confirmedResult != null);
147 private void revalidate() {
148 // always update this page
149 resultPanel.setData(local, null);
150 confirmedResult = null;
151 displayedRepoSelection = repoPage.getSelection();
152 displayedRefSpecs = refSpecPage.getRefSpecs();
153 setErrorMessage(null);
154 setPageComplete(false);
155 getControl().getDisplay().asyncExec(new Runnable() {
156 public void run() {
157 revalidateImpl();
162 private void revalidateImpl() {
163 if (getControl().isDisposed() || !isCurrentPage())
164 return;
166 final List<RefSpec> fetchSpecs;
167 if (displayedRepoSelection.isConfigSelected())
168 fetchSpecs = displayedRepoSelection.getConfig().getPushRefSpecs();
169 else
170 fetchSpecs = null;
172 final PushOperation operation;
173 try {
174 final Collection<RemoteRefUpdate> updates = Transport
175 .findRemoteRefUpdatesFor(local, displayedRefSpecs,
176 fetchSpecs);
177 if (updates.isEmpty()) {
178 // It can happen only when local refs changed in the mean time.
179 setErrorMessage(UIText.ConfirmationPage_errorRefsChangedNoMatch);
180 setPageComplete(false);
181 return;
184 final PushOperationSpecification spec = new PushOperationSpecification();
185 for (final URIish uri : displayedRepoSelection.getPushURIs())
186 spec.addURIRefUpdates(uri, copyUpdates(updates));
188 operation = new PushOperation(local, spec, true,
189 displayedRepoSelection.getConfig());
190 getContainer().run(true, true, new IRunnableWithProgress() {
191 public void run(IProgressMonitor monitor)
192 throws InvocationTargetException, InterruptedException {
193 operation.run(monitor);
196 } catch (final IOException e) {
197 setErrorMessage(NLS.bind(
198 UIText.ConfirmationPage_errorCantResolveSpecs, e
199 .getMessage()));
200 return;
201 } catch (final InvocationTargetException e) {
202 setErrorMessage(NLS.bind(UIText.ConfirmationPage_errorUnexpected, e
203 .getCause().getMessage()));
204 return;
205 } catch (final InterruptedException e) {
206 setErrorMessage(UIText.ConfirmationPage_errorInterrupted);
207 setPageComplete(true);
208 displayedRefSpecs = null;
209 displayedRepoSelection = null;
210 return;
213 final PushOperationResult result = operation.getOperationResult();
214 resultPanel.setData(local, result);
215 if (result.isSuccessfulConnectionForAnyURI()) {
216 setPageComplete(true);
217 confirmedResult = result;
218 } else {
219 final String message = NLS.bind(
220 UIText.ConfirmationPage_cantConnectToAny, result
221 .getErrorStringForAllURis());
222 setErrorMessage(message);
223 ErrorDialog
224 .openError(getShell(),
225 UIText.ConfirmationPage_cantConnectToAnyTitle,
226 null,
227 new Status(IStatus.ERROR, Activator.getPluginId(),
228 message));