1 | /*
|
---|
2 | * Copyright 2002-2005 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.taskdefs.cvslib;
|
---|
18 |
|
---|
19 | import java.text.ParseException;
|
---|
20 | import java.text.SimpleDateFormat;
|
---|
21 | import java.util.Date;
|
---|
22 | import java.util.Enumeration;
|
---|
23 | import java.util.Hashtable;
|
---|
24 | import java.util.TimeZone;
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * A class used to parse the output of the CVS log command.
|
---|
28 | *
|
---|
29 | */
|
---|
30 | class ChangeLogParser {
|
---|
31 | //private static final int GET_ENTRY = 0;
|
---|
32 | private static final int GET_FILE = 1;
|
---|
33 | private static final int GET_DATE = 2;
|
---|
34 | private static final int GET_COMMENT = 3;
|
---|
35 | private static final int GET_REVISION = 4;
|
---|
36 | private static final int GET_PREVIOUS_REV = 5;
|
---|
37 |
|
---|
38 | /** input format for dates read in from cvs log */
|
---|
39 | private static final SimpleDateFormat c_inputDate
|
---|
40 | = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
---|
41 |
|
---|
42 | static {
|
---|
43 | TimeZone utc = TimeZone.getTimeZone("UTC");
|
---|
44 | c_inputDate.setTimeZone(utc);
|
---|
45 | }
|
---|
46 |
|
---|
47 | //The following is data used while processing stdout of CVS command
|
---|
48 | private String m_file;
|
---|
49 | private String m_date;
|
---|
50 | private String m_author;
|
---|
51 | private String m_comment;
|
---|
52 | private String m_revision;
|
---|
53 | private String m_previousRevision;
|
---|
54 |
|
---|
55 | private int m_status = GET_FILE;
|
---|
56 |
|
---|
57 | /** rcs entries */
|
---|
58 | private final Hashtable m_entries = new Hashtable();
|
---|
59 |
|
---|
60 | /**
|
---|
61 | * Get a list of rcs entries as an array.
|
---|
62 | *
|
---|
63 | * @return a list of rcs entries as an array
|
---|
64 | */
|
---|
65 | CVSEntry[] getEntrySetAsArray() {
|
---|
66 | final CVSEntry[] array = new CVSEntry[ m_entries.size() ];
|
---|
67 | Enumeration e = m_entries.elements();
|
---|
68 | int i = 0;
|
---|
69 | while (e.hasMoreElements()) {
|
---|
70 | array[i++] = (CVSEntry) e.nextElement();
|
---|
71 | }
|
---|
72 | return array;
|
---|
73 | }
|
---|
74 |
|
---|
75 | /**
|
---|
76 | * Receive notification about the process writing
|
---|
77 | * to standard output.
|
---|
78 | */
|
---|
79 | public void stdout(final String line) {
|
---|
80 | switch(m_status) {
|
---|
81 | case GET_FILE:
|
---|
82 | // make sure attributes are reset when
|
---|
83 | // working on a 'new' file.
|
---|
84 | reset();
|
---|
85 | processFile(line);
|
---|
86 | break;
|
---|
87 | case GET_REVISION:
|
---|
88 | processRevision(line);
|
---|
89 | break;
|
---|
90 |
|
---|
91 | case GET_DATE:
|
---|
92 | processDate(line);
|
---|
93 | break;
|
---|
94 |
|
---|
95 | case GET_COMMENT:
|
---|
96 | processComment(line);
|
---|
97 | break;
|
---|
98 |
|
---|
99 | case GET_PREVIOUS_REV:
|
---|
100 | processGetPreviousRevision(line);
|
---|
101 | break;
|
---|
102 | }
|
---|
103 | }
|
---|
104 |
|
---|
105 | /**
|
---|
106 | * Process a line while in "GET_COMMENT" state.
|
---|
107 | *
|
---|
108 | * @param line the line
|
---|
109 | */
|
---|
110 | private void processComment(final String line) {
|
---|
111 | final String lineSeparator = System.getProperty("line.separator");
|
---|
112 | if (line.startsWith("======")) {
|
---|
113 | //We have ended changelog for that particular file
|
---|
114 | //so we can save it
|
---|
115 | final int end
|
---|
116 | = m_comment.length() - lineSeparator.length(); //was -1
|
---|
117 | m_comment = m_comment.substring(0, end);
|
---|
118 | saveEntry();
|
---|
119 | m_status = GET_FILE;
|
---|
120 | } else if (line.startsWith("----------------------------")) {
|
---|
121 | final int end
|
---|
122 | = m_comment.length() - lineSeparator.length(); //was -1
|
---|
123 | m_comment = m_comment.substring(0, end);
|
---|
124 | m_status = GET_PREVIOUS_REV;
|
---|
125 | } else {
|
---|
126 | m_comment += line + lineSeparator;
|
---|
127 | }
|
---|
128 | }
|
---|
129 |
|
---|
130 | /**
|
---|
131 | * Process a line while in "GET_FILE" state.
|
---|
132 | *
|
---|
133 | * @param line the line
|
---|
134 | */
|
---|
135 | private void processFile(final String line) {
|
---|
136 | if (line.startsWith("Working file:")) {
|
---|
137 | m_file = line.substring(14, line.length());
|
---|
138 | m_status = GET_REVISION;
|
---|
139 | }
|
---|
140 | }
|
---|
141 |
|
---|
142 | /**
|
---|
143 | * Process a line while in "REVISION" state.
|
---|
144 | *
|
---|
145 | * @param line the line
|
---|
146 | */
|
---|
147 | private void processRevision(final String line) {
|
---|
148 | if (line.startsWith("revision")) {
|
---|
149 | m_revision = line.substring(9);
|
---|
150 | m_status = GET_DATE;
|
---|
151 | } else if (line.startsWith("======")) {
|
---|
152 | //There was no revisions in this changelog
|
---|
153 | //entry so lets move unto next file
|
---|
154 | m_status = GET_FILE;
|
---|
155 | }
|
---|
156 | }
|
---|
157 |
|
---|
158 | /**
|
---|
159 | * Process a line while in "DATE" state.
|
---|
160 | *
|
---|
161 | * @param line the line
|
---|
162 | */
|
---|
163 | private void processDate(final String line) {
|
---|
164 | if (line.startsWith("date:")) {
|
---|
165 | m_date = line.substring(6, 25);
|
---|
166 | String lineData = line.substring(line.indexOf(";") + 1);
|
---|
167 | m_author = lineData.substring(10, lineData.indexOf(";"));
|
---|
168 |
|
---|
169 | m_status = GET_COMMENT;
|
---|
170 |
|
---|
171 | //Reset comment to empty here as we can accumulate multiple lines
|
---|
172 | //in the processComment method
|
---|
173 | m_comment = "";
|
---|
174 | }
|
---|
175 | }
|
---|
176 |
|
---|
177 | /**
|
---|
178 | * Process a line while in "GET_PREVIOUS_REVISION" state.
|
---|
179 | *
|
---|
180 | * @param line the line
|
---|
181 | */
|
---|
182 | private void processGetPreviousRevision(final String line) {
|
---|
183 | if (!line.startsWith("revision")) {
|
---|
184 | throw new IllegalStateException("Unexpected line from CVS: "
|
---|
185 | + line);
|
---|
186 | }
|
---|
187 | m_previousRevision = line.substring(9);
|
---|
188 |
|
---|
189 | saveEntry();
|
---|
190 |
|
---|
191 | m_revision = m_previousRevision;
|
---|
192 | m_status = GET_DATE;
|
---|
193 | }
|
---|
194 |
|
---|
195 | /**
|
---|
196 | * Utility method that saves the current entry.
|
---|
197 | */
|
---|
198 | private void saveEntry() {
|
---|
199 | final String entryKey = m_date + m_author + m_comment;
|
---|
200 | CVSEntry entry;
|
---|
201 | if (!m_entries.containsKey(entryKey)) {
|
---|
202 | entry = new CVSEntry(parseDate(m_date), m_author, m_comment);
|
---|
203 | m_entries.put(entryKey, entry);
|
---|
204 | } else {
|
---|
205 | entry = (CVSEntry) m_entries.get(entryKey);
|
---|
206 | }
|
---|
207 |
|
---|
208 | entry.addFile(m_file, m_revision, m_previousRevision);
|
---|
209 | }
|
---|
210 |
|
---|
211 | /**
|
---|
212 | * Parse date out from expected format.
|
---|
213 | *
|
---|
214 | * @param date the string holding dat
|
---|
215 | * @return the date object or null if unknown date format
|
---|
216 | */
|
---|
217 | private Date parseDate(final String date) {
|
---|
218 | try {
|
---|
219 | return c_inputDate.parse(date);
|
---|
220 | } catch (ParseException e) {
|
---|
221 | //final String message = REZ.getString( "changelog.bat-date.error", date );
|
---|
222 | //getContext().error( message );
|
---|
223 | return null;
|
---|
224 | }
|
---|
225 | }
|
---|
226 |
|
---|
227 | /**
|
---|
228 | * reset all internal attributes except status.
|
---|
229 | */
|
---|
230 | private void reset() {
|
---|
231 | m_file = null;
|
---|
232 | m_date = null;
|
---|
233 | m_author = null;
|
---|
234 | m_comment = null;
|
---|
235 | m_revision = null;
|
---|
236 | m_previousRevision = null;
|
---|
237 | }
|
---|
238 |
|
---|
239 | }
|
---|