Mercurial > jhg
diff src/org/tmatesoft/hg/core/HgCatCommand.java @ 322:d68dcb3b5f49
Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 30 Sep 2011 08:00:04 +0200 |
parents | 3fbfce107f94 |
children | 5f9073eabf06 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCatCommand.java Fri Sep 30 07:59:22 2011 +0200 +++ b/src/org/tmatesoft/hg/core/HgCatCommand.java Fri Sep 30 08:00:04 2011 +0200 @@ -21,10 +21,14 @@ import static org.tmatesoft.hg.repo.HgRepository.TIP; import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.util.Adaptable; import org.tmatesoft.hg.util.ByteChannel; +import org.tmatesoft.hg.util.CancelSupport; import org.tmatesoft.hg.util.CancelledException; import org.tmatesoft.hg.util.Path; @@ -170,6 +174,44 @@ } else { revToExtract = localRevision; } - dataFile.contentWithFilters(revToExtract, sink); + ByteChannel sinkWrap; + if (getCancelSupport(null, false) == null) { + // no command-specific cancel helper, no need for extra proxy + // sink itself still may supply CS + sinkWrap = sink; + } else { + // try CS from sink, if any. at least there is CS from command + CancelSupport cancelHelper = getCancelSupport(sink, true); + cancelHelper.checkCancelled(); + sinkWrap = new ByteChannelProxy(sink, cancelHelper); + } + dataFile.contentWithFilters(revToExtract, sinkWrap); + } + + private static class ByteChannelProxy implements ByteChannel, Adaptable { + private final ByteChannel delegate; + private final CancelSupport cancelHelper; + + public ByteChannelProxy(ByteChannel _delegate, CancelSupport cs) { + assert _delegate != null; + delegate = _delegate; + cancelHelper = cs; + } + public int write(ByteBuffer buffer) throws IOException, CancelledException { + return delegate.write(buffer); + } + + public <T> T getAdapter(Class<T> adapterClass) { + if (CancelSupport.class == adapterClass) { + return adapterClass.cast(cancelHelper); + } + if (delegate instanceof Adaptable) { + return ((Adaptable) delegate).getAdapter(adapterClass); + } + if (adapterClass.isInstance(delegate)) { + return adapterClass.cast(delegate); + } + return null; + } } }