comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 628:6526d8adbc0f

Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 22 May 2013 15:52:31 +0200
parents b4948b159ab1
children 5f52074707b2
comparison
equal deleted inserted replaced
627:5153eb73b18d 628:6526d8adbc0f
192 } 192 }
193 } 193 }
194 194
195 /** 195 /**
196 * @return file revision as recorded in repository manifest for dirstate parent, or <code>null</code> if no file revision can be found 196 * @return file revision as recorded in repository manifest for dirstate parent, or <code>null</code> if no file revision can be found
197 */ 197 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em>
198 private Nodeid getWorkingCopyRevision() throws HgInvalidControlFileException { 198 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em>
199 */
200 private Nodeid getWorkingCopyRevision() throws HgRuntimeException {
199 final Pair<Nodeid, Nodeid> wcParents = getRepo().getWorkingCopyParents(); 201 final Pair<Nodeid, Nodeid> wcParents = getRepo().getWorkingCopyParents();
200 Nodeid p = wcParents.first().isNull() ? wcParents.second() : wcParents.first(); 202 Nodeid p = wcParents.first().isNull() ? wcParents.second() : wcParents.first();
201 final HgChangelog clog = getRepo().getChangelog(); 203 final HgChangelog clog = getRepo().getChangelog();
202 final int csetRevIndex; 204 final int csetRevIndex;
203 if (p.isNull()) { 205 if (p.isNull()) {
215 final Nodeid tipRev = clog.getRevision(TIP); 217 final Nodeid tipRev = clog.getRevision(TIP);
216 if (tipRev.equals(p)) { 218 if (tipRev.equals(p)) {
217 csetRevIndex = clog.getLastRevision(); 219 csetRevIndex = clog.getLastRevision();
218 } else { 220 } else {
219 // bad luck, need to search honestly 221 // bad luck, need to search honestly
220 csetRevIndex = getRepo().getChangelog().getRevisionIndex(p); 222 csetRevIndex = clog.getRevisionIndex(p);
221 } 223 }
222 } 224 }
223 Nodeid fileRev = getRepo().getManifest().getFileRevision(csetRevIndex, getPath()); 225 Nodeid fileRev = getRepo().getManifest().getFileRevision(csetRevIndex, getPath());
224 // it's possible for a file to be in working dir and have store/.i but to belong e.g. to a different 226 // it's possible for a file to be in working dir and have store/.i but to belong e.g. to a different
225 // branch than the one from dirstate. Thus it's possible to get null fileRev 227 // branch than the one from dirstate. Thus it's possible to get null fileRev
426 } 428 }
427 429
428 /** 430 /**
429 * mimic 'hg diff -r clogRevIndex1 -r clogRevIndex2' 431 * mimic 'hg diff -r clogRevIndex1 -r clogRevIndex2'
430 */ 432 */
431 public void diff(int clogRevIndex1, int clogRevIndex2, HgBlameInspector insp) throws HgCallbackTargetException { 433 public void diff(int clogRevIndex1, int clogRevIndex2, HgBlameInspector insp) throws HgRuntimeException, HgCallbackTargetException {
432 int fileRevIndex1 = fileRevIndex(this, clogRevIndex1); 434 int fileRevIndex1 = fileRevIndex(this, clogRevIndex1);
433 int fileRevIndex2 = fileRevIndex(this, clogRevIndex2); 435 int fileRevIndex2 = fileRevIndex(this, clogRevIndex2);
434 BlameHelper bh = new BlameHelper(insp); 436 BlameHelper bh = new BlameHelper(insp);
435 bh.prepare(this, clogRevIndex1, clogRevIndex2); 437 bh.prepare(this, clogRevIndex1, clogRevIndex2);
436 bh.diff(fileRevIndex1, clogRevIndex1, fileRevIndex2, clogRevIndex2); 438 bh.diff(fileRevIndex1, clogRevIndex1, fileRevIndex2, clogRevIndex2);
437 } 439 }
438 440
439 /** 441 /**
440 * Walk file history up/down to revision at given changeset and report changes for each revision 442 * Walk file history up/down to revision at given changeset and report changes for each revision
441 */ 443 */
442 public void annotate(int changelogRevisionIndex, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException { 444 public void annotate(int changelogRevisionIndex, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgRuntimeException, HgCallbackTargetException {
443 annotate(0, changelogRevisionIndex, insp, iterateOrder); 445 annotate(0, changelogRevisionIndex, insp, iterateOrder);
444 } 446 }
445 447
446 /** 448 /**
447 * Walk file history range and report changes for each revision 449 * Walk file history range and report changes for each revision
448 */ 450 */
449 public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException { 451 public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgRuntimeException, HgCallbackTargetException {
450 if (wrongRevisionIndex(changelogRevIndexStart) || wrongRevisionIndex(changelogRevIndexEnd)) { 452 if (wrongRevisionIndex(changelogRevIndexStart) || wrongRevisionIndex(changelogRevIndexEnd)) {
451 throw new IllegalArgumentException(); 453 throw new IllegalArgumentException();
452 } 454 }
453 // Note, changelogRevIndexEnd may be TIP, while the code below doesn't tolerate constants 455 // Note, changelogRevIndexEnd may be TIP, while the code below doesn't tolerate constants
454 // 456 //
481 /** 483 /**
482 * Annotates changes of the file against its parent(s). 484 * Annotates changes of the file against its parent(s).
483 * Unlike {@link #annotate(HgDataFile, int, Inspector, HgIterateDirection)}, doesn't 485 * Unlike {@link #annotate(HgDataFile, int, Inspector, HgIterateDirection)}, doesn't
484 * walk file history, looks at the specified revision only. Handles both parents (if merge revision). 486 * walk file history, looks at the specified revision only. Handles both parents (if merge revision).
485 */ 487 */
486 public void annotateSingleRevision(int changelogRevisionIndex, HgBlameInspector insp) throws HgCallbackTargetException { 488 public void annotateSingleRevision(int changelogRevisionIndex, HgBlameInspector insp) throws HgRuntimeException, HgCallbackTargetException {
487 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f 489 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f
488 int fileRevIndex = fileRevIndex(this, changelogRevisionIndex); 490 int fileRevIndex = fileRevIndex(this, changelogRevisionIndex);
489 int[] fileRevParents = new int[2]; 491 int[] fileRevParents = new int[2];
490 parents(fileRevIndex, fileRevParents, null, null); 492 parents(fileRevIndex, fileRevParents, null, null);
491 if (changelogRevisionIndex == TIP) { 493 if (changelogRevisionIndex == TIP) {
507 sb.append(getPath()); 509 sb.append(getPath());
508 sb.append(')'); 510 sb.append(')');
509 return sb.toString(); 511 return sb.toString();
510 } 512 }
511 513
512 private void checkAndRecordMetadata(int localRev) throws HgInvalidControlFileException { 514 private void checkAndRecordMetadata(int localRev) throws HgRuntimeException {
513 if (metadata == null) { 515 if (metadata == null) {
514 metadata = new Metadata(getRepo()); 516 metadata = new Metadata(getRepo());
515 } 517 }
516 // use MetadataInspector without delegate to process metadata only 518 // use MetadataInspector without delegate to process metadata only
517 RevlogStream.Inspector insp = new MetadataInspector(metadata, null); 519 RevlogStream.Inspector insp = new MetadataInspector(metadata, null);
518 super.content.iterate(localRev, localRev, true, insp); 520 super.content.iterate(localRev, localRev, true, insp);
519 } 521 }
520 522
521 523
522 private static int fileRevIndex(HgDataFile df, int csetRevIndex) { 524 private static int fileRevIndex(HgDataFile df, int csetRevIndex) throws HgRuntimeException {
523 Nodeid fileRev = df.getRepo().getManifest().getFileRevision(csetRevIndex, df.getPath()); 525 Nodeid fileRev = df.getRepo().getManifest().getFileRevision(csetRevIndex, df.getPath());
524 return df.getRevisionIndex(fileRev); 526 return df.getRevisionIndex(fileRev);
525 } 527 }
526 528
527 529
537 metadata = _metadata; 539 metadata = _metadata;
538 delegate = chain; 540 delegate = chain;
539 setCancelSupport(CancelSupport.Factory.get(chain)); 541 setCancelSupport(CancelSupport.Factory.get(chain));
540 } 542 }
541 543
542 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { 544 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException {
543 try { 545 try {
544 if (metadata.tryRead(revisionNumber, data)) { 546 if (metadata.tryRead(revisionNumber, data)) {
545 // da is in prepared state (i.e. we consumed all bytes up to metadata end). 547 // da is in prepared state (i.e. we consumed all bytes up to metadata end).
546 // However, it's not safe to assume delegate won't call da.reset() for some reason, 548 // However, it's not safe to assume delegate won't call da.reset() for some reason,
547 // and we need to ensure predictable result. 549 // and we need to ensure predictable result.