Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/Revlog.java @ 277:74e7493a042a
Favor delegation over generalization
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 29 Aug 2011 23:14:59 +0200 |
parents | 9fb50c04f03c |
children | 2f2ab5c27f41 |
comparison
equal
deleted
inserted
replaced
276:6355ecda1f08 | 277:74e7493a042a |
---|---|
447 } | 447 } |
448 return sorted2natural[x]; | 448 return sorted2natural[x]; |
449 } | 449 } |
450 } | 450 } |
451 | 451 |
452 | 452 protected abstract static class ErrorHandlingInspector implements RevlogStream.Inspector, CancelSupport { |
453 protected static class ContentPipe implements RevlogStream.Inspector, CancelSupport { | 453 private Exception failure; |
454 private CancelSupport cancelSupport; | |
455 | |
456 protected void setCancelSupport(CancelSupport cs) { | |
457 assert cancelSupport == null; // no reason to set it twice | |
458 cancelSupport = cs; | |
459 } | |
460 | |
461 protected void recordFailure(Exception ex) { | |
462 assert failure == null; | |
463 failure = ex; | |
464 } | |
465 | |
466 public void checkFailed() throws HgException, IOException, CancelledException { | |
467 if (failure == null) { | |
468 return; | |
469 } | |
470 if (failure instanceof IOException) { | |
471 throw (IOException) failure; | |
472 } | |
473 if (failure instanceof CancelledException) { | |
474 throw (CancelledException) failure; | |
475 } | |
476 if (failure instanceof HgException) { | |
477 throw (HgException) failure; | |
478 } | |
479 throw new HgBadStateException(failure); | |
480 } | |
481 | |
482 public void checkCancelled() throws CancelledException { | |
483 if (cancelSupport != null) { | |
484 cancelSupport.checkCancelled(); | |
485 } | |
486 } | |
487 } | |
488 | |
489 protected static class ContentPipe extends ErrorHandlingInspector implements RevlogStream.Inspector, CancelSupport { | |
454 private final ByteChannel sink; | 490 private final ByteChannel sink; |
455 private final CancelSupport cancelSupport; | |
456 private Exception failure; | |
457 private final int offset; | 491 private final int offset; |
458 | 492 |
459 /** | 493 /** |
460 * @param _sink - cannot be <code>null</code> | 494 * @param _sink - cannot be <code>null</code> |
461 * @param seekOffset - when positive, orders to pipe bytes to the sink starting from specified offset, not from the first byte available in DataAccess | 495 * @param seekOffset - when positive, orders to pipe bytes to the sink starting from specified offset, not from the first byte available in DataAccess |
462 */ | 496 */ |
463 public ContentPipe(ByteChannel _sink, int seekOffset) { | 497 public ContentPipe(ByteChannel _sink, int seekOffset) { |
464 assert _sink != null; | 498 assert _sink != null; |
465 sink = _sink; | 499 sink = _sink; |
466 cancelSupport = CancelSupport.Factory.get(_sink); | 500 setCancelSupport(CancelSupport.Factory.get(_sink)); |
467 offset = seekOffset; | 501 offset = seekOffset; |
468 } | 502 } |
469 | 503 |
470 protected void prepare(int revisionNumber, DataAccess da) throws HgException, IOException { | 504 protected void prepare(int revisionNumber, DataAccess da) throws HgException, IOException { |
471 if (offset > 0) { // save few useless reset/rewind operations | 505 if (offset > 0) { // save few useless reset/rewind operations |
478 prepare(revisionNumber, da); // XXX perhaps, prepare shall return DA (sliced, if needed) | 512 prepare(revisionNumber, da); // XXX perhaps, prepare shall return DA (sliced, if needed) |
479 final ProgressSupport progressSupport = ProgressSupport.Factory.get(sink); | 513 final ProgressSupport progressSupport = ProgressSupport.Factory.get(sink); |
480 ByteBuffer buf = ByteBuffer.allocate(512); | 514 ByteBuffer buf = ByteBuffer.allocate(512); |
481 progressSupport.start(da.length()); | 515 progressSupport.start(da.length()); |
482 while (!da.isEmpty()) { | 516 while (!da.isEmpty()) { |
483 cancelSupport.checkCancelled(); | 517 checkCancelled(); |
484 da.readBytes(buf); | 518 da.readBytes(buf); |
485 buf.flip(); | 519 buf.flip(); |
486 // XXX I may not rely on returned number of bytes but track change in buf position instead. | 520 // XXX I may not rely on returned number of bytes but track change in buf position instead. |
487 int consumed = sink.write(buf); | 521 int consumed = sink.write(buf); |
488 // FIXME in fact, bad sink implementation (that consumes no bytes) would result in endless loop. Need to account for this | 522 // FIXME in fact, bad sink implementation (that consumes no bytes) would result in endless loop. Need to account for this |
496 recordFailure(ex); | 530 recordFailure(ex); |
497 } catch (HgException ex) { | 531 } catch (HgException ex) { |
498 recordFailure(ex); | 532 recordFailure(ex); |
499 } | 533 } |
500 } | 534 } |
501 | |
502 public void checkCancelled() throws CancelledException { | |
503 cancelSupport.checkCancelled(); | |
504 } | |
505 | |
506 protected void recordFailure(Exception ex) { | |
507 assert failure == null; | |
508 failure = ex; | |
509 } | |
510 | |
511 public void checkFailed() throws HgException, IOException, CancelledException { | |
512 if (failure == null) { | |
513 return; | |
514 } | |
515 if (failure instanceof IOException) { | |
516 throw (IOException) failure; | |
517 } | |
518 if (failure instanceof CancelledException) { | |
519 throw (CancelledException) failure; | |
520 } | |
521 if (failure instanceof HgException) { | |
522 throw (HgException) failure; | |
523 } | |
524 throw new HgBadStateException(failure); | |
525 } | |
526 } | 535 } |
527 } | 536 } |