source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 13.2 KB
Line 
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 */
17package org.apache.tools.ant.taskdefs.cvslib;
18
19import java.io.File;
20import java.io.FileInputStream;
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.OutputStreamWriter;
24import java.io.PrintWriter;
25import java.io.UnsupportedEncodingException;
26import java.text.SimpleDateFormat;
27import java.util.Date;
28import java.util.Enumeration;
29import java.util.Properties;
30import java.util.Vector;
31import org.apache.tools.ant.BuildException;
32import org.apache.tools.ant.DirectoryScanner;
33import org.apache.tools.ant.Project;
34import org.apache.tools.ant.taskdefs.Execute;
35import org.apache.tools.ant.taskdefs.AbstractCvsTask;
36import org.apache.tools.ant.types.Commandline;
37import org.apache.tools.ant.types.FileSet;
38
39/**
40 * Examines the output of cvs log and group related changes together.
41 *
42 * It produces an XML output representing the list of changes.
43 * <PRE>
44 * <FONT color=#0000ff>&lt;!-- Root element --&gt;</FONT>
45 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> changelog <FONT color=#ff00ff>(entry</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>&gt;</FONT>
46 * <FONT color=#0000ff>&lt;!-- CVS Entry --&gt;</FONT>
47 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> entry <FONT color=#ff00ff>(date,author,file</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>,msg)</FONT><FONT color=#6a5acd>&gt;</FONT>
48 * <FONT color=#0000ff>&lt;!-- Date of cvs entry --&gt;</FONT>
49 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> date <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
50 * <FONT color=#0000ff>&lt;!-- Author of change --&gt;</FONT>
51 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> author <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
52 * <FONT color=#0000ff>&lt;!-- List of files affected --&gt;</FONT>
53 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> msg <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
54 * <FONT color=#0000ff>&lt;!-- File changed --&gt;</FONT>
55 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> file <FONT color=#ff00ff>(name,revision,prevrevision</FONT><FONT color=#ff00ff>?</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>&gt;</FONT>
56 * <FONT color=#0000ff>&lt;!-- Name of the file --&gt;</FONT>
57 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> name <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
58 * <FONT color=#0000ff>&lt;!-- Revision number --&gt;</FONT>
59 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> revision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
60 * <FONT color=#0000ff>&lt;!-- Previous revision number --&gt;</FONT>
61 * <FONT color=#6a5acd>&lt;!ELEMENT</FONT> prevrevision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
62 * </PRE>
63 *
64 * @since Ant 1.5
65 * @ant.task name="cvschangelog" category="scm"
66 */
67public class ChangeLogTask extends AbstractCvsTask {
68 /** User list */
69 private File m_usersFile;
70
71 /** User list */
72 private Vector m_cvsUsers = new Vector();
73
74 /** Input dir */
75 private File m_dir;
76
77 /** Output file */
78 private File m_destfile;
79
80 /** The earliest date at which to start processing entries. */
81 private Date m_start;
82
83 /** The latest date at which to stop processing entries. */
84 private Date m_stop;
85
86 /**
87 * Filesets containing list of files against which the cvs log will be
88 * performed. If empty then all files will in the working directory will
89 * be checked.
90 */
91 private final Vector m_filesets = new Vector();
92
93
94 /**
95 * Set the base dir for cvs.
96 *
97 * @param dir The new dir value
98 */
99 public void setDir(final File dir) {
100 m_dir = dir;
101 }
102
103
104 /**
105 * Set the output file for the log.
106 *
107 * @param destfile The new destfile value
108 */
109 public void setDestfile(final File destfile) {
110 m_destfile = destfile;
111 }
112
113
114 /**
115 * Set a lookup list of user names & addresses
116 *
117 * @param usersFile The file containing the users info.
118 */
119 public void setUsersfile(final File usersFile) {
120 m_usersFile = usersFile;
121 }
122
123
124 /**
125 * Add a user to list changelog knows about.
126 *
127 * @param user the user
128 */
129 public void addUser(final CvsUser user) {
130 m_cvsUsers.addElement(user);
131 }
132
133
134 /**
135 * Set the date at which the changelog should start.
136 *
137 * @param start The date at which the changelog should start.
138 */
139 public void setStart(final Date start) {
140 m_start = start;
141 }
142
143
144 /**
145 * Set the date at which the changelog should stop.
146 *
147 * @param stop The date at which the changelog should stop.
148 */
149 public void setEnd(final Date stop) {
150 m_stop = stop;
151 }
152
153
154 /**
155 * Set the number of days worth of log entries to process.
156 *
157 * @param days the number of days of log to process.
158 */
159 public void setDaysinpast(final int days) {
160 final long time = System.currentTimeMillis()
161 - (long) days * 24 * 60 * 60 * 1000;
162
163 setStart(new Date(time));
164 }
165
166
167 /**
168 * Adds a set of files about which cvs logs will be generated.
169 *
170 * @param fileSet a set of files about which cvs logs will be generated.
171 */
172 public void addFileset(final FileSet fileSet) {
173 m_filesets.addElement(fileSet);
174 }
175
176
177 /**
178 * Execute task
179 *
180 * @exception BuildException if something goes wrong executing the
181 * cvs command
182 */
183 public void execute() throws BuildException {
184 File savedDir = m_dir; // may be altered in validate
185
186 try {
187
188 validate();
189 final Properties userList = new Properties();
190
191 loadUserlist(userList);
192
193 for (Enumeration e = m_cvsUsers.elements();
194 e.hasMoreElements();) {
195 final CvsUser user = (CvsUser) e.nextElement();
196
197 user.validate();
198 userList.put(user.getUserID(), user.getDisplayname());
199 }
200
201
202 setCommand("log");
203
204 if (getTag() != null) {
205 CvsVersion myCvsVersion = new CvsVersion();
206 myCvsVersion.setProject(getProject());
207 myCvsVersion.setTaskName("cvsversion");
208 myCvsVersion.setCvsRoot(getCvsRoot());
209 myCvsVersion.setCvsRsh(getCvsRsh());
210 myCvsVersion.setPassfile(getPassFile());
211 myCvsVersion.setDest(m_dir);
212 myCvsVersion.execute();
213 if (myCvsVersion.supportsCvsLogWithSOption()) {
214 addCommandArgument("-S");
215 }
216 }
217 if (null != m_start) {
218 final SimpleDateFormat outputDate =
219 new SimpleDateFormat("yyyy-MM-dd");
220
221 // We want something of the form: -d ">=YYYY-MM-dd"
222 final String dateRange = ">=" + outputDate.format(m_start);
223
224 // Supply '-d' as a separate argument - Bug# 14397
225 addCommandArgument("-d");
226 addCommandArgument(dateRange);
227 }
228
229 // Check if list of files to check has been specified
230 if (!m_filesets.isEmpty()) {
231 final Enumeration e = m_filesets.elements();
232
233 while (e.hasMoreElements()) {
234 final FileSet fileSet = (FileSet) e.nextElement();
235 final DirectoryScanner scanner =
236 fileSet.getDirectoryScanner(getProject());
237 final String[] files = scanner.getIncludedFiles();
238
239 for (int i = 0; i < files.length; i++) {
240 addCommandArgument(files[i]);
241 }
242 }
243 }
244
245 final ChangeLogParser parser = new ChangeLogParser();
246 final RedirectingStreamHandler handler =
247 new RedirectingStreamHandler(parser);
248
249 log(getCommand(), Project.MSG_VERBOSE);
250
251 setDest(m_dir);
252 setExecuteStreamHandler(handler);
253 try {
254 super.execute();
255 } finally {
256 final String errors = handler.getErrors();
257
258 if (null != errors) {
259 log(errors, Project.MSG_ERR);
260 }
261 }
262 final CVSEntry[] entrySet = parser.getEntrySetAsArray();
263 final CVSEntry[] filteredEntrySet = filterEntrySet(entrySet);
264
265 replaceAuthorIdWithName(userList, filteredEntrySet);
266
267 writeChangeLog(filteredEntrySet);
268
269 } finally {
270 m_dir = savedDir;
271 }
272 }
273
274 /**
275 * Validate the parameters specified for task.
276 *
277 * @throws BuildException if fails validation checks
278 */
279 private void validate()
280 throws BuildException {
281 if (null == m_dir) {
282 m_dir = getProject().getBaseDir();
283 }
284 if (null == m_destfile) {
285 final String message = "Destfile must be set.";
286
287 throw new BuildException(message);
288 }
289 if (!m_dir.exists()) {
290 final String message = "Cannot find base dir "
291 + m_dir.getAbsolutePath();
292
293 throw new BuildException(message);
294 }
295 if (null != m_usersFile && !m_usersFile.exists()) {
296 final String message = "Cannot find user lookup list "
297 + m_usersFile.getAbsolutePath();
298
299 throw new BuildException(message);
300 }
301 }
302
303 /**
304 * Load the userlist from the userList file (if specified) and add to
305 * list of users.
306 *
307 * @param userList the file of users
308 * @throws BuildException if file can not be loaded for some reason
309 */
310 private void loadUserlist(final Properties userList)
311 throws BuildException {
312 if (null != m_usersFile) {
313 try {
314 userList.load(new FileInputStream(m_usersFile));
315 } catch (final IOException ioe) {
316 throw new BuildException(ioe.toString(), ioe);
317 }
318 }
319 }
320
321 /**
322 * Filter the specified entries according to an appropriate rule.
323 *
324 * @param entrySet the entry set to filter
325 * @return the filtered entry set
326 */
327 private CVSEntry[] filterEntrySet(final CVSEntry[] entrySet) {
328 final Vector results = new Vector();
329
330 for (int i = 0; i < entrySet.length; i++) {
331 final CVSEntry cvsEntry = entrySet[i];
332 final Date date = cvsEntry.getDate();
333
334 if (null != m_start && m_start.after(date)) {
335 //Skip dates that are too early
336 continue;
337 }
338 if (null != m_stop && m_stop.before(date)) {
339 //Skip dates that are too late
340 continue;
341 }
342 results.addElement(cvsEntry);
343 }
344
345 final CVSEntry[] resultArray = new CVSEntry[results.size()];
346
347 results.copyInto(resultArray);
348 return resultArray;
349 }
350
351 /**
352 * replace all known author's id's with their maven specified names
353 */
354 private void replaceAuthorIdWithName(final Properties userList,
355 final CVSEntry[] entrySet) {
356 for (int i = 0; i < entrySet.length; i++) {
357
358 final CVSEntry entry = entrySet[ i ];
359 if (userList.containsKey(entry.getAuthor())) {
360 entry.setAuthor(userList.getProperty(entry.getAuthor()));
361 }
362 }
363 }
364
365 /**
366 * Print changelog to file specified in task.
367 *
368 * @param entrySet the entry set to write.
369 * @throws BuildException if there is an error writing changelog.
370 */
371 private void writeChangeLog(final CVSEntry[] entrySet)
372 throws BuildException {
373 FileOutputStream output = null;
374
375 try {
376 output = new FileOutputStream(m_destfile);
377
378 final PrintWriter writer =
379 new PrintWriter(new OutputStreamWriter(output, "UTF-8"));
380
381 final ChangeLogWriter serializer = new ChangeLogWriter();
382
383 serializer.printChangeLog(writer, entrySet);
384 } catch (final UnsupportedEncodingException uee) {
385 getProject().log(uee.toString(), Project.MSG_ERR);
386 } catch (final IOException ioe) {
387 throw new BuildException(ioe.toString(), ioe);
388 } finally {
389 if (null != output) {
390 try {
391 output.close();
392 } catch (final IOException ioe) {
393 }
394 }
395 }
396 }
397}
398
Note: See TracBrowser for help on using the repository browser.