KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > cvslib > ChangeLogParser


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.cvslib;
19
20 import java.text.ParseException JavaDoc;
21 import java.text.SimpleDateFormat JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Locale JavaDoc;
26 import java.util.TimeZone JavaDoc;
27
28 /**
29  * A class used to parse the output of the CVS log command.
30  *
31  */

32 class ChangeLogParser {
33     //private static final int GET_ENTRY = 0;
34
private static final int GET_FILE = 1;
35     private static final int GET_DATE = 2;
36     private static final int GET_COMMENT = 3;
37     private static final int GET_REVISION = 4;
38     private static final int GET_PREVIOUS_REV = 5;
39
40 // FIXME formatters are not thread-safe
41

42     /** input format for dates read in from cvs log */
43     private static final SimpleDateFormat JavaDoc INPUT_DATE
44         = new SimpleDateFormat JavaDoc("yyyy/MM/dd HH:mm:ss", Locale.US);
45     /**
46      * New formatter used to parse CVS date/timestamp.
47      */

48     private static final SimpleDateFormat JavaDoc CVS1129_INPUT_DATE =
49         new SimpleDateFormat JavaDoc("yyyy-MM-dd HH:mm:ss Z", Locale.US);
50
51     static {
52         TimeZone JavaDoc utc = TimeZone.getTimeZone("UTC");
53         INPUT_DATE.setTimeZone(utc);
54         CVS1129_INPUT_DATE.setTimeZone(utc);
55     }
56
57     //The following is data used while processing stdout of CVS command
58
private String JavaDoc file;
59     private String JavaDoc date;
60     private String JavaDoc author;
61     private String JavaDoc comment;
62     private String JavaDoc revision;
63     private String JavaDoc previousRevision;
64
65     private int status = GET_FILE;
66
67     /** rcs entries */
68     private final Hashtable JavaDoc entries = new Hashtable JavaDoc();
69
70     /**
71      * Get a list of rcs entries as an array.
72      *
73      * @return a list of rcs entries as an array
74      */

75     public CVSEntry[] getEntrySetAsArray() {
76         final CVSEntry[] array = new CVSEntry[ entries.size() ];
77         int i = 0;
78         for (Enumeration JavaDoc e = entries.elements(); e.hasMoreElements();) {
79             array[i++] = (CVSEntry) e.nextElement();
80         }
81         return array;
82     }
83
84     /**
85      * Receive notification about the process writing
86      * to standard output.
87      * @param line the line to process
88      */

89     public void stdout(final String JavaDoc line) {
90         switch(status) {
91             case GET_FILE:
92                 // make sure attributes are reset when
93
// working on a 'new' file.
94
reset();
95                 processFile(line);
96                 break;
97             case GET_REVISION:
98                 processRevision(line);
99                 break;
100
101             case GET_DATE:
102                 processDate(line);
103                 break;
104
105             case GET_COMMENT:
106                 processComment(line);
107                 break;
108
109             case GET_PREVIOUS_REV:
110                 processGetPreviousRevision(line);
111                 break;
112
113             default:
114                 // Do nothing
115
break;
116         }
117     }
118
119     /**
120      * Process a line while in "GET_COMMENT" state.
121      *
122      * @param line the line
123      */

124     private void processComment(final String JavaDoc line) {
125         final String JavaDoc lineSeparator = System.getProperty("line.separator");
126         if (line.equals(
127                 "=============================================================================")) {
128             //We have ended changelog for that particular file
129
//so we can save it
130
final int end
131                 = comment.length() - lineSeparator.length(); //was -1
132
comment = comment.substring(0, end);
133             saveEntry();
134             status = GET_FILE;
135         } else if (line.equals("----------------------------")) {
136             final int end
137                 = comment.length() - lineSeparator.length(); //was -1
138
comment = comment.substring(0, end);
139             status = GET_PREVIOUS_REV;
140         } else {
141             comment += line + lineSeparator;
142         }
143     }
144
145     /**
146      * Process a line while in "GET_FILE" state.
147      *
148      * @param line the line to process
149      */

150     private void processFile(final String JavaDoc line) {
151         if (line.startsWith("Working file:")) {
152             file = line.substring(14, line.length());
153             status = GET_REVISION;
154         }
155     }
156
157     /**
158      * Process a line while in "REVISION" state.
159      *
160      * @param line the line to process
161      */

162     private void processRevision(final String JavaDoc line) {
163         if (line.startsWith("revision")) {
164             revision = line.substring(9);
165             status = GET_DATE;
166         } else if (line.startsWith("======")) {
167             //There were no revisions in this changelog
168
//entry so lets move onto next file
169
status = GET_FILE;
170         }
171     }
172
173     /**
174      * Process a line while in "DATE" state.
175      *
176      * @param line the line to process
177      */

178     private void processDate(final String JavaDoc line) {
179         if (line.startsWith("date:")) {
180             // The date format is using a - format since 1.12.9 so we have:
181
// 1.12.9-: 'date: YYYY/mm/dd HH:mm:ss; author: name;'
182
// 1.12.9+: 'date: YYYY-mm-dd HH:mm:ss Z; author: name'
183
int endOfDateIndex = line.indexOf(';');
184             date = line.substring("date: ".length(), endOfDateIndex);
185
186             int startOfAuthorIndex = line.indexOf("author: ", endOfDateIndex + 1);
187             int endOfAuthorIndex = line.indexOf(';', startOfAuthorIndex + 1);
188             author = line.substring("author: ".length() + startOfAuthorIndex, endOfAuthorIndex);
189
190             status = GET_COMMENT;
191
192             //Reset comment to empty here as we can accumulate multiple lines
193
//in the processComment method
194
comment = "";
195         }
196     }
197
198     /**
199      * Process a line while in "GET_PREVIOUS_REVISION" state.
200      *
201      * @param line the line to process
202      */

203     private void processGetPreviousRevision(final String JavaDoc line) {
204         if (!line.startsWith("revision ")) {
205             throw new IllegalStateException JavaDoc("Unexpected line from CVS: "
206                 + line);
207         }
208         previousRevision = line.substring("revision ".length());
209
210         saveEntry();
211
212         revision = previousRevision;
213         status = GET_DATE;
214     }
215
216     /**
217      * Utility method that saves the current entry.
218      */

219     private void saveEntry() {
220         final String JavaDoc entryKey = date + author + comment;
221         CVSEntry entry;
222         if (!entries.containsKey(entryKey)) {
223             Date JavaDoc dateObject = parseDate(date);
224             entry = new CVSEntry(dateObject, author, comment);
225             entries.put(entryKey, entry);
226         } else {
227             entry = (CVSEntry) entries.get(entryKey);
228         }
229
230         entry.addFile(file, revision, previousRevision);
231     }
232
233     /**
234      * Parse date out from expected format.
235      *
236      * @param date the string holding date
237      * @return the date object or null if unknown date format
238      */

239     private Date JavaDoc parseDate(final String JavaDoc date) {
240         try {
241             return INPUT_DATE.parse(date);
242         } catch (ParseException JavaDoc e) {
243             try {
244                 return CVS1129_INPUT_DATE.parse(date);
245             } catch (ParseException JavaDoc e2) {
246                 throw new IllegalStateException JavaDoc("Invalid date format: " + date);
247             }
248         }
249     }
250
251     /**
252      * Reset all internal attributes except status.
253      */

254     public void reset() {
255         this.file = null;
256         this.date = null;
257         this.author = null;
258         this.comment = null;
259         this.revision = null;
260         this.previousRevision = null;
261     }
262 }
263
Popular Tags