bodewig     2005/02/14 05:28:33

  Modified:    proposal/sandbox/svn README
               proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn
                        AbstractSvnTask.java antlib.xml
  Added:       proposal/sandbox/svn/src/etc/testcases changelog.xml
               proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn
                        LineOrientedOutputStream.java
                        SvnChangeLogParser.java SvnChangeLogTask.java
                        SvnChangeLogWriter.java SvnEntry.java
  Log:
  svnchangelog task, very similar to cvschangelog - has a lot of potential for 
improvements
  
  Revision  Changes    Path
  1.2       +0 -6      ant/proposal/sandbox/svn/README
  
  Index: README
  ===================================================================
  RCS file: /home/cvs/ant/proposal/sandbox/svn/README,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- README    11 Feb 2005 12:25:32 -0000      1.1
  +++ README    14 Feb 2005 13:28:33 -0000      1.2
  @@ -18,9 +18,3 @@
   If you need more than what this libary provides, we encourage you to
   check out the existing alternatives.
   
  -===============
  -
  -The first cut will mimic the implementation of the <cvs> task, it will
  -even be split into an abstract task and a very thin real task - it may
  -be possible to base tasks similar to the optional CVS tasks on the
  -abstract task as well.
  
  
  
  1.1                  ant/proposal/sandbox/svn/src/etc/testcases/changelog.xml
  
  Index: changelog.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
   Copyright  2005 The Apache Software Foundation
   
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
   
        http://www.apache.org/licenses/LICENSE-2.0
   
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->
  
  <project name="changelog-test" basedir="../../../" 
           default="log" xmlns:svn="antlib:org.apache.tools.ant.taskdefs.svn">
  
    <property name="tmpdir" value="tmpdir"/>
    <property name="tpfdir" value="${tmpdir}/tpf"/>
    <property name="file" value="ebcdic.h"/>
  
    <target name="setup">
      <mkdir dir="${tmpdir}"/>
      <svn:svn
        svnURL="http://svn.apache.org/repos/asf/httpd/httpd/trunk/os/tpf/";
        dest="${tmpdir}"/>
    </target>
  
    <target name="log" depends="setup">
      <svn:changelog failonerror="true" dest="${tpfdir}"
        destfile="${tmpdir}/log.xml"/>
    </target>
  
    <target name="start" depends="setup">
      <svn:changelog failonerror="true" dest="${tpfdir}"
        destfile="${tmpdir}/log.xml" start="151000"/>
    </target>
  
    <target name="startDate" depends="setup">
      <svn:changelog failonerror="true" dest="${tpfdir}"
        destfile="${tmpdir}/log.xml" start="{2004-12-24}"/>
    </target>
  
    <target name="end" depends="setup">
      <svn:changelog failonerror="true" dest="${tpfdir}"
        destfile="${tmpdir}/log.xml" end="151000"/>
    </target>
  
    <target name="endDate" depends="setup">
      <svn:changelog failonerror="true" dest="${tpfdir}"
        destfile="${tmpdir}/log.xml" end="{2004-12-24}"/>
    </target>
  
    <target name="cleanup">
      <delete dir="${tmpdir}" />
    </target>
  </project>
  
  
  
  1.2       +17 -1     
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/AbstractSvnTask.java
  
  Index: AbstractSvnTask.java
  ===================================================================
  RCS file: 
/home/cvs/ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/AbstractSvnTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractSvnTask.java      11 Feb 2005 13:50:16 -0000      1.1
  +++ AbstractSvnTask.java      14 Feb 2005 13:28:33 -0000      1.2
  @@ -70,6 +70,11 @@
       private boolean quiet = false;
   
       /**
  +     * be verbose
  +     */
  +    private boolean verbose = false;
  +
  +    /**
        * report only, don't change any files.
        */
       private boolean dryrun = false;
  @@ -467,6 +472,14 @@
       }
   
       /**
  +     * If true, be verbose.
  +     * @param q  if true, be verbose.
  +     */
  +    public void setVerbose(boolean v) {
  +        verbose = v;
  +    }
  +
  +    /**
        * If true, report only and don't change any files.
        *
        * @param ne if true, report only and do not change any files.
  @@ -523,7 +536,7 @@
        * <li>
        * quiet
        * </li>
  -     * <li>svnroot</li>
  +     * <li>verbose</li>
        * <li>dryrun</li>
        * </ul>
        */
  @@ -535,6 +548,9 @@
           if (quiet) {
               c.createArgument(true).setValue("--quiet");
           }
  +        if (verbose) {
  +            c.createArgument(true).setValue("--verbose");
  +        }
           if (dryrun) {
               c.createArgument(true).setValue("--dry-run");
           }
  
  
  
  1.2       +4 -0      
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/antlib.xml
  
  Index: antlib.xml
  ===================================================================
  RCS file: 
/home/cvs/ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/antlib.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- antlib.xml        11 Feb 2005 13:50:16 -0000      1.1
  +++ antlib.xml        14 Feb 2005 13:28:33 -0000      1.2
  @@ -19,4 +19,8 @@
       name="svn"
       classname="org.apache.tools.ant.taskdefs.svn.Svn"
       />
  +  <taskdef
  +    name="changelog"
  +    classname="org.apache.tools.ant.taskdefs.svn.SvnChangeLogTask"
  +    />
   </antlib>
  
  
  
  1.1                  
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/LineOrientedOutputStream.java
  
  Index: LineOrientedOutputStream.java
  ===================================================================
  /*
   * Copyright  2005 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  
  package org.apache.tools.ant.taskdefs.svn;
  
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  
  /**
   * Invokes [EMAIL PROTECTED] #processLine processLine} whenever a full line 
has
   * been written to this stream.
   *
   * <p>Tries to be smart about line separators.</p>
   */
  public abstract class LineOrientedOutputStream extends OutputStream {
  
      /** Initial buffer size. */
      private static final int INTIAL_SIZE = 132;
  
      /** Carriage return */
      private static final int CR = 0x0d;
  
      /** Linefeed */
      private static final int LF = 0x0a;
  
      private ByteArrayOutputStream buffer
          = new ByteArrayOutputStream(INTIAL_SIZE);
      private boolean skip = false;
  
      /**
       * Write the data to the buffer and flush the buffer, if a line
       * separator is detected.
       *
       * @param cc data to log (byte).
       */
      public final void write(int cc) throws IOException {
          final byte c = (byte) cc;
          if ((c == '\n') || (c == '\r')) {
              if (!skip) {
                processBuffer();
              }
          } else {
            buffer.write(cc);
          }
          skip = (c == '\r');
      }
  
      /**
       * Flush this log stream
       */
      public final void flush() throws IOException {
          if (buffer.size() > 0) {
              processBuffer();
          }
      }
  
      /**
       * Converts the buffer to a string and sends it to
       * <code>processLine</code>
       */
      private void processBuffer() throws IOException {
          try {
              processLine(buffer.toString());
          } finally {
              buffer.reset();
          }
      }
  
      /**
       * Processes a line.
       *
       * @param line the line to log.
       */
      protected abstract void processLine(String line) throws IOException;
  
      /**
       * Writes all remaining
       */
      public final void close() throws IOException {
          if (buffer.size() > 0) {
              processBuffer();
          }
          super.close();
      }
  
      /**
       * Write a block of characters to the output stream
       *
       * @param b the array containing the data
       * @param off the offset into the array where data starts
       * @param len the length of block
       *
       * @throws IOException if the data cannot be written into the stream.
       */
      public final void write(byte[] b, int off, int len) throws IOException {
          // find the line breaks and pass other chars through in blocks
          int offset = off;
          int blockStartOffset = offset;
          int remaining = len;
          while (remaining > 0) {
              while (remaining > 0 && b[offset] != LF && b[offset] != CR) {
                  offset++;
                  remaining--;
              }
              // either end of buffer or a line separator char
              int blockLength = offset - blockStartOffset;
              if (blockLength > 0) {
                  buffer.write(b, blockStartOffset, blockLength);
              }
              while (remaining > 0 && (b[offset] == LF || b[offset] == CR)) {
                  write(b[offset]);
                  offset++;
                  remaining--;
              }
              blockStartOffset = offset;
          }
      }
  
  }
  
  
  
  1.1                  
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnChangeLogParser.java
  
  Index: SvnChangeLogParser.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  package org.apache.tools.ant.taskdefs.svn;
  
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.ArrayList;
  
  /**
   * A class used to parse the output of the svn log command.
   *
   * @version $Revision: 1.1 $ $Date: 2005/02/14 13:28:33 $
   */
  class SvnChangeLogParser extends LineOrientedOutputStream {
  
      private final static int GET_ENTRY_LINE = 0;
      private final static int GET_REVISION_LINE = 1;
      private final static int GET_PATHS = 2;
      private final static int GET_MESSAGE = 3;
  
      private String message = "";
      private Date date = null;
      private String author = null;
      private String revision = null;
      private ArrayList paths = new ArrayList();
  
      /** input format for dates read in from cvs log */
      private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
      private static final SimpleDateFormat INPUT_DATE
          = new SimpleDateFormat(PATTERN);
  
      private final ArrayList entries = new ArrayList();
      private int status = GET_ENTRY_LINE;
  
      /**
       * Get a list of rcs entries as an array.
       *
       * @return a list of rcs entries as an array
       */
      public SvnEntry[] getEntrySetAsArray() {
          return (SvnEntry[]) entries.toArray(new SvnEntry[entries.size()]);
      }
  
      /**
       * Receive notification about the process writing
       * to standard output.
       * @param line the line to process
       */
      public void processLine(final String line) {
          switch(status) {
              case GET_ENTRY_LINE:
                  // make sure attributes are reset when
                  // working on a 'new' file.
                  reset();
                  processEntryStart(line);
                  break;
              case GET_REVISION_LINE:
                  processRevision(line);
                  break;
  
              case GET_MESSAGE:
                  processMessage(line);
                  break;
  
              case GET_PATHS:
                  processPath(line);
                  break;
  
              default:
                  // Do nothing
                  break;
          }
      }
  
      /**
       * Process a line while in "GET_MESSAGE" state.
       *
       * @param line the line
       */
      private void processMessage(final String line) {
          final String lineSeparator = System.getProperty("line.separator");
          if 
(line.equals("------------------------------------------------------------------------"))
 {
              //We have ended changelog for that particular revision
              //so we can save it
              final int end
                  = message.length() - lineSeparator.length(); //was -1
              message = message.substring(0, end);
              saveEntry();
              status = GET_REVISION_LINE;
          } else {
              message += line + lineSeparator;
          }
      }
  
      /**
       * Process a line while in "GET_ENTRY_LINE" state.
       *
       * @param line the line to process
       */
      private void processEntryStart(final String line) {
          if 
(line.equals("------------------------------------------------------------------------"))
 {
              status = GET_REVISION_LINE;
          }
      }
  
      /**
       * Process a line while in "REVISION" state.
       *
       * @param line the line to process
       */
      private void processRevision(final String line) {
          int index = line.indexOf(" |");
          if (line.startsWith("r") 
              && (line.endsWith("lines") || line.endsWith("line"))
              && index > -1) {
              revision = line.substring(1, index);
              int end = line.indexOf(" |", index + 1);
              author = line.substring(index + 3, end);
              String d = line.substring(end + 3, end + 3 + PATTERN.length());
              date = parseDate(d);
              status = GET_PATHS;
          }
      }
  
      /**
       * Process a line while in "GET_PATHS" state.
       *
       * @param line the line to process
       */
      private void processPath(final String line) {
          if (line.startsWith("Changed paths:")) {
              // ignore
          } else if (line.equals("")) {
              status = GET_MESSAGE;
          } else {
              paths.add(line.substring(5));
          }
      }
  
      /**
       * Utility method that saves the current entry.
       */
      private void saveEntry() {
          SvnEntry entry = new SvnEntry(date, revision, author, message,
                                        paths);
          entries.add(entry);
      }
  
      /**
       * Parse date out from expected format.
       *
       * @param date the string holding date
       * @return the date object or null if unknown date format
       */
      private Date parseDate(final String date) {
          try {
              return INPUT_DATE.parse(date);
          } catch (ParseException e) {
              return null;
          }
      }
  
      /**
       * Reset all internal attributes except status.
       */
      public void reset() {
          this.date = null;
          this.author = null;
          this.message = "";
          this.revision = null;
          this.paths.clear();
      }
  }
  
  
  
  1.1                  
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnChangeLogTask.java
  
  Index: SvnChangeLogTask.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  package org.apache.tools.ant.taskdefs.svn;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.io.UnsupportedEncodingException;
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.Vector;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.DirectoryScanner;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.taskdefs.LogOutputStream;
  import org.apache.tools.ant.taskdefs.PumpStreamHandler;
  import org.apache.tools.ant.taskdefs.cvslib.CvsUser;
  import org.apache.tools.ant.types.FileSet;
  import org.apache.tools.ant.util.FileUtils;
  
  /**
   * Examines the output of svn log and group related changes together.
   *
   * It produces an XML output representing the list of changes.
   * <pre>
   * <font color=#0000ff>&lt;!-- Root element --&gt;</font>
   * <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>
   * <font color=#0000ff>&lt;!-- SVN Entry --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> entry <font 
color=#ff00ff>(date,time,revision,author,file</font><font 
color=#ff00ff>+,msg</font><font color=#ff00ff>,msg)</font><font 
color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- Date of svn entry --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> date <font 
color=#ff00ff>(#PCDATA)</font><font color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- Time of svn entry --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> time <font 
color=#ff00ff>(#PCDATA)</font><font color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- Author of change --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> author <font 
color=#ff00ff>(#PCDATA)</font><font color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- commit message --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> msg <font 
color=#ff00ff>(#PCDATA)</font><font color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- List of files affected --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> file <font 
color=#ff00ff>(name</font><font color=#ff00ff>?</font><font 
color=#ff00ff>)</font><font color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- Name of the file --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> name <font 
color=#ff00ff>(#PCDATA)</font><font color=#6a5acd>&gt;</font>
   * <font color=#0000ff>&lt;!-- Revision number --&gt;</font>
   * <font color=#6a5acd>&lt;!ELEMENT</font> revision <font 
color=#ff00ff>(#PCDATA)</font><font color=#6a5acd>&gt;</font>
   * </pre>
   *
   * @ant.task name="svnchangelog" category="scm"
   */
  public class SvnChangeLogTask extends AbstractSvnTask {
      /** User list */
      private File usersFile;
  
      /** User list */
      private Vector svnUsers = new Vector();
  
      /** Input dir */
      private File inputDir;
  
      /** Output file */
      private File destFile;
  
      /** The earliest revision at which to start processing entries.  */
      private String startRevision;
  
      /** The latest revision at which to stop processing entries.  */
      private String endRevision;
  
      /**
       * Filesets containing list of files against which the svn log will be
       * performed. If empty then all files in the working directory will
       * be checked.
       */
      private final Vector filesets = new Vector();
  
  
      /**
       * Set the base dir for svn.
       *
       * @param inputDir The new dir value
       */
      public void setDir(final File inputDir) {
          this.inputDir = inputDir;
      }
  
  
      /**
       * Set the output file for the log.
       *
       * @param destFile The new destfile value
       */
      public void setDestfile(final File destFile) {
          this.destFile = destFile;
      }
  
  
      /**
       * Set a lookup list of user names & addresses
       *
       * @param usersFile The file containing the users info.
       */
      public void setUsersfile(final File usersFile) {
          this.usersFile = usersFile;
      }
  
  
      /**
       * Add a user to list changelog knows about.
       *
       * @param user the user
       */
      public void addUser(final CvsUser user) {
          svnUsers.addElement(user);
      }
  
  
      /**
       * Set the revision at which the changelog should start.
       *
       * @param start The revision at which the changelog should start.
       */
      public void setStart(final String start) {
          this.startRevision = start;
      }
  
  
      /**
       * Set the revision at which the changelog should stop.
       *
       * @param endRevision The revision at which the changelog should stop.
       */
      public void setEnd(final String endRevision) {
          this.endRevision = endRevision;
      }
  
  
      /**
       * Set the number of days worth of log entries to process.
       *
       * @param days the number of days of log to process.
       */
      public void setDaysinpast(final int days) {
          final long time = System.currentTimeMillis()
              - (long) days * 24 * 60 * 60 * 1000;
  
          final SimpleDateFormat outputDate =
              new SimpleDateFormat("{yyyy-MM-dd}");
          setStart(outputDate.format(new Date(time)));
      }
  
  
      /**
       * Adds a set of files about which svn logs will be generated.
       *
       * @param fileSet a set of files about which svn logs will be generated.
       */
      public void addFileset(final FileSet fileSet) {
          filesets.addElement(fileSet);
      }
  
  
      /**
       * Execute task
       *
       * @exception BuildException if something goes wrong executing the
       *            svn command
       */
      public void execute() throws BuildException {
          File savedDir = inputDir; // may be altered in validate
  
          try {
  
              validate();
              final Properties userList = new Properties();
  
              loadUserlist(userList);
  
              for (int i = 0, size = svnUsers.size(); i < size; i++) {
                  final CvsUser user = (CvsUser) svnUsers.get(i);
                  user.validate();
                  userList.put(user.getUserID(), user.getDisplayname());
              }
  
              setSubCommand("log");
              setVerbose(true);
  
              if (null != startRevision) {
                  if (null != endRevision) {
                      setRevision(startRevision + ":" + endRevision);
                  } else {
                      setRevision(startRevision + ":HEAD");
                  }
              }
  
              // Check if list of files to check has been specified
              if (!filesets.isEmpty()) {
                  final Enumeration e = filesets.elements();
  
                  while (e.hasMoreElements()) {
                      final FileSet fileSet = (FileSet) e.nextElement();
                      final DirectoryScanner scanner =
                          fileSet.getDirectoryScanner(getProject());
                      final String[] files = scanner.getIncludedFiles();
  
                      for (int i = 0; i < files.length; i++) {
                          addSubCommandArgument(files[i]);
                      }
                  }
              }
  
              final SvnChangeLogParser parser = new SvnChangeLogParser();
              final PumpStreamHandler handler =
                  new PumpStreamHandler(parser,
                                        new LogOutputStream(this,
                                                            Project.MSG_ERR));
  
              log(getSubCommand(), Project.MSG_VERBOSE);
  
              setDest(inputDir);
              setExecuteStreamHandler(handler);
              super.execute();
  
              final SvnEntry[] entrySet = parser.getEntrySetAsArray();
              final SvnEntry[] filteredEntrySet = filterEntrySet(entrySet);
  
              replaceAuthorIdWithName(userList, filteredEntrySet);
  
              writeChangeLog(filteredEntrySet);
  
          } finally {
              inputDir = savedDir;
          }
      }
  
      /**
       * Validate the parameters specified for task.
       *
       * @throws BuildException if fails validation checks
       */
      private void validate()
          throws BuildException {
          if (null == inputDir) {
              inputDir = getDest();
          }
          if (null == destFile) {
              final String message = "Destfile must be set.";
  
              throw new BuildException(message);
          }
          if (!inputDir.exists()) {
              final String message = "Cannot find base dir "
                  + inputDir.getAbsolutePath();
  
              throw new BuildException(message);
          }
          if (null != usersFile && !usersFile.exists()) {
              final String message = "Cannot find user lookup list "
                  + usersFile.getAbsolutePath();
  
              throw new BuildException(message);
          }
      }
  
      /**
       * Load the userlist from the userList file (if specified) and add to
       * list of users.
       *
       * @param userList the file of users
       * @throws BuildException if file can not be loaded for some reason
       */
      private void loadUserlist(final Properties userList)
          throws BuildException {
          if (null != usersFile) {
              try {
                  userList.load(new FileInputStream(usersFile));
              } catch (final IOException ioe) {
                  throw new BuildException(ioe.toString(), ioe);
              }
          }
      }
  
      /**
       * Filter the specified entries according to an appropriate rule.
       *
       * @param entrySet the entry set to filter
       * @return the filtered entry set
       */
      private SvnEntry[] filterEntrySet(final SvnEntry[] entrySet) {
          final Vector results = new Vector();
  
          for (int i = 0; i < entrySet.length; i++) {
              final SvnEntry svnEntry = entrySet[i];
  
              if (null != endRevision && !isBeforeEndRevision(svnEntry)) {
                  //Skip revisions that are too late
                  continue;
              }
              results.addElement(svnEntry);
          }
  
          final SvnEntry[] resultArray = new SvnEntry[results.size()];
  
          results.copyInto(resultArray);
          return resultArray;
      }
  
      /**
       * replace all known author's id's with their maven specified names
       */
      private void replaceAuthorIdWithName(final Properties userList,
                                           final SvnEntry[] entrySet) {
          for (int i = 0; i < entrySet.length; i++) {
  
              final SvnEntry entry = entrySet[ i ];
              if (userList.containsKey(entry.getAuthor())) {
                  entry.setAuthor(userList.getProperty(entry.getAuthor()));
              }
          }
      }
  
      /**
       * Print changelog to file specified in task.
       *
       * @param entrySet the entry set to write.
       * @throws BuildException if there is an error writing changelog.
       */
      private void writeChangeLog(final SvnEntry[] entrySet)
          throws BuildException {
          FileOutputStream output = null;
  
          try {
              output = new FileOutputStream(destFile);
  
              final PrintWriter writer =
                  new PrintWriter(new OutputStreamWriter(output, "UTF-8"));
  
              final SvnChangeLogWriter serializer = new SvnChangeLogWriter();
  
              serializer.printChangeLog(writer, entrySet);
          } catch (final UnsupportedEncodingException uee) {
              getProject().log(uee.toString(), Project.MSG_ERR);
          } catch (final IOException ioe) {
              throw new BuildException(ioe.toString(), ioe);
          } finally {
              FileUtils.close(output);
          }
      }
  
      private static final String PATTERN = "yyyy-MM-dd";
      private static final SimpleDateFormat INPUT_DATE
          = new SimpleDateFormat(PATTERN);
  
      /**
       * Checks whether a given entry is before the given end revision,
       * using revision numbers or date information as appropriate.
       */
      private boolean isBeforeEndRevision(SvnEntry entry) {
          if (endRevision.startsWith("{")
              && endRevision.length() >= 2 + PATTERN.length() ) {
              try {
                  Date endDate = 
                      INPUT_DATE.parse(endRevision.substring(1, 
                                                             PATTERN.length() 
                                                             + 1));
                  return entry.getDate().before(endDate);
              } catch (ParseException e) {
              }
          } else {
              try {
                  int endRev = Integer.parseInt(endRevision);
                  int entryRev = Integer.parseInt(entry.getRevision());
                  return endRev >= entryRev;
              } catch (NumberFormatException e) {
              } // end of try-catch
          }
          // failed to parse revision, use a save fallback
          return true;
      }
  }
  
  
  
  
  1.1                  
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnChangeLogWriter.java
  
  Index: SvnChangeLogWriter.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  package org.apache.tools.ant.taskdefs.svn;
  
  import java.io.PrintWriter;
  import java.text.SimpleDateFormat;
  
  /**
   * Class used to generate an XML changelog.
   */
  public class SvnChangeLogWriter {
      /** output format for dates written to xml file */
      private static final SimpleDateFormat OUTPUT_DATE
          = new SimpleDateFormat("yyyy-MM-dd");
      /** output format for times written to xml file */
      private static final SimpleDateFormat OUTPUT_TIME
          = new SimpleDateFormat("HH:mm");
  
      /**
       * Print out the specified entries.
       *
       * @param output writer to which to send output.
       * @param entries the entries to be written.
       */
      public void printChangeLog(final PrintWriter output,
                                 final SvnEntry[] entries) {
          output.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
          output.println("<changelog>");
          for (int i = 0; i < entries.length; i++) {
              final SvnEntry entry = entries[i];
  
              printEntry(output, entry);
          }
          output.println("</changelog>");
          output.flush();
          output.close();
      }
  
  
      /**
       * Print out an individual entry in changelog.
       *
       * @param entry the entry to print
       * @param output writer to which to send output.
       */
      private void printEntry(final PrintWriter output, final SvnEntry entry) {
          output.println("\t<entry>");
          output.println("\t\t<date>" + OUTPUT_DATE.format(entry.getDate())
              + "</date>");
          output.println("\t\t<time>" + OUTPUT_TIME.format(entry.getDate())
              + "</time>");
          output.println("\t\t<author><![CDATA[" + entry.getAuthor()
              + "]]></author>");
          output.println("\t\t<revision><![CDATA[" + entry.getRevision()
              + "]]></revision>");
  
          String[] paths = entry.getPaths();
          for (int i = 0; i < paths.length; i++) {
              output.println("\t\t<file>");
              output.println("\t\t\t<name><![CDATA[" + paths[i] + "]]></name>");
              output.println("\t\t</file>");
          }
          output.println("\t\t<msg><![CDATA[" + entry.getMessage() + 
"]]></msg>");
          output.println("\t</entry>");
      }
  }
  
  
  
  
  1.1                  
ant/proposal/sandbox/svn/src/main/org/apache/tools/ant/taskdefs/svn/SvnEntry.java
  
  Index: SvnEntry.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   */
  package org.apache.tools.ant.taskdefs.svn;
  
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Date;
  
  public class SvnEntry {
      private final Date date;
      private final String revision;
      private String author;
      private final String message;
      private final ArrayList paths = new ArrayList();
  
      /**
       * Creates a new instance of a SvnEntry
       * @param date the date
       * @param author the author
       * @param message a message to be added to the revision
       */
      public SvnEntry(final Date date, final String revision, 
                      final String author, final String message) {
          this(date, revision, author, message, Collections.EMPTY_LIST);
      }
  
      /**
       * Creates a new instance of a SvnEntry
       * @param date the date
       * @param author the author
       * @param message a message to be added to the revision
       */
      public SvnEntry(final Date date, final String revision, 
                      final String author, final String message,
                      final Collection paths) {
          this.date = date;
          this.revision = revision;
          this.author = author;
          this.message = message;
          this.paths.addAll(paths);
      }
  
      /**
       * Adds a path to the SvnEntry
       * @param path the path to add
       * @param revision the revision
       */
      public void addPath(final String name) {
          paths.add(name);
      }
  
      /**
       * Gets the date of the SvnEntry
       * @return the date
       */
      public Date getDate() {
          return date;
      }
  
      /**
       * Gets the revision of the SvnEntry
       * @return the date
       */
      public String getRevision() {
          return revision;
      }
  
      /**
       * Sets the author of the SvnEntry
       * @param author the author
       */
      public void setAuthor(final String author) {
          this.author = author;
      }
  
      /**
       * Gets the author of the SvnEntry
       * @return the author
       */
      public String getAuthor() {
          return author;
      }
  
      /**
       * Gets the message for the SvnEntry
       * @return the message
       */
      public String getMessage() {
          return message;
      }
  
      /**
       * Gets the paths in this SvnEntry
       * @return the files
       */
      public String[] getPaths() {
          return (String[]) paths.toArray(new String[paths.size()]);
      }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to