Mercurial > hg4j
comparison test/org/tmatesoft/hg/test/StatusOutputParser.java @ 93:d55d4eedfc57
Switch to Path instead of String in filenames returned by various status operations
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 27 Jan 2011 21:15:21 +0100 |
| parents | 61eedab3eb3e |
| children | af1f3b78b918 |
comparison
equal
deleted
inserted
replaced
| 92:bf304cb14247 | 93:d55d4eedfc57 |
|---|---|
| 15 * contact TMate Software at support@svnkit.com | 15 * contact TMate Software at support@svnkit.com |
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.test; | 17 package org.tmatesoft.hg.test; |
| 18 | 18 |
| 19 import java.io.File; | 19 import java.io.File; |
| 20 import java.util.Collections; | |
| 21 import java.util.LinkedList; | 20 import java.util.LinkedList; |
| 22 import java.util.List; | 21 import java.util.List; |
| 23 import java.util.Map; | 22 import java.util.Map; |
| 24 import java.util.TreeMap; | |
| 25 import java.util.regex.Matcher; | 23 import java.util.regex.Matcher; |
| 26 import java.util.regex.Pattern; | 24 import java.util.regex.Pattern; |
| 25 | |
| 26 import org.tmatesoft.hg.core.Path; | |
| 27 import org.tmatesoft.hg.repo.StatusCollector; | |
| 28 import org.tmatesoft.hg.util.PathPool; | |
| 29 import org.tmatesoft.hg.util.PathRewrite; | |
| 27 | 30 |
| 28 /** | 31 /** |
| 29 * | 32 * |
| 30 * @author Artem Tikhomirov | 33 * @author Artem Tikhomirov |
| 31 * @author TMate Software Ltd. | 34 * @author TMate Software Ltd. |
| 32 */ | 35 */ |
| 33 public class StatusOutputParser implements OutputParser { | 36 public class StatusOutputParser implements OutputParser { |
| 34 | 37 |
| 35 private final Pattern pattern; | 38 private final Pattern pattern; |
| 36 private List<String> modified, added, removed, clean, missing, unknown, ignored; | 39 // although using StatusCollector.Record is not really quite honest for testing, |
| 37 private Map<String, String> copied; | 40 // it's deemed acceptable as long as that class is primitive 'collect all results' |
| 38 private final boolean winPathSeparator; | 41 private StatusCollector.Record result = new StatusCollector.Record(); |
| 42 private final PathPool pathHelper; | |
| 39 | 43 |
| 40 public StatusOutputParser() { | 44 public StatusOutputParser() { |
| 41 // pattern = Pattern.compile("^([MAR?IC! ]) ([\\w \\.-/\\\\]+)$", Pattern.MULTILINE); | 45 // pattern = Pattern.compile("^([MAR?IC! ]) ([\\w \\.-/\\\\]+)$", Pattern.MULTILINE); |
| 42 pattern = Pattern.compile("^([MAR?IC! ]) (.+)$", Pattern.MULTILINE); | 46 pattern = Pattern.compile("^([MAR?IC! ]) (.+)$", Pattern.MULTILINE); |
| 43 winPathSeparator = File.separatorChar == '\\'; | 47 pathHelper = new PathPool(new PathRewrite() { |
| 48 | |
| 49 private final boolean winPathSeparator = File.separatorChar == '\\'; | |
| 50 | |
| 51 public String rewrite(String s) { | |
| 52 if (winPathSeparator) { | |
| 53 // Java impl always give slashed path, while Hg uses local, os-specific convention | |
| 54 s = s.replace('\\', '/'); | |
| 55 } | |
| 56 return s; | |
| 57 } | |
| 58 }); | |
| 44 } | 59 } |
| 45 | 60 |
| 46 public void reset() { | 61 public void reset() { |
| 47 modified = added = removed = clean = missing = unknown = ignored = null; | 62 result = new StatusCollector.Record(); |
| 48 copied = null; | |
| 49 } | 63 } |
| 50 | 64 |
| 51 public void parse(CharSequence seq) { | 65 public void parse(CharSequence seq) { |
| 52 Matcher m = pattern.matcher(seq); | 66 Matcher m = pattern.matcher(seq); |
| 67 Path lastAdded = null; | |
| 53 while (m.find()) { | 68 while (m.find()) { |
| 54 String fname = m.group(2); | 69 String fname = m.group(2); |
| 55 switch ((int) m.group(1).charAt(0)) { | 70 switch ((int) m.group(1).charAt(0)) { |
| 56 case (int) 'M' : { | 71 case (int) 'M' : { |
| 57 modified = doAdd(modified, fname); | 72 result.modified(pathHelper.path(fname)); |
| 58 break; | 73 break; |
| 59 } | 74 } |
| 60 case (int) 'A' : { | 75 case (int) 'A' : { |
| 61 added = doAdd(added, fname); | 76 result.added(lastAdded = pathHelper.path(fname)); |
| 62 break; | 77 break; |
| 63 } | 78 } |
| 64 case (int) 'R' : { | 79 case (int) 'R' : { |
| 65 removed = doAdd(removed, fname); | 80 result.removed(pathHelper.path(fname)); |
| 66 break; | 81 break; |
| 67 } | 82 } |
| 68 case (int) '?' : { | 83 case (int) '?' : { |
| 69 unknown = doAdd(unknown, fname); | 84 result.unknown(pathHelper.path(fname)); |
| 70 break; | 85 break; |
| 71 } | 86 } |
| 72 case (int) 'I' : { | 87 case (int) 'I' : { |
| 73 ignored = doAdd(ignored, fname); | 88 result.ignored(pathHelper.path(fname)); |
| 74 break; | 89 break; |
| 75 } | 90 } |
| 76 case (int) 'C' : { | 91 case (int) 'C' : { |
| 77 clean = doAdd(clean, fname); | 92 result.clean(pathHelper.path(fname)); |
| 78 break; | 93 break; |
| 79 } | 94 } |
| 80 case (int) '!' : { | 95 case (int) '!' : { |
| 81 missing = doAdd(missing, fname); | 96 result.missing(pathHelper.path(fname)); |
| 82 break; | 97 break; |
| 83 } | 98 } |
| 84 case (int) ' ' : { | 99 case (int) ' ' : { |
| 85 if (copied == null) { | |
| 86 copied = new TreeMap<String, String>(); | |
| 87 } | |
| 88 // last added is copy destination | 100 // last added is copy destination |
| 89 // to get or to remove it - depends on what StatusCollector does in this case | 101 // to get or to remove it - depends on what StatusCollector does in this case |
| 90 copied.put(added.get(added.size() - 1), toJavaImplConvention(fname)); | 102 result.copied(pathHelper.path(fname), lastAdded); |
| 91 break; | 103 break; |
| 92 } | 104 } |
| 93 } | 105 } |
| 94 } | 106 } |
| 95 } | 107 } |
| 96 | 108 |
| 97 // | 109 // |
| 98 public List<String> getModified() { | 110 public List<Path> getModified() { |
| 99 return proper(modified); | 111 return result.getModified(); |
| 100 } | 112 } |
| 101 | 113 |
| 102 public List<String> getAdded() { | 114 public List<Path> getAdded() { |
| 103 return proper(added); | 115 List<Path> rv = new LinkedList<Path>(result.getAdded()); |
| 116 for (Path p : result.getCopied().keySet()) { | |
| 117 rv.remove(p); // remove only one duplicate | |
| 118 } | |
| 119 return rv; | |
| 104 } | 120 } |
| 105 | 121 |
| 106 public List<String> getRemoved() { | 122 public List<Path> getRemoved() { |
| 107 return proper(removed); | 123 return result.getRemoved(); |
| 108 } | 124 } |
| 109 | 125 |
| 110 public Map<String,String> getCopied() { | 126 public Map<Path,Path> getCopied() { |
| 111 if (copied == null) { | 127 return result.getCopied(); |
| 112 return Collections.emptyMap(); | |
| 113 } | |
| 114 return Collections.unmodifiableMap(copied); | |
| 115 } | 128 } |
| 116 | 129 |
| 117 public List<String> getClean() { | 130 public List<Path> getClean() { |
| 118 return proper(clean); | 131 return result.getClean(); |
| 119 } | 132 } |
| 120 | 133 |
| 121 public List<String> getMissing() { | 134 public List<Path> getMissing() { |
| 122 return proper(missing); | 135 return result.getMissing(); |
| 123 } | 136 } |
| 124 | 137 |
| 125 public List<String> getUnknown() { | 138 public List<Path> getUnknown() { |
| 126 return proper(unknown); | 139 return result.getUnknown(); |
| 127 } | 140 } |
| 128 | 141 |
| 129 public List<String> getIgnored() { | 142 public List<Path> getIgnored() { |
| 130 return proper(ignored); | 143 return result.getIgnored(); |
| 131 } | |
| 132 | |
| 133 private List<String> proper(List<String> l) { | |
| 134 if (l == null) { | |
| 135 return Collections.emptyList(); | |
| 136 } | |
| 137 return Collections.unmodifiableList(l); | |
| 138 } | |
| 139 | |
| 140 private List<String> doAdd(List<String> l, String s) { | |
| 141 if (l == null) { | |
| 142 l = new LinkedList<String>(); | |
| 143 } | |
| 144 l.add(toJavaImplConvention(s)); | |
| 145 return l; | |
| 146 } | |
| 147 | |
| 148 private String toJavaImplConvention(String s) { | |
| 149 if (winPathSeparator) { | |
| 150 // Java impl always give slashed path, while Hg uses local, os-specific convention | |
| 151 s = s.replace('\\', '/'); | |
| 152 } | |
| 153 return s; | |
| 154 } | 144 } |
| 155 } | 145 } |
