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 }