View Javadoc

1   package org.apache.maven.mkslib;
2   
3   /* ====================================================================
4    *   Licensed to the Apache Software Foundation (ASF) under one or more
5    *   contributor license agreements.  See the NOTICE file distributed with
6    *   this work for additional information regarding copyright ownership.
7    *   The ASF licenses this file to You under the Apache License, Version 2.0
8    *   (the "License"); you may not use this file except in compliance with
9    *   the License.  You may obtain a copy of the License at
10   *
11   *       http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *   Unless required by applicable law or agreed to in writing, software
14   *   distributed under the License is distributed on an "AS IS" BASIS,
15   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *   See the License for the specific language governing permissions and
17   *   limitations under the License.
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             // MKS filter for 'tag' is not impl yet.
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                     // wait for next entry
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         // do not add if entry is not populated
333         if ( ( changeLogEntry.getAuthor() == null )
334             || ( changeLogEntry.getDate() == null ) )
335         {
336             return;
337         }
338 
339         // do not add if entry doesn't match date range.
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 }