Mercurial > jhg
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 { | 
