1 /*
2 AntMake
3
4 Copyright (C) 2003 Jose San Leandro Armend?riz
5 jsanleandro@yahoo.es
6 chousz@yahoo.com
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 Thanks to ACM S.L. for distributing this library under the GPL license.
23 Contact info: jsr000@terra.es
24 Postal Address: c/Playa de Lagoa, 1
25 Urb. Valdecaba?as
26 Boadilla del monte
27 28660 Madrid
28 Spain
29
30 ******************************************************************************
31 This class is a customization of CvsChangeLogTask
32 included in Ant distribution, and whose license details
33 are the following.
34
35 *
36 * The Apache Software License, Version 1.1
37 *
38 * Copyright (c) 2002 The Apache Software Foundation. All rights
39 * reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 *
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 *
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in
50 * the documentation and/or other materials provided with the
51 * distribution.
52 *
53 * 3. The end-user documentation included with the redistribution, if
54 * any, must include the following acknowlegement:
55 * "This product includes software developed by the
56 * Apache Software Foundation (http://www.apache.org/)."
57 * Alternately, this acknowlegement may appear in the software itself,
58 * if and wherever such third-party acknowlegements normally appear.
59 *
60 * 4. The names "Ant" and "Apache Software
61 * Foundation" must not be used to endorse or promote products derived
62 * from this software without prior written permission. For written
63 * permission, please contact apache@apache.org.
64 *
65 * 5. Products derived from this software may not be called "Apache"
66 * nor may "Apache" appear in their names without prior written
67 * permission of the Apache Group.
68 *
69 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
70 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
71 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
73 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
74 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
75 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
76 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
78 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
79 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80 * SUCH DAMAGE.
81 * ====================================================================
82 *
83 * This software consists of voluntary contributions made by many
84 * individuals on behalf of the Apache Software Foundation. For more
85 * information on the Apache Software Foundation, please see
86 * <http://www.apache.org/>.
87 *
88
89 ******************************************************************************
90 *
91 * Filename: $RCSfile: AntMakeTask.java,v $
92 *
93 * Author: Jose San Leandro Armend?riz
94 *
95 * Description: Provides helpful methods for interacting with CVS servers
96 * through its command-line client.
97 *
98 * Last modified by: $Author: chous $ at $Date: 2004/01/24 11:17:06 $
99 *
100 * File version: $Revision: 1.8 $
101 *
102 * Project version: $Name: $
103 *
104 * $Id: AntMakeTask.java,v 1.8 2004/01/24 11:17:06 chous Exp $
105 *
106 */
107 package org.acmsl.antmake;
108
109 /*
110 * Importing project classes.
111 */
112 import org.acmsl.antmake.ChangeLogParser;
113 import org.acmsl.antmake.CvsEntry;
114 import org.acmsl.antmake.RcsFile;
115 import org.acmsl.antmake.RedirectingStreamHandler;
116
117 /*
118 * Importing some Ant classes.
119 */
120 import org.apache.tools.ant.BuildException;
121 import org.apache.tools.ant.DirectoryScanner;
122 import org.apache.tools.ant.Project;
123 import org.apache.tools.ant.Task;
124 import org.apache.tools.ant.taskdefs.Execute;
125 import org.apache.tools.ant.types.Commandline;
126 import org.apache.tools.ant.types.FileSet;
127
128 /*
129 * Importing some JDK classes.
130 */
131 import java.io.File;
132 import java.io.FileInputStream;
133 import java.io.FileOutputStream;
134 import java.io.IOException;
135 import java.io.OutputStreamWriter;
136 import java.io.PrintWriter;
137 import java.io.UnsupportedEncodingException;
138 import java.lang.ref.WeakReference;
139 import java.text.DateFormat;
140 import java.text.SimpleDateFormat;
141 import java.util.ArrayList;
142 import java.util.Arrays;
143 import java.util.Collection;
144 import java.util.Collections;
145 import java.util.Comparator;
146 import java.util.Date;
147 import java.util.Iterator;
148 import java.util.List;
149 import java.util.Properties;
150
151 /***
152 * Provides helpful methods for interacting with CVS servers
153 * through its command-line client.
154 * @author <a href="mailto:jsanleandro@yahoo.es"
155 >Jose San Leandro</a>, based on
156 * <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> and
157 * <a href="mailto:peter@apache.org">Peter Donald</a>'s
158 * CvsChangeLogTask.
159 * @version $Revision: 1.8 $
160 */
161 public class CvsUtils
162 {
163 /***
164 * The date comparator to sort the CVS entries.
165 */
166 public static final Comparator DATE_COMPARATOR =
167 new DateComparator();
168
169 /***
170 * The date format.
171 */
172 public static final DateFormat DATE_FORMAT =
173 new SimpleDateFormat("yyyy-MM-dd");
174
175 /***
176 * Singleton implemented as a weak reference.
177 */
178 private static WeakReference m__Singleton;
179
180 /***
181 * Specifies a new weak reference.
182 * @param utils the utils instance to use.
183 */
184 protected static void setReference(CvsUtils utils)
185 {
186 m__Singleton = new WeakReference(utils);
187 }
188
189 /***
190 * Retrieves the weak reference.
191 * @return such reference.
192 */
193 protected static WeakReference getReference()
194 {
195 return m__Singleton;
196 }
197
198 /***
199 * Retrieves a CvsUtils instance.
200 * @return such instance.
201 */
202 public static CvsUtils getInstance()
203 {
204 CvsUtils result = null;
205
206 WeakReference reference = getReference();
207
208 if (reference != null)
209 {
210 result = (CvsUtils) reference.get();
211 }
212
213 if (result == null)
214 {
215 result = new CvsUtils() {};
216
217 setReference(result);
218 }
219
220 return result;
221 }
222
223 /***
224 * Protected constructor to avoid accidental instantiation.
225 */
226 protected CvsUtils() {};
227
228 /***
229 * Generates a GNU-formatted ChangeLog file.
230 * @param workingDirectory the working directory.
231 * @param output the output file.
232 * @param files the files to record changes for.
233 * @param task an Ant task (for logging, and required by Execute).
234 * @throws AntMakeException if something goes wrong while
235 * executing the cvs command.
236 */
237 public void generateChangeLog(
238 File workingDirectory, String output, String[] files, Task task)
239 throws AntMakeException
240 {
241 if ( (workingDirectory != null)
242 && (output != null)
243 && (files != null)
244 && (task != null))
245 {
246 AntMakeUtils t_AntMakeUtils = AntMakeUtils.getInstance();
247
248 System.out.println("working directory:" + workingDirectory.getAbsolutePath());
249
250 Commandline t_Command = new Commandline();
251
252 t_Command.setExecutable("cvs");
253 t_Command.createArgument().setValue("log");
254
255 /*
256 for (int t_iFileIndex = 0;
257 t_iFileIndex < files.length;
258 t_iFileIndex++)
259 {
260 t_Command.createArgument().setValue(
261 files[t_iFileIndex]);
262 }
263 */
264
265 ChangeLogParser t_Parser = new ChangeLogParser();
266
267 RedirectingStreamHandler t_Handler =
268 new RedirectingStreamHandler(t_Parser);
269
270 t_AntMakeUtils.log(
271 task, t_Command.describeCommand(), Project.MSG_VERBOSE);
272
273 Execute t_Execute = new Execute(t_Handler);
274
275 t_Execute.setWorkingDirectory(workingDirectory);
276
277 t_Execute.setCommandline(t_Command.getCommandline());
278
279 t_Execute.setAntRun(task.getProject());
280
281 try
282 {
283 int t_iResultCode = t_Execute.execute();
284
285 if (t_iResultCode == -1)
286 {
287 throw new AntMakeException("Error running cvs log");
288 }
289 }
290 catch (IOException ioException)
291 {
292 t_AntMakeUtils.log(
293 task, ioException.getMessage(), Project.MSG_VERBOSE);
294
295 throw new AntMakeException(
296 "Error running cvs log", ioException);
297 }
298
299 String t_strErrors = t_Handler.getErrors();
300
301 if (t_strErrors != null)
302 {
303 System.out.println("Error: " + t_strErrors);
304
305 t_AntMakeUtils.log(
306 task, t_strErrors, Project.MSG_ERR);
307 }
308
309 CvsEntry[] t_aEntrySet = t_Parser.getEntrySetAsArray();
310
311 writeChangeLog(output, t_aEntrySet, t_AntMakeUtils, task);
312 }
313 }
314
315 /***
316 * Prints changelog to given output file.
317 * @param output the output file.
318 * @param cvsEntries the entry set to write.
319 * @throws AntMakeException if theres an error writing changelog.
320 */
321 public void writeChangeLog(
322 String output,
323 CvsEntry[] cvsEntries,
324 AntMakeUtils antMakeUtils,
325 Task task)
326 throws AntMakeException
327 {
328 if ( (output != null)
329 && (cvsEntries != null))
330 {
331 Exception t_Exception = null;
332
333 FileOutputStream t_fosOutput = null;
334
335 try
336 {
337 System.out.println("Parsing cvs log output");
338
339 t_fosOutput = new FileOutputStream(output);
340
341 PrintWriter t_pwWriter =
342 new PrintWriter(
343 new OutputStreamWriter(t_fosOutput, "UTF-8"));
344
345 cvsEntries = sortByDate(cvsEntries);
346
347 writeChangeLog(t_pwWriter, cvsEntries);
348 }
349 catch (UnsupportedEncodingException unsupportedEncodingException)
350 {
351 if (antMakeUtils != null)
352 {
353 antMakeUtils.log(
354 task, unsupportedEncodingException.getMessage(), Project.MSG_ERR);
355 }
356
357 t_Exception = unsupportedEncodingException;
358 }
359 catch (IOException ioException)
360 {
361 if (antMakeUtils != null)
362 {
363 antMakeUtils.log(
364 task, ioException.getMessage(), Project.MSG_VERBOSE);
365 }
366
367 if (t_Exception == null)
368 {
369 t_Exception = ioException;
370 }
371 }
372 finally
373 {
374 if (t_fosOutput != null)
375 {
376 try
377 {
378 t_fosOutput.close();
379 }
380 catch (IOException ioException)
381 {
382 if (antMakeUtils != null)
383 {
384 antMakeUtils.log(
385 task,
386 ioException.getMessage(),
387 Project.MSG_VERBOSE);
388 }
389
390 if (t_Exception == null)
391 {
392 t_Exception = ioException;
393 }
394 }
395 }
396
397 if (t_Exception != null)
398 {
399 throw new AntMakeException(
400 "Error writing ChangeLog file", t_Exception);
401 }
402 }
403 }
404 }
405
406 /***
407 * Sorts given CVS entries by date.
408 * @param cvsEntries the CVS entries to sort.
409 * @return the sorted collection.
410 */
411 public CvsEntry[] sortByDate(CvsEntry[] cvsEntries)
412 {
413 List t_lResult = new ArrayList();
414
415 if (cvsEntries != null)
416 {
417 t_lResult = Arrays.asList(cvsEntries);
418
419 Collections.sort(t_lResult, DATE_COMPARATOR);
420 }
421
422 return (CvsEntry[]) t_lResult.toArray(cvsEntries);
423 }
424
425 /***
426 * Writes the changelog.
427 * @param printWriter the printWriter.
428 * @param cvsEntries the CVS entries.
429 * @throws IOException if the write operation fails.
430 */
431 public void writeChangeLog(PrintWriter printWriter, CvsEntry[] cvsEntries)
432 throws IOException
433 {
434 if ( (printWriter != null)
435 && (cvsEntries != null))
436 {
437 for (int t_iEntryIndex = 0;
438 t_iEntryIndex < cvsEntries.length;
439 t_iEntryIndex++)
440 {
441 writeChangeLog(printWriter, cvsEntries[t_iEntryIndex]);
442 }
443 }
444 }
445
446 /***
447 * Writes a changelog entry.
448 * @param printWriter the printWriter.
449 * @param cvsEntry the CVS entry.
450 * @throws IOException if the write operation fails.
451 */
452 public void writeChangeLog(PrintWriter printWriter, CvsEntry cvsEntry)
453 throws IOException
454 {
455 if ( (printWriter != null)
456 && (cvsEntry != null))
457 {
458 printWriter.println(
459 DATE_FORMAT.format(cvsEntry.getDate())
460 + " "
461 + cvsEntry.getAuthor());
462 printWriter.println();
463
464 Collection t_cRcsFiles = cvsEntry.getRcsFiles();
465
466 if (t_cRcsFiles != null)
467 {
468 Iterator t_FileIterator =
469 t_cRcsFiles.iterator();
470
471 while ( (t_FileIterator != null)
472 && (t_FileIterator.hasNext()))
473 {
474 writeChangeLog(
475 printWriter,
476 (RcsFile) t_FileIterator.next());
477 }
478 }
479 }
480 }
481
482 /***
483 * Writes the CVS log message for given RCS file.
484 * @param printWriter the print writer.
485 * @param rcsFile the RCS file.
486 * @throws IOException if the write operation fails.
487 */
488 public void writeChangeLog(PrintWriter printWriter, RcsFile rcsFile)
489 throws IOException
490 {
491 if ( (printWriter != null)
492 && (rcsFile != null))
493 {
494 printWriter.println(
495 "\t* "
496 + rcsFile.getName());
497 }
498 }
499
500 /***
501 * Sorts CVS entries by date.
502 * @author <a href="mailto:jsanleandro@yahoo.es"
503 >Jose San Leandro</a>
504 * @version $Revision: $
505 */
506 public static class DateComparator
507 implements Comparator
508 {
509 /***
510 * Compares its two arguments for order.
511 * @param first the first entry.
512 * @param second the second entry.
513 * @return a negative integer, zero, or a positive integer
514 * as the first argument is less than, equal to, or greater
515 * than the second.
516 * @throws ClassCastException if the arguments' types prevent
517 * them from being compared by this Comparator.
518 */
519 public int compare(Object first, Object second)
520 throws ClassCastException
521 {
522 return compare((CvsEntry) first, (CvsEntry) second);
523 }
524
525 /***
526 * Compares given CVS entries by their date.
527 * @param first the first entry.
528 * @param second the second entry.
529 * @return a negative integer or a positive integer
530 * depending on whether the first entry is before or after
531 * the second.
532 */
533 public int compare(CvsEntry first, CvsEntry second)
534 {
535 int result = 0;
536
537 if ( (first != null)
538 && (first.getDate() != null))
539 {
540 if ( (second != null)
541 && (second.getDate() != null)
542 && (second.getDate().after(first.getDate())))
543 {
544 result = -1;
545 }
546 else
547 {
548 result = 1;
549 }
550 }
551 else if ( (second != null)
552 && (second.getDate() != null))
553 {
554 result = -1;
555 }
556
557 return result;
558 }
559
560 /***
561 * Checks if given comparator is semantically equal to this
562 * instance.
563 * @param comparator the comparator to check against.
564 * @return <code>true</code> if both instances are semantically
565 * equal.
566 */
567 public boolean equals(Object comparator)
568 {
569 boolean result = false;
570
571 if ( (comparator != null)
572 && (comparator instanceof DateComparator))
573 {
574 result = true;
575 }
576
577 return result;
578 }
579 }
580 }
581
This page was automatically generated by Maven