Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgRemoteRepository.java @ 215:41a778e3fd31
Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 17 May 2011 00:56:54 +0200 |
parents | 6a2481866491 |
children | 9fb50c04f03c |
comparison
equal
deleted
inserted
replaced
214:4252faa556cd | 215:41a778e3fd31 |
---|---|
46 import javax.net.ssl.TrustManager; | 46 import javax.net.ssl.TrustManager; |
47 import javax.net.ssl.X509TrustManager; | 47 import javax.net.ssl.X509TrustManager; |
48 | 48 |
49 import org.tmatesoft.hg.core.HgBadArgumentException; | 49 import org.tmatesoft.hg.core.HgBadArgumentException; |
50 import org.tmatesoft.hg.core.HgBadStateException; | 50 import org.tmatesoft.hg.core.HgBadStateException; |
51 import org.tmatesoft.hg.core.HgException; | 51 import org.tmatesoft.hg.core.HgRemoteConnectionException; |
52 import org.tmatesoft.hg.core.Nodeid; | 52 import org.tmatesoft.hg.core.Nodeid; |
53 | 53 |
54 /** | 54 /** |
55 * WORK IN PROGRESS, DO NOT USE | 55 * WORK IN PROGRESS, DO NOT USE |
56 * | 56 * |
113 } else { | 113 } else { |
114 authInfo = null; | 114 authInfo = null; |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
118 public boolean isInvalid() throws HgException { | 118 public boolean isInvalid() throws HgRemoteConnectionException { |
119 // say hello to server, check response | 119 // say hello to server, check response |
120 if (Boolean.FALSE.booleanValue()) { | 120 if (Boolean.FALSE.booleanValue()) { |
121 throw HgRepository.notImplemented(); | 121 throw HgRepository.notImplemented(); |
122 } | 122 } |
123 return false; // FIXME | 123 return false; // FIXME |
135 } else { | 135 } else { |
136 return String.format("%s://%s%s", url.getProtocol(), url.getHost(), url.getPath()); | 136 return String.format("%s://%s%s", url.getProtocol(), url.getHost(), url.getPath()); |
137 } | 137 } |
138 } | 138 } |
139 | 139 |
140 public List<Nodeid> heads() throws HgException { | 140 public List<Nodeid> heads() throws HgRemoteConnectionException { |
141 try { | 141 try { |
142 URL u = new URL(url, url.getPath() + "?cmd=heads"); | 142 URL u = new URL(url, url.getPath() + "?cmd=heads"); |
143 HttpURLConnection c = setupConnection(u.openConnection()); | 143 HttpURLConnection c = setupConnection(u.openConnection()); |
144 c.connect(); | 144 c.connect(); |
145 if (debug) { | 145 if (debug) { |
154 while (st.nextToken() != StreamTokenizer.TT_EOF) { | 154 while (st.nextToken() != StreamTokenizer.TT_EOF) { |
155 parseResult.add(Nodeid.fromAscii(st.sval)); | 155 parseResult.add(Nodeid.fromAscii(st.sval)); |
156 } | 156 } |
157 return parseResult; | 157 return parseResult; |
158 } catch (MalformedURLException ex) { | 158 } catch (MalformedURLException ex) { |
159 throw new HgException(ex); | 159 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("heads").setServerInfo(getLocation()); |
160 } catch (IOException ex) { | 160 } catch (IOException ex) { |
161 throw new HgException(ex); | 161 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("heads").setServerInfo(getLocation()); |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 public List<Nodeid> between(Nodeid tip, Nodeid base) throws HgException { | 165 public List<Nodeid> between(Nodeid tip, Nodeid base) throws HgRemoteConnectionException { |
166 Range r = new Range(base, tip); | 166 Range r = new Range(base, tip); |
167 // XXX shall handle errors like no range key in the returned map, not sure how. | 167 // XXX shall handle errors like no range key in the returned map, not sure how. |
168 return between(Collections.singletonList(r)).get(r); | 168 return between(Collections.singletonList(r)).get(r); |
169 } | 169 } |
170 | 170 |
171 /** | 171 /** |
172 * @param ranges | 172 * @param ranges |
173 * @return map, where keys are input instances, values are corresponding server reply | 173 * @return map, where keys are input instances, values are corresponding server reply |
174 * @throws HgException | 174 * @throws HgRemoteConnectionException |
175 */ | 175 */ |
176 public Map<Range, List<Nodeid>> between(Collection<Range> ranges) throws HgException { | 176 public Map<Range, List<Nodeid>> between(Collection<Range> ranges) throws HgRemoteConnectionException { |
177 if (ranges.isEmpty()) { | 177 if (ranges.isEmpty()) { |
178 return Collections.emptyMap(); | 178 return Collections.emptyMap(); |
179 } | 179 } |
180 // if fact, shall do other way round, this method shall send | 180 // if fact, shall do other way round, this method shall send |
181 LinkedHashMap<Range, List<Nodeid>> rv = new LinkedHashMap<HgRemoteRepository.Range, List<Nodeid>>(ranges.size() * 4 / 3); | 181 LinkedHashMap<Range, List<Nodeid>> rv = new LinkedHashMap<HgRemoteRepository.Range, List<Nodeid>>(ranges.size() * 4 / 3); |
255 } | 255 } |
256 } | 256 } |
257 is.close(); | 257 is.close(); |
258 return rv; | 258 return rv; |
259 } catch (MalformedURLException ex) { | 259 } catch (MalformedURLException ex) { |
260 throw new HgException(ex); | 260 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("between").setServerInfo(getLocation()); |
261 } catch (IOException ex) { | 261 } catch (IOException ex) { |
262 throw new HgException(ex); | 262 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("between").setServerInfo(getLocation()); |
263 } | 263 } |
264 } | 264 } |
265 | 265 |
266 public List<RemoteBranch> branches(List<Nodeid> nodes) throws HgException { | 266 public List<RemoteBranch> branches(List<Nodeid> nodes) throws HgRemoteConnectionException { |
267 StringBuilder sb = new StringBuilder(20 + nodes.size() * 41); | 267 StringBuilder sb = new StringBuilder(20 + nodes.size() * 41); |
268 sb.append("nodes="); | 268 sb.append("nodes="); |
269 for (Nodeid n : nodes) { | 269 for (Nodeid n : nodes) { |
270 sb.append(n.toString()); | 270 sb.append(n.toString()); |
271 sb.append('+'); | 271 sb.append('+'); |
289 ArrayList<Nodeid> parseResult = new ArrayList<Nodeid>(nodes.size() * 4); | 289 ArrayList<Nodeid> parseResult = new ArrayList<Nodeid>(nodes.size() * 4); |
290 while (st.nextToken() != StreamTokenizer.TT_EOF) { | 290 while (st.nextToken() != StreamTokenizer.TT_EOF) { |
291 parseResult.add(Nodeid.fromAscii(st.sval)); | 291 parseResult.add(Nodeid.fromAscii(st.sval)); |
292 } | 292 } |
293 if (parseResult.size() != nodes.size() * 4) { | 293 if (parseResult.size() != nodes.size() * 4) { |
294 throw new HgException(String.format("Bad number of nodeids in result (shall be factor 4), expected %d, got %d", nodes.size()*4, parseResult.size())); | 294 throw new HgRemoteConnectionException(String.format("Bad number of nodeids in result (shall be factor 4), expected %d, got %d", nodes.size()*4, parseResult.size())); |
295 } | 295 } |
296 ArrayList<RemoteBranch> rv = new ArrayList<RemoteBranch>(nodes.size()); | 296 ArrayList<RemoteBranch> rv = new ArrayList<RemoteBranch>(nodes.size()); |
297 for (int i = 0; i < nodes.size(); i++) { | 297 for (int i = 0; i < nodes.size(); i++) { |
298 RemoteBranch rb = new RemoteBranch(parseResult.get(i*4), parseResult.get(i*4 + 1), parseResult.get(i*4 + 2), parseResult.get(i*4 + 3)); | 298 RemoteBranch rb = new RemoteBranch(parseResult.get(i*4), parseResult.get(i*4 + 1), parseResult.get(i*4 + 2), parseResult.get(i*4 + 3)); |
299 rv.add(rb); | 299 rv.add(rb); |
300 } | 300 } |
301 return rv; | 301 return rv; |
302 } catch (MalformedURLException ex) { | 302 } catch (MalformedURLException ex) { |
303 throw new HgException(ex); | 303 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("branches").setServerInfo(getLocation()); |
304 } catch (IOException ex) { | 304 } catch (IOException ex) { |
305 throw new HgException(ex); | 305 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("branches").setServerInfo(getLocation()); |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 /* | 309 /* |
310 * XXX need to describe behavior when roots arg is empty; our RepositoryComparator code currently returns empty lists when | 310 * XXX need to describe behavior when roots arg is empty; our RepositoryComparator code currently returns empty lists when |
320 * | 320 * |
321 * according to latter, bundleformat data is sent through zlib | 321 * according to latter, bundleformat data is sent through zlib |
322 * (there's no header like HG10?? with the server output, though, | 322 * (there's no header like HG10?? with the server output, though, |
323 * as one may expect according to http://mercurial.selenic.com/wiki/BundleFormat) | 323 * as one may expect according to http://mercurial.selenic.com/wiki/BundleFormat) |
324 */ | 324 */ |
325 public HgBundle getChanges(List<Nodeid> roots) throws HgException { | 325 public HgBundle getChanges(List<Nodeid> roots) throws HgRemoteConnectionException { |
326 List<Nodeid> _roots = roots.isEmpty() ? Collections.singletonList(Nodeid.NULL) : roots; | 326 List<Nodeid> _roots = roots.isEmpty() ? Collections.singletonList(Nodeid.NULL) : roots; |
327 StringBuilder sb = new StringBuilder(20 + _roots.size() * 41); | 327 StringBuilder sb = new StringBuilder(20 + _roots.size() * 41); |
328 sb.append("roots="); | 328 sb.append("roots="); |
329 for (Nodeid n : _roots) { | 329 for (Nodeid n : _roots) { |
330 sb.append(n.toString()); | 330 sb.append(n.toString()); |
344 File tf = writeBundle(c.getInputStream(), false, "HG10GZ" /*didn't see any other that zip*/); | 344 File tf = writeBundle(c.getInputStream(), false, "HG10GZ" /*didn't see any other that zip*/); |
345 if (debug) { | 345 if (debug) { |
346 System.out.printf("Wrote bundle %s for roots %s\n", tf, sb); | 346 System.out.printf("Wrote bundle %s for roots %s\n", tf, sb); |
347 } | 347 } |
348 return getLookupHelper().loadBundle(tf); | 348 return getLookupHelper().loadBundle(tf); |
349 } catch (MalformedURLException ex) { | 349 } catch (MalformedURLException ex) { // XXX in fact, this exception might be better to be re-thrown as RuntimeEx, |
350 throw new HgException(ex); | 350 // as there's little user can do about this issue (URLs are constructed by our code) |
351 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("changegroup").setServerInfo(getLocation()); | |
351 } catch (IOException ex) { | 352 } catch (IOException ex) { |
352 throw new HgException(ex); | 353 throw new HgRemoteConnectionException("Communication failure", ex).setRemoteCommand("changegroup").setServerInfo(getLocation()); |
353 } | 354 } |
354 } | 355 } |
355 | 356 |
356 @Override | 357 @Override |
357 public String toString() { | 358 public String toString() { |