comparison src/org/tmatesoft/hg/repo/HgBundle.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 31a89587eb04
comparison
equal deleted inserted replaced
422:5d1cc7366d04 423:9c9c442b5f2e
17 package org.tmatesoft.hg.repo; 17 package org.tmatesoft.hg.repo;
18 18
19 import java.io.File; 19 import java.io.File;
20 import java.io.IOException; 20 import java.io.IOException;
21 21
22 import org.tmatesoft.hg.core.HgBadStateException; 22 import org.tmatesoft.hg.core.HgBadArgumentException;
23 import org.tmatesoft.hg.core.HgCallbackTargetException;
24 import org.tmatesoft.hg.core.HgInvalidFileException;
25 import org.tmatesoft.hg.core.Nodeid; 23 import org.tmatesoft.hg.core.Nodeid;
26 import org.tmatesoft.hg.core.SessionContext; 24 import org.tmatesoft.hg.core.SessionContext;
27 import org.tmatesoft.hg.internal.ByteArrayChannel; 25 import org.tmatesoft.hg.internal.ByteArrayChannel;
28 import org.tmatesoft.hg.internal.ByteArrayDataAccess; 26 import org.tmatesoft.hg.internal.ByteArrayDataAccess;
29 import org.tmatesoft.hg.internal.DataAccess; 27 import org.tmatesoft.hg.internal.DataAccess;
34 import org.tmatesoft.hg.internal.Patch; 32 import org.tmatesoft.hg.internal.Patch;
35 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; 33 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
36 import org.tmatesoft.hg.util.CancelledException; 34 import org.tmatesoft.hg.util.CancelledException;
37 35
38 /** 36 /**
37 * WORK IN PROGRESS
38 *
39 * @see http://mercurial.selenic.com/wiki/BundleFormat 39 * @see http://mercurial.selenic.com/wiki/BundleFormat
40 * 40 *
41 * @author Artem Tikhomirov 41 * @author Artem Tikhomirov
42 * @author TMate Software Ltd. 42 * @author TMate Software Ltd.
43 */ 43 */
64 } 64 }
65 if (signature[4] == 'B' && signature[5] == 'Z') { 65 if (signature[4] == 'B' && signature[5] == 'Z') {
66 throw HgRepository.notImplemented(); 66 throw HgRepository.notImplemented();
67 } 67 }
68 if (signature[4] != 'U' || signature[5] != 'N') { 68 if (signature[4] != 'U' || signature[5] != 'N') {
69 throw new HgBadStateException("Bad bundle signature:" + new String(signature)); 69 throw new HgInvalidStateException(String.format("Bad bundle signature: %s", String.valueOf(signature)));
70 } 70 }
71 // "...UN", fall-through 71 // "...UN", fall-through
72 } else { 72 } else {
73 da.reset(); 73 da.reset();
74 } 74 }
94 /** 94 /**
95 * Get changes recorded in the bundle that are missing from the supplied repository. 95 * Get changes recorded in the bundle that are missing from the supplied repository.
96 * @param hgRepo repository that shall possess base revision for this bundle 96 * @param hgRepo repository that shall possess base revision for this bundle
97 * @param inspector callback to get each changeset found 97 * @param inspector callback to get each changeset found
98 */ 98 */
99 public void changes(final HgRepository hgRepo, final HgChangelog.Inspector inspector) throws HgCallbackTargetException, HgInvalidFileException { 99 public void changes(final HgRepository hgRepo, final HgChangelog.Inspector inspector) throws HgRuntimeException {
100 Inspector bundleInsp = new Inspector() { 100 Inspector bundleInsp = new Inspector() {
101 DigestHelper dh = new DigestHelper(); 101 DigestHelper dh = new DigestHelper();
102 boolean emptyChangelog = true; 102 boolean emptyChangelog = true;
103 private DataAccess prevRevContent; 103 private DataAccess prevRevContent;
104 private int revisionIndex; 104 private int revisionIndex;
157 } 157 }
158 // 158 //
159 byte[] csetContent = ge.apply(prevRevContent); 159 byte[] csetContent = ge.apply(prevRevContent);
160 dh = dh.sha1(ge.firstParent(), ge.secondParent(), csetContent); // XXX ge may give me access to byte[] content of nodeid directly, perhaps, I don't need DH to be friend of Nodeid? 160 dh = dh.sha1(ge.firstParent(), ge.secondParent(), csetContent); // XXX ge may give me access to byte[] content of nodeid directly, perhaps, I don't need DH to be friend of Nodeid?
161 if (!ge.node().equalsTo(dh.asBinary())) { 161 if (!ge.node().equalsTo(dh.asBinary())) {
162 throw new IllegalStateException("Integrity check failed on " + bundleFile + ", node:" + ge.node()); 162 throw new HgInvalidStateException(String.format("Integrity check failed on %s, node: %s", bundleFile, ge.node().shortNotation()));
163 } 163 }
164 ByteArrayDataAccess csetDataAccess = new ByteArrayDataAccess(csetContent); 164 ByteArrayDataAccess csetDataAccess = new ByteArrayDataAccess(csetContent);
165 RawChangeset cs = RawChangeset.parse(csetDataAccess); 165 RawChangeset cs = RawChangeset.parse(csetDataAccess);
166 inspector.next(revisionIndex++, ge.node(), cs); 166 inspector.next(revisionIndex++, ge.node(), cs);
167 prevRevContent.done(); 167 prevRevContent.done();
168 prevRevContent = csetDataAccess.reset(); 168 prevRevContent = csetDataAccess.reset();
169 } catch (CancelledException ex) { 169 } catch (CancelledException ex) {
170 return false; 170 return false;
171 } catch (Exception ex) { 171 } catch (IOException ex) {
172 throw new HgBadStateException(ex); // FIXME EXCEPTIONS 172 throw new HgInvalidFileException("Invalid bundle file", ex, bundleFile); // TODO post-1.0 revisit exception handling
173 } catch (HgBadArgumentException ex) {
174 throw new HgInvalidControlFileException("Invalid bundle file", ex, bundleFile);
173 } 175 }
174 return true; 176 return true;
175 } 177 }
176 178
177 public void manifestStart() {} 179 public void manifestStart() {}
178 public void manifestEnd() {} 180 public void manifestEnd() {}
179 public void fileStart(String name) {} 181 public void fileStart(String name) {}
180 public void fileEnd(String name) {} 182 public void fileEnd(String name) {}
181 183
182 }; 184 };
183 try { 185 inspectChangelog(bundleInsp);
184 inspectChangelog(bundleInsp);
185 } catch (RuntimeException ex) {
186 throw new HgCallbackTargetException(ex);
187 }
188 } 186 }
189 187
190 // callback to minimize amount of Strings and Nodeids instantiated 188 // callback to minimize amount of Strings and Nodeids instantiated
191 public interface Inspector { 189 public interface Inspector {
192 void changelogStart(); 190 void changelogStart();
207 * @return <code>true</code> to continue 205 * @return <code>true</code> to continue
208 */ 206 */
209 boolean element(GroupElement element); 207 boolean element(GroupElement element);
210 } 208 }
211 209
212 public void inspectChangelog(Inspector inspector) throws HgInvalidFileException { 210 /**
211 * @param inspector callback to visit changelog entries
212 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
213 * @throws IllegalArgumentException if inspector argument is null
214 */
215 public void inspectChangelog(Inspector inspector) throws HgRuntimeException {
213 if (inspector == null) { 216 if (inspector == null) {
214 throw new IllegalArgumentException(); 217 throw new IllegalArgumentException();
215 } 218 }
216 DataAccess da = null; 219 DataAccess da = null;
217 try { 220 try {
224 da.done(); 227 da.done();
225 } 228 }
226 } 229 }
227 } 230 }
228 231
229 public void inspectManifest(Inspector inspector) throws HgInvalidFileException { 232 /**
233 * @param inspector callback to visit manifest entries
234 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
235 * @throws IllegalArgumentException if inspector argument is null
236 */
237 public void inspectManifest(Inspector inspector) throws HgRuntimeException {
230 if (inspector == null) { 238 if (inspector == null) {
231 throw new IllegalArgumentException(); 239 throw new IllegalArgumentException();
232 } 240 }
233 DataAccess da = null; 241 DataAccess da = null;
234 try { 242 try {
245 da.done(); 253 da.done();
246 } 254 }
247 } 255 }
248 } 256 }
249 257
250 public void inspectFiles(Inspector inspector) throws HgInvalidFileException { 258 /**
259 * @param inspector callback to visit file entries
260 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
261 * @throws IllegalArgumentException if inspector argument is null
262 */
263 public void inspectFiles(Inspector inspector) throws HgRuntimeException {
251 if (inspector == null) { 264 if (inspector == null) {
252 throw new IllegalArgumentException(); 265 throw new IllegalArgumentException();
253 } 266 }
254 DataAccess da = null; 267 DataAccess da = null;
255 try { 268 try {
270 da.done(); 283 da.done();
271 } 284 }
272 } 285 }
273 } 286 }
274 287
275 public void inspectAll(Inspector inspector) throws HgInvalidFileException { 288 /**
289 * @param inspector visit complete bundle (changelog, manifest and file entries)
290 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em>
291 * @throws IllegalArgumentException if inspector argument is null
292 */
293 public void inspectAll(Inspector inspector) throws HgRuntimeException {
276 if (inspector == null) { 294 if (inspector == null) {
277 throw new IllegalArgumentException(); 295 throw new IllegalArgumentException();
278 } 296 }
279 DataAccess da = null; 297 DataAccess da = null;
280 try { 298 try {