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