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