1 package org.apache.maven.scm.provider.cvslib.command.changelog;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.scm.ChangeFile;
23 import org.apache.maven.scm.ChangeSet;
24 import org.apache.maven.scm.log.ScmLogger;
25 import org.apache.maven.scm.util.AbstractConsumer;
26
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.Comparator;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.StringTokenizer;
33
34
35
36
37
38
39 public class CvsChangeLogConsumer
40 extends AbstractConsumer
41 {
42 private List entries = new ArrayList();
43
44
45
46
47
48
49 private static final int GET_FILE = 1;
50
51
52
53
54 private static final int GET_DATE = 2;
55
56
57
58
59 private static final int GET_COMMENT = 3;
60
61
62
63
64 private static final int GET_REVISION = 4;
65
66
67
68
69 private static final String START_FILE = "Working file: ";
70
71
72
73
74 private static final String END_FILE =
75 "===================================" + "==========================================";
76
77
78
79
80 private static final String START_REVISION = "----------------------------";
81
82
83
84
85 private static final String REVISION_TAG = "revision ";
86
87
88
89
90 private static final String DATE_TAG = "date: ";
91
92
93
94
95 private int status = GET_FILE;
96
97
98
99
100 private ChangeSet currentChange = null;
101
102
103
104
105 private ChangeFile currentFile = null;
106
107 private String userDatePattern;
108
109 public CvsChangeLogConsumer( ScmLogger logger, String userDatePattern )
110 {
111 super( logger );
112
113 this.userDatePattern = userDatePattern;
114 }
115
116 public List getModifications()
117 {
118 Collections.sort( entries, new Comparator()
119 {
120 public int compare( Object entry1, Object entry2 )
121 {
122 ChangeSet set1 = (ChangeSet) entry1;
123 ChangeSet set2 = (ChangeSet) entry2;
124 return set1.getDate().compareTo( set2.getDate() );
125 }
126 } );
127 List fixedModifications = new ArrayList();
128 ChangeSet currentEntry = null;
129 for ( Iterator entryIterator = entries.iterator(); entryIterator.hasNext(); )
130 {
131 ChangeSet entry = (ChangeSet) entryIterator.next();
132 if ( currentEntry == null )
133 {
134 currentEntry = entry;
135 }
136 else if ( areEqual( currentEntry, entry ) )
137 {
138 currentEntry.addFile( (ChangeFile) entry.getFiles().get( 0 ) );
139 }
140 else
141 {
142 fixedModifications.add( currentEntry );
143 currentEntry = entry;
144 }
145 }
146 if ( currentEntry != null )
147 {
148 fixedModifications.add( currentEntry );
149 }
150 return fixedModifications;
151 }
152
153 private boolean areEqual( ChangeSet set1, ChangeSet set2 )
154 {
155 if ( set1.getAuthor().equals( set2.getAuthor() ) && set1.getComment().equals( set2.getComment() ) &&
156 set1.getDate().equals( set2.getDate() ) )
157 {
158 return true;
159 }
160 return false;
161 }
162
163 public void consumeLine( String line )
164 {
165 try
166 {
167 switch ( getStatus() )
168 {
169 case GET_FILE:
170 processGetFile( line );
171 break;
172 case GET_REVISION:
173 processGetRevision( line );
174 break;
175 case GET_DATE:
176 processGetDate( line );
177 break;
178 case GET_COMMENT:
179 processGetComment( line );
180 break;
181 default:
182 throw new IllegalStateException( "Unknown state: " + status );
183 }
184 }
185 catch ( Throwable ex )
186 {
187 getLogger().warn( "Exception in the cvs changelog consumer.", ex );
188 }
189 }
190
191
192
193
194
195
196
197
198
199
200 private void addEntry( ChangeSet entry, ChangeFile file )
201 {
202
203 if ( entry.getAuthor() == null )
204 {
205 return;
206 }
207
208 entry.addFile( file );
209
210 entries.add( entry );
211 }
212
213
214
215
216
217
218 private void processGetFile( String line )
219 {
220 if ( line.startsWith( START_FILE ) )
221 {
222 setCurrentChange( new ChangeSet() );
223 setCurrentFile( new ChangeFile( line.substring( START_FILE.length(), line.length() ) ) );
224 setStatus( GET_REVISION );
225 }
226 }
227
228
229
230
231
232
233 private void processGetRevision( String line )
234 {
235 if ( line.startsWith( REVISION_TAG ) )
236 {
237 getCurrentFile().setRevision( line.substring( REVISION_TAG.length() ) );
238 setStatus( GET_DATE );
239 }
240 else if ( line.startsWith( END_FILE ) )
241 {
242
243
244
245 setStatus( GET_FILE );
246 addEntry( getCurrentChange(), getCurrentFile() );
247 }
248 }
249
250
251
252
253
254
255 private void processGetDate( String line )
256 {
257 if ( line.startsWith( DATE_TAG ) )
258 {
259 StringTokenizer tokenizer = new StringTokenizer( line, ";" );
260
261
262 String datePart = tokenizer.nextToken().trim();
263 String dateTime = datePart.substring( "date: ".length() );
264 StringTokenizer dateTokenizer = new StringTokenizer( dateTime, " " );
265 if ( dateTokenizer.countTokens() == 2 )
266 {
267 dateTime += " UTC";
268 }
269 getCurrentChange().setDate( dateTime, userDatePattern );
270
271 String authorPart = tokenizer.nextToken().trim();
272 String author = authorPart.substring( "author: ".length() );
273 getCurrentChange().setAuthor( author );
274 setStatus( GET_COMMENT );
275 }
276 }
277
278
279
280
281
282
283 private void processGetComment( String line )
284 {
285 if ( line.startsWith( START_REVISION ) )
286 {
287
288 addEntry( getCurrentChange(), getCurrentFile() );
289
290 setCurrentChange( new ChangeSet() );
291
292 setCurrentFile( new ChangeFile( getCurrentFile().getName() ) );
293 setStatus( GET_REVISION );
294 }
295 else if ( line.startsWith( END_FILE ) )
296 {
297 addEntry( getCurrentChange(), getCurrentFile() );
298 setStatus( GET_FILE );
299 }
300 else
301 {
302
303 getCurrentChange().setComment( getCurrentChange().getComment() + line + "\n" );
304 }
305 }
306
307
308
309
310
311
312 private ChangeFile getCurrentFile()
313 {
314 return currentFile;
315 }
316
317
318
319
320
321
322 private void setCurrentFile( ChangeFile currentFile )
323 {
324 this.currentFile = currentFile;
325 }
326
327
328
329
330
331
332 private ChangeSet getCurrentChange()
333 {
334 return currentChange;
335 }
336
337
338
339
340
341
342 private void setCurrentChange( ChangeSet currentChange )
343 {
344 this.currentChange = currentChange;
345 }
346
347
348
349
350
351
352 private int getStatus()
353 {
354 return status;
355 }
356
357
358
359
360
361
362 private void setStatus( int status )
363 {
364 this.status = status;
365 }
366 }