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