3939public final class UnifiedDiffReader {
4040
4141 static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern .compile ("^@@\\ s+-(?:(\\ d+)(?:,(\\ d+))?)\\ s+\\ +(?:(\\ d+)(?:,(\\ d+))?)\\ s+@@" );
42+ static final Pattern TIMESTAMP_REGEXP = Pattern .compile ("(\\ d{4}-\\ d{2}-\\ d{2}[T ]\\ d{2}:\\ d{2}:\\ d{2}\\ .\\ d{3,})" );
4243
4344 private final InternalUnifiedDiffReader READER ;
4445 private final UnifiedDiff data = new UnifiedDiff ();
@@ -49,9 +50,9 @@ public final class UnifiedDiffReader {
4950 private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine (true , "^\\ +\\ +\\ +\\ s" , this ::processToFile );
5051
5152 private final UnifiedDiffLine CHUNK = new UnifiedDiffLine (false , UNIFIED_DIFF_CHUNK_REGEXP , this ::processChunk );
52- private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine ("^\\ s+ " , this ::processNormalLine );
53+ private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine ("^\\ s" , this ::processNormalLine );
5354 private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine ("^-" , this ::processDelLine );
54- private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine ("^+" , this ::processAddLine );
55+ private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine ("^\\ +" , this ::processAddLine );
5556
5657 private UnifiedDiffFile actualFile ;
5758
@@ -81,20 +82,37 @@ private UnifiedDiff parse() throws IOException, UnifiedDiffParserException {
8182
8283 while (line != null ) {
8384 if (!CHUNK .validLine (line )) {
84- processLine (line , DIFF_COMMAND , INDEX , FROM_FILE , TO_FILE );
85- } else {
86- processLine (line , CHUNK );
85+ initFileIfNecessary ();
86+ while (!CHUNK .validLine (line )) {
87+ if (processLine (line , DIFF_COMMAND , INDEX , FROM_FILE , TO_FILE ) == false ) {
88+ throw new UnifiedDiffParserException ("expected file start line not found" );
89+ }
90+ line = READER .readLine ();
91+ }
92+ }
93+ processLine (line , CHUNK );
94+ while ((line = READER .readLine ()) != null ) {
95+ if (processLine (line , LINE_NORMAL , LINE_ADD , LINE_DEL ) == false ) {
96+ throw new UnifiedDiffParserException ("expected data line not found" );
97+ }
98+ if (originalTxt .size () == old_size && revisedTxt .size () == new_size ) {
99+ finalizeChunk ();
100+ break ;
101+ }
87102 }
88103 line = READER .readLine ();
104+ if (line == null || line .startsWith ("--" )) {
105+ break ;
106+ }
89107 }
90108
91- finalizeChunk ();
92-
93- String tailTxt = "" ;
94- while (READER .ready ()) {
95- tailTxt += READER .readLine () + "\n " ;
109+ if (READER .ready ()) {
110+ String tailTxt = "" ;
111+ while (READER .ready ()) {
112+ tailTxt += READER .readLine () + "\n " ;
113+ }
114+ data .setTailTxt (tailTxt );
96115 }
97- data .setTailTxt (tailTxt );
98116
99117 return data ;
100118 }
@@ -114,30 +132,31 @@ public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOExceptio
114132 return parser .parse ();
115133 }
116134
117- private void processLine (String line , UnifiedDiffLine ... rules ) throws UnifiedDiffParserException {
135+ private boolean processLine (String line , UnifiedDiffLine ... rules ) throws UnifiedDiffParserException {
118136 for (UnifiedDiffLine rule : rules ) {
119137 if (rule .processLine (line )) {
120138 LOG .info (" >>> processed rule " + rule .toString ());
121- return ;
139+ return true ;
122140 }
123141 }
124142 LOG .info (" >>> no rule matched " + line );
125- throw new UnifiedDiffParserException ("parsing error at line " + line );
143+ return false ;
144+ //throw new UnifiedDiffParserException("parsing error at line " + line);
126145 }
127146
128147 private void initFileIfNecessary () {
129148 if (!originalTxt .isEmpty () || !revisedTxt .isEmpty ()) {
130- finalizeChunk ();
131- actualFile = null ;
149+ throw new IllegalStateException ();
132150 }
151+ actualFile = null ;
133152 if (actualFile == null ) {
134153 actualFile = new UnifiedDiffFile ();
135154 data .addFile (actualFile );
136155 }
137156 }
138157
139158 private void processDiff (MatchResult match , String line ) {
140- initFileIfNecessary ();
159+ // initFileIfNecessary();
141160 LOG .log (Level .INFO , "start {0}" , line );
142161 String [] fromTo = parseFileNames (READER .lastLine ());
143162 actualFile .setFromFile (fromTo [0 ]);
@@ -181,7 +200,7 @@ private void processDelLine(MatchResult match, String line) {
181200 }
182201
183202 private void processChunk (MatchResult match , String chunkStart ) {
184- finalizeChunk ();
203+ // finalizeChunk();
185204 old_ln = toInteger (match , 1 , 1 );
186205 old_size = toInteger (match , 2 , 0 );
187206 new_ln = toInteger (match , 3 , 1 );
@@ -195,27 +214,43 @@ private void processChunk(MatchResult match, String chunkStart) {
195214 }
196215
197216 private static Integer toInteger (MatchResult match , int group , int defValue ) throws NumberFormatException {
198- return Integer .valueOf (Objects .toString ( match .group (group ) , "" + defValue ));
217+ return Integer .valueOf (Objects .toString (match .group (group ), "" + defValue ));
199218 }
200219
201220 private void processIndex (MatchResult match , String line ) {
202- initFileIfNecessary ();
221+ // initFileIfNecessary();
203222 LOG .log (Level .INFO , "index {0}" , line );
204223 actualFile .setIndex (line .substring (6 ));
205224 }
206225
207226 private void processFromFile (MatchResult match , String line ) {
208- initFileIfNecessary ();
227+ // initFileIfNecessary();
209228 actualFile .setFromFile (extractFileName (line ));
229+ actualFile .setFromTimestamp (extractTimestamp (line ));
210230 }
211231
212232 private void processToFile (MatchResult match , String line ) {
213- initFileIfNecessary ();
233+ // initFileIfNecessary();
214234 actualFile .setToFile (extractFileName (line ));
235+ actualFile .setToTimestamp (extractTimestamp (line ));
236+ }
237+
238+ private String extractFileName (String _line ) {
239+ Matcher matcher = TIMESTAMP_REGEXP .matcher (_line );
240+ String line = _line ;
241+ if (matcher .find ()) {
242+ line = line .substring (1 , matcher .start ());
243+ }
244+ return line .substring (4 ).replaceFirst ("^(a|b)\\ /" , "" )
245+ .replace (TIMESTAMP_REGEXP .toString (), "" ).trim ();
215246 }
216247
217- private String extractFileName (String line ) {
218- return line .substring (4 ).replaceFirst ("^(a|b)\\ /" , "" );
248+ private String extractTimestamp (String line ) {
249+ Matcher matcher = TIMESTAMP_REGEXP .matcher (line );
250+ if (matcher .find ()) {
251+ return matcher .group ();
252+ }
253+ return null ;
219254 }
220255
221256 final class UnifiedDiffLine {
0 commit comments