kaz         02/04/30 08:33:15

  Added:       src/java/org/apache/maven/cvslib CvsChangeLogGenerator.java
                        CvsChangeLogParser.java
  Log:
  Adding missing files from glenn's patch.
  
  Revision  Changes    Path
  1.1                  
jakarta-turbine-maven/src/java/org/apache/maven/cvslib/CvsChangeLogGenerator.java
  
  Index: CvsChangeLogGenerator.java
  ===================================================================
  package org.apache.maven.cvslib;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Maven" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Maven", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  import java.util.Collection;
  import java.util.Date;
  import java.text.SimpleDateFormat;
  
  // maven imports
  import org.apache.maven.changelog.ChangeLog;
  import org.apache.maven.changelog.ChangeLogGenerator;
  import org.apache.maven.changelog.ChangeLogParser;
  import org.apache.maven.util.AsyncStreamReader;
  
  // ant imports
  import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
  import org.apache.tools.ant.taskdefs.Execute;
  import org.apache.tools.ant.types.Commandline;
  
  /**
   * A CVS implementation of the {@link org.apache.maven.changelog.ChangeLog}
   * interface.
   *
   * @todo Check CVS exists first by running cvs -version instead of current hack
   * @author Glenn McAllister
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jeff Martin</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jason van Zyl</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>dIon Gillard</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Stefan Bodewig</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Id: CvsChangeLogGenerator.java,v 1.1 2002/04/30 15:33:15 kaz Exp $
   */
  public class CvsChangeLogGenerator 
  implements ChangeLogGenerator, ExecuteStreamHandler
  {
      /** 
       * Reference to the enclosing ChangeLog instance - used to obtain any
       * necessary configuration information. 
       * */
      private ChangeLog changeLogExecutor;
      
      /** 
       * stderr stream eater 
       * */
      private AsyncStreamReader errorReader;
  
      /** 
       * The cvs process input stream. 
       * */
      private InputStream in;
  
      /** 
       * The working directory for cvs. 
       * */
      private File base;
  
      /**
       * The CVS date range.
       */
      private String dateRange;
  
      /**
       * The parser that takes the cvs log output and transforms it into a
       * collection of ChangeLogEntry's.
       */
      private ChangeLogParser clParser;
  
      /**
       * The collection of ChangeLogEntry's returned from clParser.
       */
      private Collection entries;
  
      // doc comment inherited from interface
      public void init( ChangeLog changeLog )
      {
          changeLogExecutor = changeLog;
          
          base = changeLogExecutor.getBasedir();
  
          if (changeLogExecutor.getRange() != null)
          {
              setDateRange( changeLogExecutor.getRange() );
          }
   
      }
  
      /**
       * Set the dateRange member based on the number of days obtained from the
       * ChangeLog.
       */
      private void setDateRange( String numDaysString )
      {
          int days = Integer.parseInt( numDaysString );
  
          Date before = new Date(
              System.currentTimeMillis() - (long) days * 24 * 60 * 60 * 1000);
          Date to = new Date(
              System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000);
  
          SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd");
          // We want something of the form: -d ">=YYYY-MM-dd"
          dateRange = "-d " + outputDate.format(before) + "<" + 
              outputDate.format(to);
  
      }
  
      // doc comment inherited from ChangeLogGenerator interface
      public Collection getEntries( ChangeLogParser parser ) throws IOException
      {
          if (parser == null)
          {
              throw new NullPointerException("parser cannot be null");
          }
  
          if (base == null)
          {
              throw new NullPointerException("basedir must be set");
          }
  
          if (!base.exists())
          {
              throw new FileNotFoundException(
                  "Cannot find base dir " + base.getAbsolutePath());
          }
  
          clParser = parser;
          try 
          {
              Execute exe = new Execute(this);
              exe.setCommandline(getCvsLogCommand().getCommandline());
              exe.setAntRun(changeLogExecutor.getProject());
              exe.setWorkingDirectory(base);
              exe.execute();
  
  
              // log messages from stderr
              String errors = errorReader.toString().trim();
              if (errors.length() > 0)
              {
                  changeLogExecutor.log(errors);
              }
          }
          catch (IOException ioe)
          {
              if (ioe.getMessage().indexOf("CreateProcess")  != -1 ||
                  ioe.getMessage().indexOf("cvs: not found") != -1) 
              {
                  // can't find CVS on Win32 or Linux...
                  changeLogExecutor.log(
                      "Unable to find cvs executable. Changelog will be empty");
              }
              else
              {
                  throw ioe;
              }
          }
  
          return entries;
      }
  
      // doc comment inherited from interface - nothing to do
      public void cleanup()
      {
      }
  
      /**
       * @return the cvs command line to be executed.
       */
      private Commandline getCvsLogCommand() 
      {
          Commandline command = new Commandline();
  
          command.setExecutable("cvs");
          command.createArgument().setValue("log");
  
          if (dateRange != null)
          {
              command.createArgument().setValue(dateRange);
          }
          
          return command;
      }
  
  
      /**
       * Stop the process - currently unimplemented
       */
      public void stop()
      {
      }
  
      /**
       * Set the input stream for the cvs process. cvs requires no input so this
       * is not used.
       * @param os - an {@link java.io.OutputStream}
       */
      public void setProcessInputStream(OutputStream os)
      {
      }
  
      /**
       * Set the error stream for reading from cvs log. This stream will be read
       * on a separate thread.
       * @param is - an {@link java.io.InputStream}
       */
      public void setProcessErrorStream(InputStream is)
      {
          errorReader = new AsyncStreamReader(is);
      }
  
      /**
       * Set the input stream used to read from cvs log
       * @param is - a stream of cvs log output to be read from
       */
      public void setProcessOutputStream(InputStream is)
      {
          in = is;
      }
  
      /**
       * Start read from the cvs log.
       * @throws IOException when there are errors reading from the streams
       *      previously provided
       */
      public void start() throws IOException
      {
          errorReader.start();
          entries = clParser.parse(in);
      }
  
  
  }
  
  
  
  1.1                  
jakarta-turbine-maven/src/java/org/apache/maven/cvslib/CvsChangeLogParser.java
  
  Index: CvsChangeLogParser.java
  ===================================================================
  package org.apache.maven.cvslib;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Maven" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Maven", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.BufferedReader;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.IOException;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Map;
  import java.util.StringTokenizer;
  import java.util.TreeMap;
  
  import org.apache.maven.changelog.ChangeLog;
  import org.apache.maven.changelog.ChangeLogParser;
  import org.apache.maven.changelog.ChangeLogEntry;
  import org.apache.maven.changelog.ChangeLogFile;
  
  /**
   * A class to parse cvs log output
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>dIon Gillard</a>
   * @version $Id: CvsChangeLogParser.java,v 1.1 2002/04/30 15:33:15 kaz Exp $
   */
  public class CvsChangeLogParser implements ChangeLogParser
  {
      
      /**
       * rcs entries, in reverse (date, time, author, comment) order
       */
      private Map entries = new TreeMap(Collections.reverseOrder());
  
      // state machine constants for reading cvs output
      /** expecting file information */
      private static final int GET_FILE = 1;
      /** expecting date */
      private static final int GET_DATE = 2;
      /** expecting comments */
      private static final int GET_COMMENT = 3;
      /** expecting revision */
      private static final int GET_REVISION = 4;
      /** Marks start of file data*/
      private static final String START_FILE = "Working file: ";
      /** Marks end of file */
      private static final String END_FILE = "==================================="
          + "==========================================";
      /** Marks start of revision */
      private static final String START_REVISION = "----------------------------";
      /** Marks revision data */
      private static final String REVISION_TAG = "revision ";
      /** Marks date data */
      private static final String DATE_TAG = "date: ";
  
      /** current status of the parser */
      private int status = GET_FILE;
      
      /** the current log entry being processed by the parser*/
      private ChangeLogEntry currentLogEntry = null;
      
      /** the current file being processed by the parser */
      private ChangeLogFile currentFile = null;
  
      /**
       * Create a new ChangeLogParser.
       */
      public CvsChangeLogParser()
      {
      }
  
      // doc comment inherited from ChangeLogParer interface
      public void init( ChangeLog changeLog )
      {
      }
  
      // doc comment inherited from ChangeLogParer interface
      public void cleanup()
      {
      }
      
      /**
       * Parse the input stream into a collection.
       * @param anInputStream an input stream containing cvs log output
       * @return a collection of ChangeLogEntry's
       * @throws IOException when there are errors reading the provided stream
       */
      public Collection parse(InputStream anInputStream) throws IOException
      {
          BufferedReader stream = new BufferedReader( 
              new InputStreamReader(anInputStream) );
  
          // current state transitions in the state machine - starts with Get File
          //      Get File                -> Get Revision
          //      Get Revision            -> Get Date or Get File
          //      Get Date                -> Get Comment
          //      Get Comment             -> Get Comment or Get Revision
          String line = null;
          while ((line = stream.readLine()) != null)
          {
              switch (status)
              {
                  case GET_FILE:
                      processGetFile(line);
                      break;
                  case GET_REVISION:
                      processGetRevision(line);
                      break;
                  case GET_DATE:
                      processGetDate(line);
                      break;
                  case GET_COMMENT:
                      processGetComment(line);
                      break;
                  default:
                      throw new IllegalStateException("Unknown state: " + status);
              }
          }
          
          return entries.values();
       }
      
      /**
       * Add a change log entry to the list (if it's not already there)
       * with the given file.
       * @param entry a {@link ChangeLogEntry} to be added to the list if another
       *      with the same key doesn't exist already. If the entry's author
       *      is null, the entry wont be added
       * @param file a {@link ChangeLogFile} to be added to the entry
       */
      private void addEntry(ChangeLogEntry entry, ChangeLogFile file)
      {
          // do not add if entry is not populated
          if (entry.getAuthor() == null)
          {
              return;
          }
          
          String key = entry.getDateFormatted() + entry.getTimeFormatted() + 
              entry.getAuthor() + entry.getComment();
          if (!entries.containsKey(key))
          {
              entry.addFile(file);
              entries.put(key, entry);
          }
          else
          {
              ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get(key);
              existingEntry.addFile(file);
          }
      }
   
      /**
       * Process the current input line in the Get File state.
       * @param line a line of text from the cvs log output
       */
      private void processGetFile(String line) 
      {
          if (line.startsWith(START_FILE))
          {
              setCurrentLogEntry(new ChangeLogEntry());
              setCurrentFile(new ChangeLogFile(line.substring(START_FILE.length(),
                  line.length())));
              setStatus(GET_REVISION);
          }
      }
  
      /**
       * Process the current input line in the Get Revision state.
       * @param line a line of text from the cvs log output
       */
      private void processGetRevision(String line) 
      {
          if (line.startsWith(REVISION_TAG))
          {
              getCurrentFile().setRevision(line.substring(REVISION_TAG.length()));
              setStatus(GET_DATE);
          }
          else if (line.startsWith(END_FILE))
          {
              // If we encounter an end of file line, it means there 
              // are no more revisions for the current file.
              // there could also be a file still being processed.
              setStatus(GET_FILE);
              addEntry(getCurrentLogEntry(), getCurrentFile());
          }
      }
  
      /**
       * Process the current input line in the Get Date state.
       * @param line a line of text from the cvs log output
       */
      private void processGetDate(String line)
      {
          if (line.startsWith(DATE_TAG))
          {
              StringTokenizer tokenizer = new StringTokenizer(line, " ;");
              // date: YYYY/mm/dd HH:mm:ss; author: name
              tokenizer.nextToken(); // date tag
              String date = tokenizer.nextToken(); 
              String time = tokenizer.nextToken();
              getCurrentLogEntry().setDate(date + " " + time);
              tokenizer.nextToken(); // author tag
              // assumes author can't contain spaces
              String author = tokenizer.nextToken();
              getCurrentLogEntry().setAuthor(author);
              setStatus(GET_COMMENT);
          }
      }
  
      /**
       * Process the current input line in the Get Comment state.
       * @param line a line of text from the cvs log output
       */
      private void processGetComment(String line)
      {
          if (line.startsWith(START_REVISION))
          {
              // add entry, and set state to get revision
              addEntry(getCurrentLogEntry(), getCurrentFile());
              // new change log entry
              setCurrentLogEntry(new ChangeLogEntry());
              // same file name, but different rev
              setCurrentFile(new ChangeLogFile(getCurrentFile().getName()));
              setStatus(GET_REVISION);
          }
          else if (line.startsWith(END_FILE))
          {
              addEntry(getCurrentLogEntry(), getCurrentFile());
              setStatus(GET_FILE);
          }
          else
          {
              // keep gathering comments
              getCurrentLogEntry().setComment(
                  getCurrentLogEntry().getComment() + line + "\n");
          }
      }
  
      /**
       * Getter for property currentFile.
       * @return Value of property currentFile.
       */
      private ChangeLogFile getCurrentFile()
      {
          return currentFile;
      }
      
      /**
       * Setter for property currentFile.
       * @param currentFile New value of property currentFile.
       */
      private void setCurrentFile(ChangeLogFile currentFile)
      {
          this.currentFile = currentFile;
      }
      
      /**
       * Getter for property currentLogEntry.
       * @return Value of property currentLogEntry.
       */
      private ChangeLogEntry getCurrentLogEntry()
      {
          return currentLogEntry;
      }
      
      /**
       * Setter for property currentLogEntry.
       * @param currentLogEntry New value of property currentLogEntry.
       */
      private void setCurrentLogEntry(ChangeLogEntry currentLogEntry)
      {
          this.currentLogEntry = currentLogEntry;
      }
      
      /**
       * Getter for property status.
       * @return Value of property status.
       */
      private int getStatus()
      {
          return status;
      }
      
      /**
       * Setter for property status.
       * @param status New value of property status.
       */
      private void setStatus(int status)
      {
          this.status = status;
      }
  }
  
  
  


Reply via email to