Multi-project connect to Git provider
[egit/imyousuf.git] / org.spearce.egit.core / src / org / spearce / egit / core / op / PushOperationResult.java
blobe3a392d47cb39e5cd319bf36199cfdc65c83979c
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 * See LICENSE for the full license text, also available.
7 *******************************************************************************/
8 package org.spearce.egit.core.op;
10 import java.io.IOException;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.LinkedHashMap;
15 import java.util.Set;
17 import org.spearce.jgit.lib.ObjectId;
18 import org.spearce.jgit.lib.Ref;
19 import org.spearce.jgit.transport.PushResult;
20 import org.spearce.jgit.transport.RemoteRefUpdate;
21 import org.spearce.jgit.transport.URIish;
23 /**
24 * Data class for storing push operation results for each remote repository/URI
25 * being part of push operation.
26 * <p>
27 * One instance of this class is dedicated for result of one push operation:
28 * either to one URI or to many URIs.
30 * @see PushOperation
32 public class PushOperationResult {
33 private LinkedHashMap<URIish, Entry> urisEntries;
35 /**
36 * Construct empty push operation result.
38 PushOperationResult() {
39 this.urisEntries = new LinkedHashMap<URIish, Entry>();
42 /**
43 * Add push result for the repository (URI) with successful connection.
45 * @param uri
46 * remote repository URI.
47 * @param result
48 * push result.
50 public void addOperationResult(final URIish uri, final PushResult result) {
51 urisEntries.put(uri, new Entry(result));
54 /**
55 * Add error message for the repository (URI) with unsuccessful connection.
57 * @param uri
58 * remote repository URI.
59 * @param errorMessage
60 * failure error message.
62 public void addOperationResult(final URIish uri, final String errorMessage) {
63 urisEntries.put(uri, new Entry(errorMessage));
66 /**
67 * @return set of remote repositories URIish. Set is ordered in addition
68 * sequence, which is usually the same as that from
69 * {@link PushOperationSpecification}.
71 public Set<URIish> getURIs() {
72 return Collections.unmodifiableSet(urisEntries.keySet());
75 /**
76 * @param uri
77 * remote repository URI.
78 * @return true if connection was successful for this repository (URI),
79 * false if this operation ended with unsuccessful connection.
81 public boolean isSuccessfulConnection(final URIish uri) {
82 return urisEntries.get(uri).isSuccessfulConnection();
85 /**
86 * @return true if connection was successful for any repository (URI), false
87 * otherwise.
89 public boolean isSuccessfulConnectionForAnyURI() {
90 for (final URIish uri : getURIs()) {
91 if (isSuccessfulConnection(uri))
92 return true;
94 return false;
97 /**
98 * @param uri
99 * remote repository URI.
100 * @return push result for this repository (URI) or null if operation ended
101 * with unsuccessful connection for this URI.
103 public PushResult getPushResult(final URIish uri) {
104 return urisEntries.get(uri).getResult();
108 * @param uri
109 * remote repository URI.
110 * @return error message for this repository (URI) or null if operation
111 * ended with successful connection for this URI.
113 public String getErrorMessage(final URIish uri) {
114 return urisEntries.get(uri).getErrorMessage();
118 * @return string being list of failed URIs with their error messages.
120 public String getErrorStringForAllURis() {
121 final StringBuilder sb = new StringBuilder();
122 boolean first = true;
123 for (final URIish uri : getURIs()) {
124 if (first)
125 first = false;
126 else
127 sb.append(", ");
128 sb.append(uri);
129 sb.append(" (");
130 sb.append(getErrorMessage(uri));
131 sb.append(")");
133 return sb.toString();
137 * Derive push operation specification from this push operation result.
138 * <p>
139 * Specification is created basing on URIs of remote repositories in this
140 * result that completed without connection errors, and remote ref updates
141 * from push results.
142 * <p>
143 * This method is targeted to provide support for 2-stage push, where first
144 * operation is dry run for user confirmation and second one is a real
145 * operation.
147 * @param requireUnchanged
148 * if true, newly created copies of remote ref updates have
149 * expected old object id set to previously advertised ref value
150 * (remote ref won't be updated if it change in the mean time),
151 * if false, newly create copies of remote ref updates have
152 * expected object id set up as in this result source
153 * specification.
154 * @return derived specification for another push operation.
155 * @throws IOException
156 * when some previously locally available source ref is not
157 * available anymore, or some error occurred during creation
158 * locally tracking ref update.
161 public PushOperationSpecification deriveSpecification(
162 final boolean requireUnchanged) throws IOException {
163 final PushOperationSpecification spec = new PushOperationSpecification();
164 for (final URIish uri : getURIs()) {
165 final PushResult pr = getPushResult(uri);
166 if (pr == null)
167 continue;
169 final Collection<RemoteRefUpdate> oldUpdates = pr
170 .getRemoteUpdates();
171 final ArrayList<RemoteRefUpdate> newUpdates = new ArrayList<RemoteRefUpdate>(
172 oldUpdates.size());
173 for (final RemoteRefUpdate rru : oldUpdates) {
174 final ObjectId expectedOldObjectId;
175 if (requireUnchanged) {
176 final Ref advertisedRef = getPushResult(uri)
177 .getAdvertisedRef(rru.getRemoteName());
178 if (advertisedRef == null)
179 expectedOldObjectId = ObjectId.zeroId();
180 else
181 expectedOldObjectId = advertisedRef.getObjectId();
182 } else
183 expectedOldObjectId = rru.getExpectedOldObjectId();
184 final RemoteRefUpdate newRru = new RemoteRefUpdate(rru,
185 expectedOldObjectId);
186 newUpdates.add(newRru);
188 spec.addURIRefUpdates(uri, newUpdates);
190 return spec;
194 * This implementation returns true if all following conditions are met:
195 * <ul>
196 * <li>both objects result have the same set successfully connected
197 * repositories (URIs) - unsuccessful connections are discarded, AND <li>
198 * remote ref updates must match for each successful connection in sense of
199 * equal remoteName, equal status and equal newObjectId value.</li>
200 * </ul>
202 * @see Object#equals(Object)
203 * @param obj
204 * other push operation result to compare to.
205 * @return true if object is equal to this one in terms of conditions
206 * described above, false otherwise.
208 @Override
209 public boolean equals(final Object obj) {
210 if (!(obj instanceof PushOperationResult))
211 return false;
213 final PushOperationResult other = (PushOperationResult) obj;
215 // Check successful connections/URIs two-ways:
216 final Set<URIish> otherURIs = other.getURIs();
217 for (final URIish uri : getURIs()) {
218 if (isSuccessfulConnection(uri)
219 && (!otherURIs.contains(uri) || !other
220 .isSuccessfulConnection(uri)))
221 return false;
223 for (final URIish uri : other.getURIs()) {
224 if (other.isSuccessfulConnection(uri)
225 && (!urisEntries.containsKey(uri) || !isSuccessfulConnection(uri)))
226 return false;
229 for (final URIish uri : getURIs()) {
230 if (!isSuccessfulConnection(uri))
231 continue;
233 final PushResult otherPushResult = other.getPushResult(uri);
234 for (final RemoteRefUpdate rru : getPushResult(uri)
235 .getRemoteUpdates()) {
236 final RemoteRefUpdate otherRru = otherPushResult
237 .getRemoteUpdate(rru.getRemoteName());
238 if (otherRru == null)
239 return false;
240 if (otherRru.getStatus() != rru.getStatus()
241 || otherRru.getNewObjectId() != rru.getNewObjectId())
242 return false;
245 return true;
248 private static class Entry {
249 private String errorMessage;
251 private PushResult result;
253 Entry(final PushResult result) {
254 this.result = result;
257 Entry(final String errorMessage) {
258 this.errorMessage = errorMessage;
261 boolean isSuccessfulConnection() {
262 return result != null;
265 String getErrorMessage() {
266 return errorMessage;
269 PushResult getResult() {
270 return result;