View Javadoc
1 /* 2 AntMake 3 4 Copyright (C) 2004 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: CvsUtils.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/31 18:18:58 $ 99 * 100 * File version: $Revision: 1.5 $ 101 * 102 * Project version: $Name: $ 103 * 104 * $Id: CvsUtils.java,v 1.5 2004/01/31 18:18:58 chous Exp $ 105 * 106 */ 107 package org.acmsl.antmake.cvslib; 108 109 /* 110 * Importing project classes. 111 */ 112 import org.acmsl.antmake.AntMakeException; 113 import org.acmsl.antmake.AntMakeUtils; 114 import org.acmsl.antmake.cvslib.ChangeLogParser; 115 import org.acmsl.antmake.cvslib.CvsEntry; 116 import org.acmsl.antmake.cvslib.RcsFile; 117 import org.acmsl.antmake.cvslib.RedirectingStreamHandler; 118 119 /* 120 * Importing ACM-SL Commons classes. 121 */ 122 import org.acmsl.commons.utils.StringUtils; 123 124 /* 125 * Importing some Ant classes. 126 */ 127 import org.apache.tools.ant.BuildException; 128 import org.apache.tools.ant.DirectoryScanner; 129 import org.apache.tools.ant.Project; 130 import org.apache.tools.ant.Task; 131 import org.apache.tools.ant.taskdefs.Execute; 132 import org.apache.tools.ant.types.Commandline; 133 import org.apache.tools.ant.types.FileSet; 134 135 /* 136 * Importing some JDK classes. 137 */ 138 import java.io.BufferedWriter; 139 import java.io.File; 140 import java.io.FileInputStream; 141 import java.io.FileOutputStream; 142 import java.io.IOException; 143 import java.io.OutputStreamWriter; 144 import java.io.PrintWriter; 145 import java.io.UnsupportedEncodingException; 146 import java.lang.ref.WeakReference; 147 import java.text.DateFormat; 148 import java.text.SimpleDateFormat; 149 import java.util.ArrayList; 150 import java.util.Arrays; 151 import java.util.Collection; 152 import java.util.Collections; 153 import java.util.Comparator; 154 import java.util.Date; 155 import java.util.Iterator; 156 import java.util.List; 157 import java.util.Properties; 158 159 /*** 160 * Provides helpful methods for interacting with CVS servers 161 * through its command-line client. 162 * @author <a href="mailto:jsanleandro@yahoo.es" 163 >Jose San Leandro</a>, based on 164 * <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> and 165 * <a href="mailto:peter@apache.org">Peter Donald</a>'s 166 * CvsChangeLogTask. 167 * @version $Revision: 1.5 $ 168 */ 169 public class CvsUtils 170 { 171 /*** 172 * The margin. 173 */ 174 public static final int MARGIN = 71; 175 176 /*** 177 * The date comparator to sort the CVS entries. 178 */ 179 public static final Comparator DATE_COMPARATOR = 180 new DateComparator(); 181 182 /*** 183 * The date format. 184 */ 185 public static final DateFormat DATE_FORMAT = 186 new SimpleDateFormat("yyyy-MM-dd"); 187 188 /*** 189 * Singleton implemented as a weak reference. 190 */ 191 private static WeakReference m__Singleton; 192 193 /*** 194 * Specifies a new weak reference. 195 * @param utils the utils instance to use. 196 */ 197 protected static void setReference(CvsUtils utils) 198 { 199 m__Singleton = new WeakReference(utils); 200 } 201 202 /*** 203 * Retrieves the weak reference. 204 * @return such reference. 205 */ 206 protected static WeakReference getReference() 207 { 208 return m__Singleton; 209 } 210 211 /*** 212 * Retrieves a CvsUtils instance. 213 * @return such instance. 214 */ 215 public static CvsUtils getInstance() 216 { 217 CvsUtils result = null; 218 219 WeakReference reference = getReference(); 220 221 if (reference != null) 222 { 223 result = (CvsUtils) reference.get(); 224 } 225 226 if (result == null) 227 { 228 result = new CvsUtils() {}; 229 230 setReference(result); 231 } 232 233 return result; 234 } 235 236 /*** 237 * Protected constructor to avoid accidental instantiation. 238 */ 239 protected CvsUtils() {}; 240 241 /*** 242 * Generates a GNU-formatted ChangeLog file. 243 * @param workingDirectory the working directory. 244 * @param output the output file. 245 * @param task an Ant task (for logging, and required by Execute). 246 * @throws AntMakeException if something goes wrong while 247 * executing the cvs command. 248 */ 249 public void generateChangeLog( 250 File workingDirectory, String output, Task task) 251 throws AntMakeException 252 { 253 if ( (workingDirectory != null) 254 && (output != null) 255 && (task != null)) 256 { 257 AntMakeUtils t_AntMakeUtils = AntMakeUtils.getInstance(); 258 259 Commandline t_Command = new Commandline(); 260 261 t_Command.setExecutable("cvs"); 262 t_Command.createArgument().setValue("log"); 263 264 ChangeLogParser t_Parser = new ChangeLogParser(); 265 266 RedirectingStreamHandler t_Handler = 267 new RedirectingStreamHandler(t_Parser); 268 269 t_AntMakeUtils.log( 270 task, t_Command.describeCommand(), Project.MSG_VERBOSE); 271 272 Execute t_Execute = new Execute(t_Handler); 273 274 t_Execute.setWorkingDirectory(workingDirectory); 275 276 t_Execute.setCommandline(t_Command.getCommandline()); 277 278 t_Execute.setAntRun(task.getProject()); 279 280 try 281 { 282 int t_iResultCode = t_Execute.execute(); 283 284 if (t_iResultCode == -1) 285 { 286 throw new AntMakeException("Error running cvs log"); 287 } 288 } 289 catch (IOException ioException) 290 { 291 t_AntMakeUtils.log( 292 task, ioException.getMessage(), Project.MSG_VERBOSE); 293 294 throw new AntMakeException( 295 "Error running cvs log", ioException); 296 } 297 298 String t_strErrors = t_Handler.getErrors(); 299 300 if (t_strErrors != null) 301 { 302 t_AntMakeUtils.log( 303 task, t_strErrors, Project.MSG_ERR); 304 } 305 306 CvsEntry[] t_aEntrySet = t_Parser.getEntrySetAsArray(); 307 308 writeChangeLog(output, t_aEntrySet, t_AntMakeUtils, task); 309 } 310 } 311 312 /*** 313 * Prints changelog to given output file. 314 * @param output the output file. 315 * @param cvsEntries the entry set to write. 316 * @throws AntMakeException if theres an error writing changelog. 317 */ 318 public void writeChangeLog( 319 String output, 320 CvsEntry[] cvsEntries, 321 AntMakeUtils antMakeUtils, 322 Task task) 323 throws AntMakeException 324 { 325 if ( (output != null) 326 && (cvsEntries != null)) 327 { 328 Exception t_Exception = null; 329 330 FileOutputStream t_fosOutput = null; 331 332 try 333 { 334 t_fosOutput = new FileOutputStream(output); 335 336 PrintWriter t_pwWriter = 337 new PrintWriter( 338 new BufferedWriter( 339 new OutputStreamWriter(t_fosOutput, "UTF-8"))); 340 341 cvsEntries = sortByDate(cvsEntries); 342 343 writeChangeLog(t_pwWriter, cvsEntries); 344 } 345 catch (UnsupportedEncodingException unsupportedEncodingException) 346 { 347 if (antMakeUtils != null) 348 { 349 antMakeUtils.log( 350 task, unsupportedEncodingException.getMessage(), Project.MSG_ERR); 351 } 352 353 t_Exception = unsupportedEncodingException; 354 } 355 catch (IOException ioException) 356 { 357 if (antMakeUtils != null) 358 { 359 antMakeUtils.log( 360 task, ioException.getMessage(), Project.MSG_VERBOSE); 361 } 362 363 if (t_Exception == null) 364 { 365 t_Exception = ioException; 366 } 367 } 368 finally 369 { 370 if (t_fosOutput != null) 371 { 372 try 373 { 374 t_fosOutput.close(); 375 } 376 catch (IOException ioException) 377 { 378 if (antMakeUtils != null) 379 { 380 antMakeUtils.log( 381 task, 382 ioException.getMessage(), 383 Project.MSG_VERBOSE); 384 } 385 386 if (t_Exception == null) 387 { 388 t_Exception = ioException; 389 } 390 } 391 } 392 393 if (t_Exception != null) 394 { 395 throw new AntMakeException( 396 "Error writing ChangeLog file", t_Exception); 397 } 398 } 399 } 400 } 401 402 /*** 403 * Sorts given CVS entries by date. 404 * @param cvsEntries the CVS entries to sort. 405 * @return the sorted collection. 406 */ 407 public CvsEntry[] sortByDate(CvsEntry[] cvsEntries) 408 { 409 List t_lResult = new ArrayList(); 410 411 if (cvsEntries != null) 412 { 413 t_lResult = Arrays.asList(cvsEntries); 414 415 Collections.sort(t_lResult, DATE_COMPARATOR); 416 } 417 418 return (CvsEntry[]) t_lResult.toArray(cvsEntries); 419 } 420 421 /*** 422 * Writes the changelog. 423 * @param printWriter the printWriter. 424 * @param cvsEntries the CVS entries. 425 * @throws IOException if the write operation fails. 426 */ 427 public void writeChangeLog(PrintWriter printWriter, CvsEntry[] cvsEntries) 428 throws IOException 429 { 430 if ( (printWriter != null) 431 && (cvsEntries != null)) 432 { 433 for (int t_iEntryIndex = 0; 434 t_iEntryIndex < cvsEntries.length; 435 t_iEntryIndex++) 436 { 437 writeChangeLog(printWriter, cvsEntries[t_iEntryIndex]); 438 printWriter.flush(); 439 } 440 } 441 } 442 443 /*** 444 * Writes a changelog entry. 445 * @param printWriter the printWriter. 446 * @param cvsEntry the CVS entry. 447 * @throws IOException if the write operation fails. 448 */ 449 public void writeChangeLog(PrintWriter printWriter, CvsEntry cvsEntry) 450 throws IOException 451 { 452 if ( (printWriter != null) 453 && (cvsEntry != null)) 454 { 455 printWriter.println( 456 DATE_FORMAT.format(cvsEntry.getDate()) 457 + " " 458 + cvsEntry.getAuthor()); 459 460 Collection t_cRcsFiles = cvsEntry.getRcsFiles(); 461 462 if (t_cRcsFiles != null) 463 { 464 String t_strLastFile = ""; 465 466 Iterator t_FileIterator = 467 t_cRcsFiles.iterator(); 468 469 while ( (t_FileIterator != null) 470 && (t_FileIterator.hasNext())) 471 { 472 t_strLastFile = 473 "\n\t* " 474 + ((RcsFile) t_FileIterator.next()).getName(); 475 476 if (t_FileIterator.hasNext()) 477 { 478 write( 479 printWriter, t_strLastFile); 480 } 481 } 482 483 write( 484 printWriter, 485 "\n\t" // Added since StringUtils removes them, 486 // but they're still needed for the margin 487 // calculation 488 + StringUtils.getInstance().justify( 489 "\n\t" 490 + t_strLastFile 491 + ": " 492 + cvsEntry.getComment(), 493 "\t", 494 MARGIN)); 495 496 printWriter.println(); 497 printWriter.println(); 498 } 499 } 500 } 501 502 /*** 503 * Writes the CVS log message. 504 * @param printWriter the print writer. 505 * @param content the content to write. 506 * @throws IOException if the write operation fails. 507 */ 508 public void write(PrintWriter printWriter, String content) 509 throws IOException 510 { 511 if ( (printWriter != null) 512 && (content != null)) 513 { 514 printWriter.print(content); 515 } 516 } 517 518 /*** 519 * Sorts CVS entries by date. 520 * @author <a href="mailto:jsanleandro@yahoo.es" 521 >Jose San Leandro</a> 522 * @version $Revision: 1.5 $ 523 */ 524 public static class DateComparator 525 implements Comparator 526 { 527 /*** 528 * Compares its two arguments for order. 529 * @param first the first entry. 530 * @param second the second entry. 531 * @return a negative integer, zero, or a positive integer 532 * as the first argument is less than, equal to, or greater 533 * than the second. 534 * @throws ClassCastException if the arguments' types prevent 535 * them from being compared by this Comparator. 536 */ 537 public int compare(Object first, Object second) 538 throws ClassCastException 539 { 540 return compare((CvsEntry) first, (CvsEntry) second); 541 } 542 543 /*** 544 * Compares given CVS entries by their date. 545 * @param first the first entry. 546 * @param second the second entry. 547 * @return a negative integer or a positive integer 548 * depending on whether the first entry is before or after 549 * the second. 550 */ 551 public int compare(CvsEntry first, CvsEntry second) 552 { 553 int result = 0; 554 555 if ( (first != null) 556 && (first.getDate() != null)) 557 { 558 if ( (second != null) 559 && (second.getDate() != null) 560 && (second.getDate().after(first.getDate()))) 561 { 562 result = 1; 563 } 564 else 565 { 566 result = -1; 567 } 568 } 569 else if ( (second != null) 570 && (second.getDate() != null)) 571 { 572 result = 1; 573 } 574 575 return result; 576 } 577 578 /*** 579 * Checks if given comparator is semantically equal to this 580 * instance. 581 * @param comparator the comparator to check against. 582 * @return <code>true</code> if both instances are semantically 583 * equal. 584 */ 585 public boolean equals(Object comparator) 586 { 587 boolean result = false; 588 589 if ( (comparator != null) 590 && (comparator instanceof DateComparator)) 591 { 592 result = true; 593 } 594 595 return result; 596 } 597 } 598 } 599

This page was automatically generated by Maven