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 }