Mercurial > jhg
comparison src/org/tmatesoft/hg/core/HgCloneCommand.java @ 423:9c9c442b5f2e
Major refactoring of exception handling. Low-level API uses RuntimeExceptions, while checked are left for higher level
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 23 Mar 2012 22:51:18 +0100 |
parents | 528b6780a8bd |
children | 12f668401613 |
comparison
equal
deleted
inserted
replaced
422:5d1cc7366d04 | 423:9c9c442b5f2e |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011 TMate Software Ltd | 2 * Copyright (c) 2011-2012 TMate Software Ltd |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or modify | 4 * This program is free software; you can redistribute it and/or modify |
5 * it under the terms of the GNU General Public License as published by | 5 * it under the terms of the GNU General Public License as published by |
6 * the Free Software Foundation; version 2 of the License. | 6 * the Free Software Foundation; version 2 of the License. |
7 * | 7 * |
35 import org.tmatesoft.hg.internal.DataAccess; | 35 import org.tmatesoft.hg.internal.DataAccess; |
36 import org.tmatesoft.hg.internal.DigestHelper; | 36 import org.tmatesoft.hg.internal.DigestHelper; |
37 import org.tmatesoft.hg.internal.Internals; | 37 import org.tmatesoft.hg.internal.Internals; |
38 import org.tmatesoft.hg.repo.HgBundle; | 38 import org.tmatesoft.hg.repo.HgBundle; |
39 import org.tmatesoft.hg.repo.HgBundle.GroupElement; | 39 import org.tmatesoft.hg.repo.HgBundle.GroupElement; |
40 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | |
41 import org.tmatesoft.hg.repo.HgInvalidFileException; | |
42 import org.tmatesoft.hg.repo.HgInvalidStateException; | |
40 import org.tmatesoft.hg.repo.HgLookup; | 43 import org.tmatesoft.hg.repo.HgLookup; |
41 import org.tmatesoft.hg.repo.HgRemoteRepository; | 44 import org.tmatesoft.hg.repo.HgRemoteRepository; |
42 import org.tmatesoft.hg.repo.HgRepository; | 45 import org.tmatesoft.hg.repo.HgRepository; |
46 import org.tmatesoft.hg.repo.HgRuntimeException; | |
43 import org.tmatesoft.hg.util.CancelledException; | 47 import org.tmatesoft.hg.util.CancelledException; |
44 import org.tmatesoft.hg.util.PathRewrite; | 48 import org.tmatesoft.hg.util.PathRewrite; |
45 | 49 |
46 /** | 50 /** |
47 * WORK IN PROGRESS, DO NOT USE | 51 * WORK IN PROGRESS, DO NOT USE |
48 * | 52 * |
49 * @author Artem Tikhomirov | 53 * @author Artem Tikhomirov |
50 * @author TMate Software Ltd. | 54 * @author TMate Software Ltd. |
51 */ | 55 */ |
52 public class HgCloneCommand { | 56 public class HgCloneCommand extends HgAbstractCommand<HgCloneCommand> { |
53 | 57 |
54 private File destination; | 58 private File destination; |
55 private HgRemoteRepository srcRepo; | 59 private HgRemoteRepository srcRepo; |
56 | 60 |
57 public HgCloneCommand() { | 61 public HgCloneCommand() { |
70 public HgCloneCommand source(HgRemoteRepository hgRemote) { | 74 public HgCloneCommand source(HgRemoteRepository hgRemote) { |
71 srcRepo = hgRemote; | 75 srcRepo = hgRemote; |
72 return this; | 76 return this; |
73 } | 77 } |
74 | 78 |
75 public HgRepository execute() throws HgBadArgumentException, HgRemoteConnectionException, HgInvalidFileException, CancelledException { | 79 /** |
80 * | |
81 * @return | |
82 * @throws HgBadArgumentException | |
83 * @throws HgRemoteConnectionException | |
84 * @throws HgRepositoryNotFoundException | |
85 * @throws HgException | |
86 * @throws CancelledException | |
87 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | |
88 */ | |
89 public HgRepository execute() throws HgException, CancelledException { | |
76 if (destination == null) { | 90 if (destination == null) { |
77 throw new IllegalArgumentException("Destination not set", null); | 91 throw new IllegalArgumentException("Destination not set", null); |
78 } | 92 } |
79 if (srcRepo == null || srcRepo.isInvalid()) { | 93 if (srcRepo == null || srcRepo.isInvalid()) { |
80 throw new HgBadArgumentException("Bad source repository", null); | 94 throw new HgBadArgumentException("Bad source repository", null); |
157 offset = 0; | 171 offset = 0; |
158 revisionSequence.clear(); | 172 revisionSequence.clear(); |
159 indexFile = new FileOutputStream(new File(hgDir, filename = "store/00changelog.i")); | 173 indexFile = new FileOutputStream(new File(hgDir, filename = "store/00changelog.i")); |
160 collectChangelogIndexes = true; | 174 collectChangelogIndexes = true; |
161 } catch (IOException ex) { | 175 } catch (IOException ex) { |
162 throw new HgBadStateException(ex); | 176 throw new HgInvalidControlFileException("Failed to write changelog", ex, new File(filename)); |
163 } | 177 } |
164 } | 178 } |
165 | 179 |
166 public void changelogEnd() { | 180 public void changelogEnd() { |
167 try { | 181 try { |
172 collectChangelogIndexes = false; | 186 collectChangelogIndexes = false; |
173 indexFile.close(); | 187 indexFile.close(); |
174 indexFile = null; | 188 indexFile = null; |
175 filename = null; | 189 filename = null; |
176 } catch (IOException ex) { | 190 } catch (IOException ex) { |
177 throw new HgBadStateException(ex); | 191 throw new HgInvalidControlFileException("Failed to write changelog", ex, new File(filename)); |
178 } | 192 } |
179 } | 193 } |
180 | 194 |
181 public void manifestStart() { | 195 public void manifestStart() { |
182 try { | 196 try { |
183 base = -1; | 197 base = -1; |
184 offset = 0; | 198 offset = 0; |
185 revisionSequence.clear(); | 199 revisionSequence.clear(); |
186 indexFile = new FileOutputStream(new File(hgDir, filename = "store/00manifest.i")); | 200 indexFile = new FileOutputStream(new File(hgDir, filename = "store/00manifest.i")); |
187 } catch (IOException ex) { | 201 } catch (IOException ex) { |
188 throw new HgBadStateException(ex); | 202 throw new HgInvalidControlFileException("Failed to write manifest", ex, new File(filename)); |
189 } | 203 } |
190 } | 204 } |
191 | 205 |
192 public void manifestEnd() { | 206 public void manifestEnd() { |
193 try { | 207 try { |
197 } | 211 } |
198 indexFile.close(); | 212 indexFile.close(); |
199 indexFile = null; | 213 indexFile = null; |
200 filename = null; | 214 filename = null; |
201 } catch (IOException ex) { | 215 } catch (IOException ex) { |
202 throw new HgBadStateException(ex); | 216 throw new HgInvalidControlFileException("Failed to write changelog", ex, new File(filename)); |
203 } | 217 } |
204 } | 218 } |
205 | 219 |
206 public void fileStart(String name) { | 220 public void fileStart(String name) { |
207 try { | 221 try { |
212 // need to investigate more how filenames are kept in fncache | 226 // need to investigate more how filenames are kept in fncache |
213 File file = new File(hgDir, filename = storagePathHelper.rewrite(name).toString()); | 227 File file = new File(hgDir, filename = storagePathHelper.rewrite(name).toString()); |
214 file.getParentFile().mkdirs(); | 228 file.getParentFile().mkdirs(); |
215 indexFile = new FileOutputStream(file); | 229 indexFile = new FileOutputStream(file); |
216 } catch (IOException ex) { | 230 } catch (IOException ex) { |
217 throw new HgBadStateException(ex); | 231 String m = String.format("Failed to write file %s", filename); |
232 throw new HgInvalidControlFileException(m, ex, new File(filename)); | |
218 } | 233 } |
219 } | 234 } |
220 | 235 |
221 public void fileEnd(String name) { | 236 public void fileEnd(String name) { |
222 try { | 237 try { |
226 } | 241 } |
227 indexFile.close(); | 242 indexFile.close(); |
228 indexFile = null; | 243 indexFile = null; |
229 filename = null; | 244 filename = null; |
230 } catch (IOException ex) { | 245 } catch (IOException ex) { |
231 throw new HgBadStateException(ex); | 246 String m = String.format("Failed to write file %s", filename); |
247 throw new HgInvalidControlFileException(m, ex, new File(filename)); | |
232 } | 248 } |
233 } | 249 } |
234 | 250 |
235 private int knownRevision(Nodeid p) { | 251 private int knownRevision(Nodeid p) { |
236 if (p.isNull()) { | 252 if (p.isNull()) { |
240 if (revisionSequence.get(i).equals(p)) { | 256 if (revisionSequence.get(i).equals(p)) { |
241 return i; | 257 return i; |
242 } | 258 } |
243 } | 259 } |
244 } | 260 } |
245 throw new HgBadStateException(String.format("Can't find index of %s for file %s", p.shortNotation(), filename)); | 261 String m = String.format("Can't find index of %s for file %s", p.shortNotation(), filename); |
262 throw new HgInvalidControlFileException(m, null, null).setRevision(p); | |
246 } | 263 } |
247 | 264 |
248 public boolean element(GroupElement ge) { | 265 public boolean element(GroupElement ge) { |
249 try { | 266 try { |
250 assert indexFile != null; | 267 assert indexFile != null; |
257 } | 274 } |
258 byte[] content = ge.apply(prevRevContent.byteArray()); | 275 byte[] content = ge.apply(prevRevContent.byteArray()); |
259 byte[] calculated = dh.sha1(p1, p2, content).asBinary(); | 276 byte[] calculated = dh.sha1(p1, p2, content).asBinary(); |
260 final Nodeid node = ge.node(); | 277 final Nodeid node = ge.node(); |
261 if (!node.equalsTo(calculated)) { | 278 if (!node.equalsTo(calculated)) { |
262 throw new HgBadStateException(String.format("Checksum failed: expected %s, calculated %s. File %s", node, calculated, filename)); | 279 // TODO post-1.0 custom exception ChecksumCalculationFailed? |
280 throw new HgInvalidStateException(String.format("Checksum failed: expected %s, calculated %s. File %s", node, calculated, filename)); | |
263 } | 281 } |
264 final int link; | 282 final int link; |
265 if (collectChangelogIndexes) { | 283 if (collectChangelogIndexes) { |
266 changelogIndexes.put(node, revisionSequence.size()); | 284 changelogIndexes.put(node, revisionSequence.size()); |
267 link = revisionSequence.size(); | 285 link = revisionSequence.size(); |
268 } else { | 286 } else { |
269 Integer csRev = changelogIndexes.get(ge.cset()); | 287 Integer csRev = changelogIndexes.get(ge.cset()); |
270 if (csRev == null) { | 288 if (csRev == null) { |
271 throw new HgBadStateException(String.format("Changelog doesn't contain revision %s of %s", ge.cset().shortNotation(), filename)); | 289 throw new HgInvalidStateException(String.format("Changelog doesn't contain revision %s of %s", ge.cset().shortNotation(), filename)); |
272 } | 290 } |
273 link = csRev.intValue(); | 291 link = csRev.intValue(); |
274 } | 292 } |
275 final int p1Rev = knownRevision(p1), p2Rev = knownRevision(p2); | 293 final int p1Rev = knownRevision(p1), p2Rev = knownRevision(p2); |
276 byte[] patchContent = ge.rawDataByteArray(); | 294 byte[] patchContent = ge.rawDataByteArray(); |
323 offset += compressedLen; | 341 offset += compressedLen; |
324 revisionSequence.add(node); | 342 revisionSequence.add(node); |
325 prevRevContent.done(); | 343 prevRevContent.done(); |
326 prevRevContent = new ByteArrayDataAccess(content); | 344 prevRevContent = new ByteArrayDataAccess(content); |
327 } catch (IOException ex) { | 345 } catch (IOException ex) { |
328 throw new HgBadStateException(ex); | 346 String m = String.format("Failed to write revision %s of file %s", ge.node().shortNotation(), filename); |
347 throw new HgInvalidControlFileException(m, ex, new File(filename)); | |
329 } | 348 } |
330 return true; | 349 return true; |
331 } | 350 } |
332 } | 351 } |
333 | 352 |