Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/ext/MqManager.java @ 480:f3fab7a20841
Refactor LineReader utility as stanalone class to facilitate reuse
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Tue, 17 Jul 2012 22:14:21 +0200 |
| parents | 0e34b8f3946a |
| children | b3c16d1aede0 |
comparison
equal
deleted
inserted
replaced
| 479:59b7c817bc4d | 480:f3fab7a20841 |
|---|---|
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.repo.ext; | 17 package org.tmatesoft.hg.repo.ext; |
| 18 | 18 |
| 19 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; | 19 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; |
| 20 | 20 |
| 21 import java.io.BufferedReader; | |
| 22 import java.io.File; | 21 import java.io.File; |
| 23 import java.io.FileReader; | |
| 24 import java.io.IOException; | 22 import java.io.IOException; |
| 25 import java.util.ArrayList; | 23 import java.util.ArrayList; |
| 26 import java.util.Collection; | |
| 27 import java.util.Collections; | 24 import java.util.Collections; |
| 28 import java.util.HashMap; | 25 import java.util.HashMap; |
| 29 import java.util.LinkedList; | 26 import java.util.LinkedList; |
| 30 import java.util.List; | 27 import java.util.List; |
| 31 import java.util.Map; | 28 import java.util.Map; |
| 32 | 29 |
| 33 import org.tmatesoft.hg.core.Nodeid; | 30 import org.tmatesoft.hg.core.Nodeid; |
| 31 import org.tmatesoft.hg.internal.LineReader; | |
| 34 import org.tmatesoft.hg.repo.HgInternals; | 32 import org.tmatesoft.hg.repo.HgInternals; |
| 35 import org.tmatesoft.hg.repo.HgInvalidControlFileException; | 33 import org.tmatesoft.hg.repo.HgInvalidControlFileException; |
| 36 import org.tmatesoft.hg.repo.HgInvalidFileException; | 34 import org.tmatesoft.hg.repo.HgInvalidFileException; |
| 37 import org.tmatesoft.hg.repo.HgRepository; | 35 import org.tmatesoft.hg.repo.HgRepository; |
| 38 import org.tmatesoft.hg.util.LogFacility; | 36 import org.tmatesoft.hg.util.LogFacility; |
| 69 final LogFacility log = HgInternals.getContext(repo).getLog(); | 67 final LogFacility log = HgInternals.getContext(repo).getLog(); |
| 70 try { | 68 try { |
| 71 File queues = new File(repoDir, "patches.queues"); | 69 File queues = new File(repoDir, "patches.queues"); |
| 72 if (queues.isFile()) { | 70 if (queues.isFile()) { |
| 73 LineReader lr = new LineReader(queues, log).trimLines(true).skipEmpty(true); | 71 LineReader lr = new LineReader(queues, log).trimLines(true).skipEmpty(true); |
| 74 lr.read(new SimpleLineCollector(), queueNames = new LinkedList<String>()); | 72 lr.read(new LineReader.SimpleLineCollector(), queueNames = new LinkedList<String>()); |
| 75 } | 73 } |
| 76 final String queueLocation; // path under .hg to patch queue information (status, series and diff files) | 74 final String queueLocation; // path under .hg to patch queue information (status, series and diff files) |
| 77 File activeQueueFile = new File(repoDir, "patches.queue"); | 75 File activeQueueFile = new File(repoDir, "patches.queue"); |
| 78 // file is there only if it's not default queue ('patches') that is active | 76 // file is there only if it's not default queue ('patches') that is active |
| 79 if (activeQueueFile.isFile()) { | 77 if (activeQueueFile.isFile()) { |
| 80 ArrayList<String> contents = new ArrayList<String>(); | 78 ArrayList<String> contents = new ArrayList<String>(); |
| 81 new LineReader(activeQueueFile, log).read(new SimpleLineCollector(), contents); | 79 new LineReader(activeQueueFile, log).read(new LineReader.SimpleLineCollector(), contents); |
| 82 if (contents.isEmpty()) { | 80 if (contents.isEmpty()) { |
| 83 log.dump(getClass(), Warn, "File %s with active queue name is empty", activeQueueFile.getName()); | 81 log.dump(getClass(), Warn, "File %s with active queue name is empty", activeQueueFile.getName()); |
| 84 activeQueue = PATCHES_DIR; | 82 activeQueue = PATCHES_DIR; |
| 85 queueLocation = PATCHES_DIR + '/'; | 83 queueLocation = PATCHES_DIR + '/'; |
| 86 } else { | 84 } else { |
| 102 } | 100 } |
| 103 }; | 101 }; |
| 104 final File fileStatus = new File(repoDir, queueLocation + "status"); | 102 final File fileStatus = new File(repoDir, queueLocation + "status"); |
| 105 final File fileSeries = new File(repoDir, queueLocation + "series"); | 103 final File fileSeries = new File(repoDir, queueLocation + "series"); |
| 106 if (fileStatus.isFile()) { | 104 if (fileStatus.isFile()) { |
| 107 new LineReader(fileStatus, log).read(new LineConsumer<List<PatchRecord>>() { | 105 new LineReader(fileStatus, log).read(new LineReader.LineConsumer<List<PatchRecord>>() { |
| 108 | 106 |
| 109 public boolean consume(String line, List<PatchRecord> result) throws IOException { | 107 public boolean consume(String line, List<PatchRecord> result) throws IOException { |
| 110 int sep = line.indexOf(':'); | 108 int sep = line.indexOf(':'); |
| 111 if (sep == -1) { | 109 if (sep == -1) { |
| 112 log.dump(MqManager.class, Warn, "Bad line in %s:%s", fileStatus.getPath(), line); | 110 log.dump(MqManager.class, Warn, "Bad line in %s:%s", fileStatus.getPath(), line); |
| 123 final Map<String,PatchRecord> name2patch = new HashMap<String, PatchRecord>(); | 121 final Map<String,PatchRecord> name2patch = new HashMap<String, PatchRecord>(); |
| 124 for (PatchRecord pr : applied) { | 122 for (PatchRecord pr : applied) { |
| 125 name2patch.put(pr.getName(), pr); | 123 name2patch.put(pr.getName(), pr); |
| 126 } | 124 } |
| 127 LinkedList<String> knownPatchNames = new LinkedList<String>(); | 125 LinkedList<String> knownPatchNames = new LinkedList<String>(); |
| 128 new LineReader(fileSeries, log).read(new SimpleLineCollector(), knownPatchNames); | 126 new LineReader(fileSeries, log).read(new LineReader.SimpleLineCollector(), knownPatchNames); |
| 129 // XXX read other queues? | 127 // XXX read other queues? |
| 130 allKnown = new ArrayList<PatchRecord>(knownPatchNames.size()); | 128 allKnown = new ArrayList<PatchRecord>(knownPatchNames.size()); |
| 131 for (String name : knownPatchNames) { | 129 for (String name : knownPatchNames) { |
| 132 PatchRecord pr = name2patch.get(name); | 130 PatchRecord pr = name2patch.get(name); |
| 133 if (pr == null) { | 131 if (pr == null) { |
| 138 } | 136 } |
| 139 } catch (HgInvalidFileException ex) { | 137 } catch (HgInvalidFileException ex) { |
| 140 HgInvalidControlFileException th = new HgInvalidControlFileException(ex.getMessage(), ex.getCause(), ex.getFile()); | 138 HgInvalidControlFileException th = new HgInvalidControlFileException(ex.getMessage(), ex.getCause(), ex.getFile()); |
| 141 th.setStackTrace(ex.getStackTrace()); | 139 th.setStackTrace(ex.getStackTrace()); |
| 142 throw th; | 140 throw th; |
| 143 } | |
| 144 } | |
| 145 | |
| 146 static class SimpleLineCollector implements LineConsumer<Collection<String>> { | |
| 147 | |
| 148 public boolean consume(String line, Collection<String> result) throws IOException { | |
| 149 result.add(line); | |
| 150 return true; | |
| 151 } | 141 } |
| 152 } | 142 } |
| 153 | 143 |
| 154 /** | 144 /** |
| 155 * Number of patches not yet applied | 145 * Number of patches not yet applied |
| 244 String fmt = "mq.PatchRecord[name:%s; %spath:%s]"; | 234 String fmt = "mq.PatchRecord[name:%s; %spath:%s]"; |
| 245 String ni = nodeid != null ? String.format("applied as: %s; ", nodeid.shortNotation()) : ""; | 235 String ni = nodeid != null ? String.format("applied as: %s; ", nodeid.shortNotation()) : ""; |
| 246 return String.format(fmt, name, ni, location); | 236 return String.format(fmt, name, ni, location); |
| 247 } | 237 } |
| 248 } | 238 } |
| 249 | |
| 250 // TODO refine API and extract into separate classes | |
| 251 | |
| 252 interface LineConsumer<T> { | |
| 253 // boolean begin(File f, T paramObj) throws IOException; | |
| 254 boolean consume(String line, T paramObj) throws IOException; | |
| 255 // boolean end(File f, T paramObj) throws IOException; | |
| 256 } | |
| 257 | |
| 258 class LineReader { | |
| 259 | |
| 260 private final File file; | |
| 261 private final LogFacility log; | |
| 262 private boolean trimLines = true; | |
| 263 private boolean skipEmpty = true; | |
| 264 private String ignoreThatStars = null; | |
| 265 | |
| 266 LineReader(File f, LogFacility logFacility) { | |
| 267 file = f; | |
| 268 log = logFacility; | |
| 269 } | |
| 270 | |
| 271 /** | |
| 272 * default: <code>true</code> | |
| 273 * <code>false</code> to return line as is | |
| 274 */ | |
| 275 LineReader trimLines(boolean trim) { | |
| 276 trimLines = trim; | |
| 277 return this; | |
| 278 } | |
| 279 | |
| 280 /** | |
| 281 * default: <code>true</code> | |
| 282 * <code>false</code> to pass empty lines to consumer | |
| 283 */ | |
| 284 LineReader skipEmpty(boolean skip) { | |
| 285 skipEmpty = skip; | |
| 286 return this; | |
| 287 } | |
| 288 | |
| 289 /** | |
| 290 * default: doesn't skip any line. | |
| 291 * set e.g. to "#" or "//" to skip lines that start with such prefix | |
| 292 */ | |
| 293 LineReader ignoreLineComments(String lineStart) { | |
| 294 ignoreThatStars = lineStart; | |
| 295 return this; | |
| 296 } | |
| 297 | |
| 298 <T> void read(LineConsumer<T> consumer, T paramObj) throws HgInvalidFileException { | |
| 299 BufferedReader statusFileReader = null; | |
| 300 try { | |
| 301 // consumer.begin(file, paramObj); | |
| 302 statusFileReader = new BufferedReader(new FileReader(file)); | |
| 303 String line; | |
| 304 boolean ok = true; | |
| 305 while (ok && (line = statusFileReader.readLine()) != null) { | |
| 306 if (trimLines) { | |
| 307 line = line.trim(); | |
| 308 } | |
| 309 if (ignoreThatStars != null && line.startsWith(ignoreThatStars)) { | |
| 310 continue; | |
| 311 } | |
| 312 if (!skipEmpty || line.length() > 0) { | |
| 313 ok = consumer.consume(line, paramObj); | |
| 314 } | |
| 315 } | |
| 316 } catch (IOException ex) { | |
| 317 throw new HgInvalidFileException(ex.getMessage(), ex, file); | |
| 318 } finally { | |
| 319 try { | |
| 320 statusFileReader.close(); | |
| 321 } catch (IOException ex) { | |
| 322 log.dump(MqManager.class, Warn, ex, null); | |
| 323 } | |
| 324 // try { | |
| 325 // consumer.end(file, paramObj); | |
| 326 // } catch (IOException ex) { | |
| 327 // log.warn(MqManager.class, ex, null); | |
| 328 // } | |
| 329 } | |
| 330 } | |
| 331 } | |
| 332 } | 239 } |
