1 package org.apache.maven.mkslib;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Date;
33 import java.util.Map;
34 import java.util.TreeMap;
35
36 import org.apache.maven.changelog.ChangeLog;
37 import org.apache.maven.changelog.ChangeLogEntry;
38 import org.apache.maven.changelog.ChangeLogFile;
39 import org.apache.maven.changelog.ChangeLogParser;
40
41 /**
42 * This class parse mks log output.
43 *
44 * @author <a href="mailto:c.jerolimov@tarent.de">Christoph Jerolimov</a>
45 * @version $Id: MksChangeLogParser.java 532339 2007-04-25 12:28:56Z ltheussl $
46 */
47 public class MksChangeLogParser implements ChangeLogParser
48 {
49 /**
50 * This date/time formatter will be uses to parse a mks date.
51 */
52 private static final SimpleDateFormat MKS_TIMESTAMP_FORMAT =
53 new SimpleDateFormat( "MMM d, yyyy - h:mm a" );
54
55 /**
56 * Custom date/time formatter. Rounds ChangeLogEntry times to the nearest
57 * minute.
58 */
59 private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
60 new SimpleDateFormat( "yyyyMMddHHmm" );
61
62 /** expecting file name */
63 private static final int GET_FILE_NAME = 1;
64
65 /** expecting file revision */
66 private static final int GET_FILE_REVISION = 2;
67
68 /** expecting entry revision */
69 private static final int WAITFOR_ENTRY_REVISION = 3;
70
71 /** expecting file revision */
72 private static final int GET_ENTRY_INFO = 4;
73
74 /** expecting file revision */
75 private static final int GET_ENTRY_COMMENT = 5;
76
77 /** rcs entries, in reverse (date, time, author, comment) order */
78 private Map entries = new TreeMap( Collections.reverseOrder() );
79
80 /** current status of the parser */
81 private int status = GET_FILE_NAME;
82
83 /** current changelog entry */
84 private ChangeLogEntry changeLogEntry;
85
86 /** current changelog file */
87 private ChangeLogFile changeLogFile;
88
89 /** date filter, only entries after this date match */
90 private Date filterDateStart;
91
92 /** date filter, only entries before this date match */
93 private Date filterDateEnd;
94
95 public void init( ChangeLog changeLog )
96 {
97 if (changeLog.getType().equals("range"))
98 {
99 try
100 {
101 if ( ( changeLog.getRange() != null )
102 && ( changeLog.getRange().length() != 0 ) )
103 {
104 long range = Integer.parseInt(changeLog.getRange());
105 filterDateStart = new Date(System.currentTimeMillis()
106 - ( range * ( 24 * 60 * 60 * 1000 ) ) );
107 filterDateEnd = null;
108 }
109 else
110 {
111 throw new NumberFormatException("no range");
112 }
113 }
114 catch (NumberFormatException e)
115 {
116 e.printStackTrace();
117 filterDateStart = null;
118 filterDateEnd = null;
119 }
120 }
121 else if (changeLog.getType().equals("date"))
122 {
123 if ( ( changeLog.getMarkerStart() != null )
124 && ( changeLog.getMarkerStart().length() != 0 ) )
125 {
126 try
127 {
128 filterDateStart = new SimpleDateFormat("y-M-d").
129 parse(changeLog.getMarkerStart());
130 }
131 catch (ParseException e)
132 {
133 e.printStackTrace();
134 filterDateStart = null;
135 }
136 }
137
138 if ( ( changeLog.getMarkerEnd() != null )
139 && ( changeLog.getMarkerEnd().length() != 0 ) )
140 {
141 try
142 {
143 filterDateEnd = new SimpleDateFormat("y-M-d").
144 parse(changeLog.getMarkerEnd());
145 }
146 catch (ParseException e)
147 {
148 e.printStackTrace();
149 filterDateEnd = null;
150 }
151 }
152 }
153 else if (changeLog.getType().equals("tag"))
154 {
155
156 }
157 }
158
159 public void cleanup()
160 {
161 }
162
163 public void setDateFormatInFile( String dateFormat )
164 {
165 }
166
167 public Collection parse( InputStream in )
168 throws IOException
169 {
170 try
171 {
172 BufferedReader reader =
173 new BufferedReader( new InputStreamReader( in ) );
174
175 String line;
176
177 while ( ( line = reader.readLine() ) != null )
178 {
179 if ( line.startsWith(
180 "========================================" ) )
181 {
182 status = GET_FILE_NAME;
183 }
184
185 switch ( status )
186 {
187 case GET_FILE_NAME :
188 addEntry();
189 processGetFileName( line );
190
191 break;
192
193 case GET_FILE_REVISION :
194 processGetFileRevision( line );
195
196 break;
197
198 case WAITFOR_ENTRY_REVISION :
199 processWaitForEntryRevision( line );
200
201 break;
202
203 case GET_ENTRY_INFO :
204 processGetEntryInfo( line );
205
206 break;
207
208 case GET_ENTRY_COMMENT :
209 processGetEntryComment( line );
210
211 break;
212
213 default :
214
215
216 break;
217 }
218 }
219
220 addEntry();
221 }
222 catch ( RuntimeException e )
223 {
224 e.printStackTrace();
225 throw e;
226 }
227 catch ( IOException e )
228 {
229 e.printStackTrace();
230 throw e;
231 }
232
233 return entries.values();
234 }
235
236 protected void processGetFileName( String line )
237 {
238 if ( line.startsWith( "member name: " ) )
239 {
240 String filename;
241
242 if ( line.indexOf( ";" ) == -1 )
243 {
244 filename = line.substring( 13 );
245 }
246 else
247 {
248 filename = line.substring( 13, line.indexOf( ";" ) );
249 }
250
251 changeLogFile = new ChangeLogFile( filename );
252 status = GET_FILE_REVISION;
253 }
254 }
255
256 protected void processGetFileRevision( String line )
257 {
258 if ( line.startsWith( "member:\t" ) )
259 {
260 changeLogFile.setRevision( line.substring( 8 ) );
261 status = WAITFOR_ENTRY_REVISION;
262 }
263 }
264
265 protected void processWaitForEntryRevision( String line )
266 {
267 if ( line.equals( "-----------------------" ) )
268 {
269 status = GET_ENTRY_INFO;
270 }
271 }
272
273 protected void processGetEntryInfo( String line )
274 {
275 if ( line.startsWith( "date: " ) )
276 {
277 changeLogEntry = new ChangeLogEntry();
278
279 int posAuthor = line.indexOf( "; author: " );
280
281 if ( posAuthor == -1 )
282 {
283 return;
284 }
285
286 int posState = line.indexOf( "; state: " );
287
288 if ( posState == -1 )
289 {
290 return;
291 }
292
293 try
294 {
295 Date date =
296 MKS_TIMESTAMP_FORMAT.parse( line.substring( 6, posAuthor ) );
297 String author = line.substring( posAuthor + 10, posState );
298
299 changeLogEntry.setDate( date );
300 changeLogEntry.setAuthor( author );
301 status = GET_ENTRY_COMMENT;
302 }
303 catch ( ParseException e )
304 {
305 throw new IllegalArgumentException(
306 "I don't understand this date: "
307 + line.substring( 6, posAuthor ) );
308 }
309 }
310 }
311
312 protected void processGetEntryComment( String line )
313 {
314 if ( line.equals( "-----------------------" ) )
315 {
316 addEntry();
317 status = GET_ENTRY_INFO;
318
319 return;
320 }
321
322 changeLogEntry.setComment( changeLogEntry.getComment() + line + "\n" );
323 }
324
325 protected void addEntry()
326 {
327 if ( ( changeLogEntry == null ) || ( changeLogFile == null ) )
328 {
329 return;
330 }
331
332
333 if ( ( changeLogEntry.getAuthor() == null )
334 || ( changeLogEntry.getDate() == null ) )
335 {
336 return;
337 }
338
339
340 if ( (filterDateStart != null && changeLogEntry.getDate().before(filterDateStart)) ||
341 (filterDateEnd != null && changeLogEntry.getDate().after(filterDateEnd)) )
342 {
343 return;
344 }
345
346 String key =
347 ENTRY_KEY_TIMESTAMP_FORMAT.format( changeLogEntry.getDate() )
348 + changeLogEntry.getAuthor() + changeLogEntry.getComment();
349
350 if ( !entries.containsKey( key ) )
351 {
352 changeLogEntry.addFile( changeLogFile );
353 entries.put( key, changeLogEntry );
354 }
355 else
356 {
357 ( (ChangeLogEntry) entries.get( key ) ).addFile( changeLogFile );
358 }
359 }
360 }