1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.provider.hg.command.diff;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.maven.scm.ScmFile;
28 import org.apache.maven.scm.ScmFileStatus;
29 import org.apache.maven.scm.provider.hg.command.HgConsumer;
30
31
32
33
34
35
36 public class HgDiffConsumer extends HgConsumer {
37
38
39
40 private static final String INDEX_TOKEN = "diff -r ";
41
42 private static final String FILE_SEPARATOR_TOKEN = "===";
43
44 private static final String START_REVISION_TOKEN = "---";
45
46 private static final String END_REVISION_TOKEN = "+++";
47
48 private static final String ADDED_LINE_TOKEN = "+";
49
50 private static final String REMOVED_LINE_TOKEN = "-";
51
52 private static final String UNCHANGED_LINE_TOKEN = " ";
53
54 private static final String CHANGE_SEPARATOR_TOKEN = "@@";
55
56 private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file";
57
58 private static final int HASH_ID_LEN = 12;
59
60 private String currentFile;
61
62 private StringBuilder currentDifference;
63
64 private final List<ScmFile> changedFiles = new ArrayList<>();
65
66 private final Map<String, CharSequence> differences = new HashMap<>();
67
68 private final StringBuilder patch = new StringBuilder();
69
70 @SuppressWarnings("unused")
71 private final File workingDirectory;
72
73 public HgDiffConsumer(File workingDirectory) {
74 this.workingDirectory = workingDirectory;
75 }
76
77
78
79
80
81
82 public void consumeLine(String line) {
83 if (line.startsWith(INDEX_TOKEN)) {
84
85 currentFile = line.substring(INDEX_TOKEN.length() + HASH_ID_LEN + 1);
86
87 changedFiles.add(new ScmFile(currentFile, ScmFileStatus.MODIFIED));
88
89 currentDifference = new StringBuilder();
90
91 differences.put(currentFile, currentDifference);
92
93 patch.append(line).append("\n");
94
95 return;
96 }
97
98 if (currentFile == null) {
99 if (logger.isWarnEnabled()) {
100 logger.warn("Unparseable line: '" + line + "'");
101 }
102 patch.append(line).append("\n");
103 return;
104 }
105
106 if (line.startsWith(FILE_SEPARATOR_TOKEN)) {
107
108 patch.append(line).append("\n");
109 } else if (line.startsWith(START_REVISION_TOKEN)) {
110
111 patch.append(line).append("\n");
112 } else if (line.startsWith(END_REVISION_TOKEN)) {
113
114 patch.append(line).append("\n");
115 } else if (line.startsWith(ADDED_LINE_TOKEN)
116 || line.startsWith(REMOVED_LINE_TOKEN)
117 || line.startsWith(UNCHANGED_LINE_TOKEN)
118 || line.startsWith(CHANGE_SEPARATOR_TOKEN)
119 || line.equals(NO_NEWLINE_TOKEN)) {
120
121 currentDifference.append(line).append("\n");
122 patch.append(line).append("\n");
123 } else {
124
125
126 if (logger.isWarnEnabled()) {
127 logger.warn("Unparseable line: '" + line + "'");
128 }
129 patch.append(line).append("\n");
130
131 currentFile = null;
132 currentDifference = null;
133 }
134 }
135
136 public List<ScmFile> getChangedFiles() {
137 return changedFiles;
138 }
139
140 public Map<String, CharSequence> getDifferences() {
141 return differences;
142 }
143
144 public String getPatch() {
145 return patch.toString();
146 }
147 }