Mercurial > jhg
comparison src/org/tmatesoft/hg/core/HgCatCommand.java @ 427:31a89587eb04
FIXMEs: consistent names, throws for commands and their handlers. Use of checked exceptions in hi-level api
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 29 Mar 2012 17:14:35 +0200 |
parents | 9c9c442b5f2e |
children | 78a9e26e670d |
comparison
equal
deleted
inserted
replaced
426:063b0663495a | 427:31a89587eb04 |
---|---|
22 | 22 |
23 import java.io.IOException; | 23 import java.io.IOException; |
24 import java.nio.ByteBuffer; | 24 import java.nio.ByteBuffer; |
25 | 25 |
26 import org.tmatesoft.hg.repo.HgDataFile; | 26 import org.tmatesoft.hg.repo.HgDataFile; |
27 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | |
28 import org.tmatesoft.hg.repo.HgInvalidFileException; | |
29 import org.tmatesoft.hg.repo.HgInvalidRevisionException; | |
30 import org.tmatesoft.hg.repo.HgRepository; | 27 import org.tmatesoft.hg.repo.HgRepository; |
28 import org.tmatesoft.hg.repo.HgRuntimeException; | |
31 import org.tmatesoft.hg.util.Adaptable; | 29 import org.tmatesoft.hg.util.Adaptable; |
32 import org.tmatesoft.hg.util.ByteChannel; | 30 import org.tmatesoft.hg.util.ByteChannel; |
33 import org.tmatesoft.hg.util.CancelSupport; | 31 import org.tmatesoft.hg.util.CancelSupport; |
34 import org.tmatesoft.hg.util.CancelledException; | 32 import org.tmatesoft.hg.util.CancelledException; |
35 import org.tmatesoft.hg.util.Path; | 33 import org.tmatesoft.hg.util.Path; |
134 * Runs the command with current set of parameters and pipes data to provided sink. | 132 * Runs the command with current set of parameters and pipes data to provided sink. |
135 * | 133 * |
136 * @param sink output channel to write data to. | 134 * @param sink output channel to write data to. |
137 * | 135 * |
138 * @throws HgBadArgumentException if no target file node found | 136 * @throws HgBadArgumentException if no target file node found |
139 * @throws HgInvalidControlFileException if access to revlog index/data entry failed | 137 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state |
140 * @throws HgInvalidFileException if access to file in working directory failed | 138 * @throws CancelledException if execution of the command was cancelled |
141 * @throws HgException in case of some other library issue | |
142 * @throws CancelledException if execution of the operation was cancelled | |
143 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog (<em>runtime exception</em>) | |
144 * @throws IllegalArgumentException when command arguments are incomplete or wrong | 139 * @throws IllegalArgumentException when command arguments are incomplete or wrong |
145 */ | 140 */ |
146 public void execute(ByteChannel sink) throws HgException, CancelledException { | 141 public void execute(ByteChannel sink) throws HgException, CancelledException { |
147 // XXX perhaps, IAE together with HgBadArgumentException is not the best idea | 142 // XXX perhaps, IAE together with HgBadArgumentException is not the best idea |
148 if (revisionIndex == BAD_REVISION && revision == null && cset == null) { | 143 if (revisionIndex == BAD_REVISION && revision == null && cset == null) { |
152 throw new IllegalArgumentException("Name of the file is missing"); | 147 throw new IllegalArgumentException("Name of the file is missing"); |
153 } | 148 } |
154 if (sink == null) { | 149 if (sink == null) { |
155 throw new IllegalArgumentException("Need an output channel"); | 150 throw new IllegalArgumentException("Need an output channel"); |
156 } | 151 } |
157 HgDataFile dataFile = repo.getFileNode(file); | 152 try { |
158 if (!dataFile.exists()) { | 153 HgDataFile dataFile = repo.getFileNode(file); |
159 // TODO may benefit from repo.getStoragePath to print revlog location in addition to human-friendly file path | 154 if (!dataFile.exists()) { |
160 throw new HgBadArgumentException(String.format("File %s not found in the repository", file), null).setFileName(file); | 155 // TODO may benefit from repo.getStoragePath to print revlog location in addition to human-friendly file path |
161 } | 156 throw new HgPathNotFoundException(String.format("File %s not found in the repository", file), file); |
162 int revToExtract; | 157 } |
163 if (cset != null) { | 158 int revToExtract; |
164 int csetRev = repo.getChangelog().getRevisionIndex(cset); | 159 if (cset != null) { |
165 Nodeid toExtract = null; | 160 int csetRev = repo.getChangelog().getRevisionIndex(cset); |
166 do { | 161 Nodeid toExtract = null; |
167 // TODO post-1.0 perhaps, HgChangesetFileSneaker may come handy? | 162 do { |
168 toExtract = repo.getManifest().getFileRevision(csetRev, file); | 163 // TODO post-1.0 perhaps, HgChangesetFileSneaker may come handy? |
164 toExtract = repo.getManifest().getFileRevision(csetRev, file); | |
165 if (toExtract == null) { | |
166 if (dataFile.isCopy()) { | |
167 file = dataFile.getCopySourceName(); | |
168 dataFile = repo.getFileNode(file); | |
169 } else { | |
170 break; | |
171 } | |
172 } | |
173 } while (toExtract == null); | |
169 if (toExtract == null) { | 174 if (toExtract == null) { |
170 if (dataFile.isCopy()) { | 175 String m = String.format("File %s nor its origins were known at repository's %s revision", file, cset.shortNotation()); |
171 file = dataFile.getCopySourceName(); | 176 throw new HgPathNotFoundException(m, file).setRevision(cset); |
172 dataFile = repo.getFileNode(file); | |
173 } else { | |
174 break; | |
175 } | |
176 } | 177 } |
177 } while (toExtract == null); | 178 revToExtract = dataFile.getRevisionIndex(toExtract); |
178 if (toExtract == null) { | 179 } else if (revision != null) { |
179 // TODO explicit FileNotFoundException? | 180 revToExtract = dataFile.getRevisionIndex(revision); |
180 throw new HgBadArgumentException(String.format("File %s nor its origins were not known at repository %s revision", file, cset.shortNotation()), null); | 181 } else { |
181 } | 182 revToExtract = revisionIndex; |
182 revToExtract = dataFile.getRevisionIndex(toExtract); | 183 } |
183 } else if (revision != null) { | 184 ByteChannel sinkWrap; |
184 revToExtract = dataFile.getRevisionIndex(revision); | 185 if (getCancelSupport(null, false) == null) { |
185 } else { | 186 // no command-specific cancel helper, no need for extra proxy |
186 revToExtract = revisionIndex; | 187 // sink itself still may supply CS |
187 } | 188 sinkWrap = sink; |
188 ByteChannel sinkWrap; | 189 } else { |
189 if (getCancelSupport(null, false) == null) { | 190 // try CS from sink, if any. at least there is CS from command |
190 // no command-specific cancel helper, no need for extra proxy | 191 CancelSupport cancelHelper = getCancelSupport(sink, true); |
191 // sink itself still may supply CS | 192 cancelHelper.checkCancelled(); |
192 sinkWrap = sink; | 193 sinkWrap = new ByteChannelProxy(sink, cancelHelper); |
193 } else { | 194 } |
194 // try CS from sink, if any. at least there is CS from command | 195 dataFile.contentWithFilters(revToExtract, sinkWrap); |
195 CancelSupport cancelHelper = getCancelSupport(sink, true); | 196 } catch (HgRuntimeException ex) { |
196 cancelHelper.checkCancelled(); | 197 throw new HgLibraryFailureException(ex); |
197 sinkWrap = new ByteChannelProxy(sink, cancelHelper); | 198 } |
198 } | |
199 dataFile.contentWithFilters(revToExtract, sinkWrap); | |
200 } | 199 } |
201 | 200 |
202 private static class ByteChannelProxy implements ByteChannel, Adaptable { | 201 private static class ByteChannelProxy implements ByteChannel, Adaptable { |
203 private final ByteChannel delegate; | 202 private final ByteChannel delegate; |
204 private final CancelSupport cancelHelper; | 203 private final CancelSupport cancelHelper; |