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