diff --git a/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLog.java b/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLog.java index c1d945348..dab6b55ca 100644 --- a/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLog.java +++ b/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLog.java @@ -14,15 +14,9 @@ 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.Hashtable; -import java.util.Iterator; import java.util.Properties; import java.util.Vector; -import org.apache.aut.nativelib.ExecOutputHandler; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; import org.apache.avalon.excalibur.io.IOUtil; @@ -63,33 +57,15 @@ import org.apache.tools.todo.types.Commandline; */ public class ChangeLog extends AbstractTask - implements ExecOutputHandler { private final static Resources REZ = ResourceManager.getPackageResources( ChangeLog.class ); - //private static final int GET_ENTRY = 0; - private static final int GET_FILE = 1; - private static final int GET_DATE = 2; - private static final int GET_COMMENT = 3; - private static final int GET_REVISION = 4; - private static final int GET_PREVIOUS_REV = 5; - - /** input format for dates read in from cvs log */ - private static final SimpleDateFormat c_inputDate = new SimpleDateFormat( "yyyy/MM/dd" ); - /** output format for dates writtn to xml file */ - private static final SimpleDateFormat c_outputDate = new SimpleDateFormat( "yyyy-MM-dd" ); - /** output format for times writtn to xml file */ - private static final SimpleDateFormat c_outputTime = new SimpleDateFormat( "hh:mm" ); - - /** User list */ - private File m_users; - /** User list */ - private final Properties m_userList = new Properties(); + private File m_usersFile; /** User list */ - private Vector m_ulist = new Vector(); + private Vector m_cvsUsers = new Vector(); /** Input dir */ private File m_basedir; @@ -97,17 +73,6 @@ public class ChangeLog /** Output file */ private File m_destfile; - private int m_status = GET_FILE; - - /** rcs entries */ - private final Hashtable m_entries = new Hashtable(); - private String m_workingFile; - private String m_workingDate; - private String m_workingAuthor; - private String m_workingComment; - private String m_workingRevision; - private String m_workingPreviousRevision; - /** * Set the base dir for cvs. */ @@ -127,9 +92,9 @@ public class ChangeLog /** * Set a lookup list of user names & addresses */ - public void setUserlist( final File users ) + public void setUsersfile( final File usersFile ) { - m_users = users; + m_usersFile = usersFile; } /** @@ -139,7 +104,7 @@ public class ChangeLog */ public void addUser( final CvsUser user ) { - m_ulist.addElement( user ); + m_cvsUsers.addElement( user ); } /** @@ -149,26 +114,29 @@ public class ChangeLog { validate(); - loadUserlist(); + final Properties userList = new Properties(); + + loadUserlist( userList ); - for( Enumeration e = m_ulist.elements(); e.hasMoreElements(); ) + for( Enumeration e = m_cvsUsers.elements(); e.hasMoreElements(); ) { final CvsUser user = (CvsUser)e.nextElement(); user.validate(); - m_userList.put( user.getUserID(), user.getDisplayname() ); + userList.put( user.getUserID(), user.getDisplayname() ); } final Commandline command = new Commandline(); command.setExecutable( "cvs" ); command.addArgument( "log" ); + final ChangeLogParser parser = new ChangeLogParser( userList ); final Execute exe = new Execute(); exe.setWorkingDirectory( m_basedir ); exe.setCommandline( command ); - exe.setExecOutputHandler( this ); + exe.setExecOutputHandler( parser ); exe.execute( getContext() ); - writeChangeLog(); + writeChangeLog( parser ); } /** @@ -195,10 +163,10 @@ public class ChangeLog REZ.getString( "changelog.bad-basedir.error", m_basedir.getAbsolutePath() ); throw new TaskException( message ); } - if( null != m_users && !m_users.exists() ) + if( null != m_usersFile && !m_usersFile.exists() ) { final String message = - REZ.getString( "changelog.bad-userlist.error", m_users.getAbsolutePath() ); + REZ.getString( "changelog.bad-userlist.error", m_usersFile.getAbsolutePath() ); throw new TaskException( message ); } } @@ -209,14 +177,14 @@ public class ChangeLog * * @throws TaskException if file can not be loaded for some reason */ - private void loadUserlist() + private void loadUserlist( final Properties userList ) throws TaskException { - if( null != m_users ) + if( null != m_usersFile ) { try { - m_userList.load( new FileInputStream( m_users ) ); + userList.load( new FileInputStream( m_usersFile ) ); } catch( final IOException ioe ) { @@ -225,187 +193,12 @@ public class ChangeLog } } - /** - * Receive notification about the process writing - * to standard output. - */ - public void stdout( final String line ) - { - switch( m_status ) - { - case GET_FILE: - processFile( line ); - break; - case GET_REVISION: - processRevision( line ); - //Was a fall through .... - //break; - case GET_DATE: - processDate( line ); - break; - - case GET_COMMENT: - processComment( line ); - break; - - case GET_PREVIOUS_REV: - processGetPreviousRevision( line ); - break; - } - } - - /** - * Process a line while in "GET_COMMENT" state. - * - * @param line the line - */ - private void processComment( final String line ) - { - final String lineSeparator = System.getProperty( "line.separator" ); - if( line.startsWith( "======" ) || line.startsWith( "------" ) ) - { - final int end = m_workingComment.length() - lineSeparator.length(); //was -1 - m_workingComment = m_workingComment.substring( 0, end ); - m_workingComment = ""; - m_status = GET_PREVIOUS_REV; - } - else - { - m_workingComment += line + lineSeparator; - } - } - - /** - * Process a line while in "GET_FILE" state. - * - * @param line the line - */ - private void processFile( final String line ) - { - if( line.startsWith( "Working file:" ) ) - { - m_workingFile = line.substring( 14, line.length() ); - m_status = GET_REVISION; - } - } - - /** - * Process a line while in "REVISION" state. - * - * @param line the line - */ - private void processRevision( final String line ) - { - if( line.startsWith( "revision" ) ) - { - m_workingRevision = line.substring( 9 ); - m_status = GET_DATE; - } - } - - /** - * Process a line while in "DATE" state. - * - * @param line the line - */ - private void processDate( final String line ) - { - if( line.startsWith( "date:" ) ) - { - m_workingDate = line.substring( 6, 16 ); - String lineData = line.substring( line.indexOf( ";" ) + 1 ); - m_workingAuthor = lineData.substring( 10, lineData.indexOf( ";" ) ); - - if( m_userList.containsKey( m_workingAuthor ) ) - { - m_workingAuthor = ""; - } - - m_status = GET_COMMENT; - - //Reset comment to empty here as we can accumulate multiple lines - //in the processComment method - m_workingComment = ""; - } - } - - /** - * Process a line while in "GET_PREVIOUS_REVISION" state. - * - * @param line the line - */ - private void processGetPreviousRevision( final String line ) - { - final String entryKey = m_workingDate + m_workingAuthor + m_workingComment; - if( line.startsWith( "revision" ) ) - { - m_workingPreviousRevision = line.substring( 9 ); - m_status = GET_FILE; - - CVSEntry entry; - if( !m_entries.containsKey( entryKey ) ) - { - entry = new CVSEntry( parseDate( m_workingDate ), m_workingAuthor, m_workingComment ); - m_entries.put( entryKey, entry ); - } - else - { - entry = (CVSEntry)m_entries.get( entryKey ); - } - entry.addFile( m_workingFile, m_workingRevision, m_workingPreviousRevision ); - } - else if( line.startsWith( "======" ) ) - { - m_status = GET_FILE; - CVSEntry entry; - if( !m_entries.containsKey( entryKey ) ) - { - entry = new CVSEntry( parseDate( m_workingDate ), m_workingAuthor, m_workingComment ); - m_entries.put( entryKey, entry ); - } - else - { - entry = (CVSEntry)m_entries.get( entryKey ); - } - entry.addFile( m_workingFile, m_workingRevision ); - } - } - - /** - * Receive notification about the process writing - * to standard error. - */ - public void stderr( String line ) - { - //ignored - } - - /** - * Parse date out from expected format. - * - * @param date the string holding dat - * @return the date object or null if unknown date format - */ - private Date parseDate( final String date ) - { - try - { - return c_inputDate.parse( date ); - } - catch( ParseException e ) - { - final String message = REZ.getString( "changelog.bat-date.error", date ); - getContext().error( message ); - return null; - } - } - /** * Print changelog to file specified in task. * * @throws TaskException if theres an error writing changelog */ - private void writeChangeLog() + private void writeChangeLog( final ChangeLogParser parser ) throws TaskException { FileOutputStream output = null; @@ -414,7 +207,10 @@ public class ChangeLog output = new FileOutputStream( m_destfile ); final PrintWriter writer = new PrintWriter( new OutputStreamWriter( output, "UTF-8" ) ); - printChangeLog( writer ); + + final CVSEntry[] entrySet = parser.getEntrySetAsArray(); + ChangeLogWriter serializer = new ChangeLogWriter(); + serializer.printChangeLog( writer, entrySet ); } catch( final UnsupportedEncodingException uee ) { @@ -429,52 +225,4 @@ public class ChangeLog IOUtil.shutdownStream( output ); } } - - /** - * Print out the full changelog. - */ - private void printChangeLog( final PrintWriter output ) - { - output.println( "" ); - for( Enumeration en = m_entries.elements(); en.hasMoreElements(); ) - { - final CVSEntry entry = (CVSEntry)en.nextElement(); - printEntry( output, entry ); - } - output.println( "" ); - output.flush(); - output.close(); - } - - /** - * Print out an individual entry in changelog. - * - * @param entry the entry to print - */ - private void printEntry( final PrintWriter output, final CVSEntry entry ) - { - output.println( "\t" ); - output.println( "\t\t" + c_outputDate.format( entry.getDate() ) + "" ); - output.println( "\t\t" ); - output.println( "\t\t" + entry.getAuthor() + "" ); - - final Iterator iterator = entry.getFiles().iterator(); - while( iterator.hasNext() ) - { - final RCSFile file = (RCSFile)iterator.next(); - output.println( "\t\t" ); - output.println( "\t\t\t" + file.getName() + "" ); - output.println( "\t\t\t" + file.getRevision() + "" ); - - final String previousRevision = file.getPreviousRevision(); - if( previousRevision != null ) - { - output.println( "\t\t\t" + previousRevision + "" ); - } - - output.println( "\t\t" ); - } - output.println( "\t\t" + entry.getComment() + "" ); - output.println( "\t" ); - } } diff --git a/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLogParser.java b/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLogParser.java new file mode 100644 index 000000000..8f5dcce75 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLogParser.java @@ -0,0 +1,246 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.antlib.cvslib; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Hashtable; +import java.util.Properties; +import org.apache.aut.nativelib.ExecOutputHandler; + +/** + * A class used to parse the output of the CVS log command. + * + * @author Peter Donald + * @version $Revision$ $Date$ + */ +class ChangeLogParser + implements ExecOutputHandler +{ + //private static final int GET_ENTRY = 0; + private static final int GET_FILE = 1; + private static final int GET_DATE = 2; + private static final int GET_COMMENT = 3; + private static final int GET_REVISION = 4; + private static final int GET_PREVIOUS_REV = 5; + + /** input format for dates read in from cvs log */ + private static final SimpleDateFormat c_inputDate = new SimpleDateFormat( "yyyy/MM/dd" ); + + //The following is data used while processing stdout of CVS command + private String m_file; + private String m_date; + private String m_author; + private String m_comment; + private String m_revision; + private String m_previousRevision; + + private int m_status = GET_FILE; + + /** rcs entries */ + private final Hashtable m_entries = new Hashtable(); + + private final Properties m_userList; + + /** + * Construct a parser that uses specified user list. + * + * @param userList the userlist + */ + public ChangeLogParser( Properties userList ) + { + m_userList = userList; + } + + /** + * Get a list of rcs entrys as an array. + * + * @return a list of rcs entrys as an array + */ + CVSEntry[] getEntrySetAsArray() + { + final CVSEntry[] array = new CVSEntry[ m_entries.values().size() ]; + return (CVSEntry[])m_entries.values().toArray( array ); + } + + /** + * Receive notification about the process writing + * to standard output. + */ + public void stdout( final String line ) + { + switch( m_status ) + { + case GET_FILE: + processFile( line ); + break; + case GET_REVISION: + processRevision( line ); + //Was a fall through .... + //break; + case GET_DATE: + processDate( line ); + break; + + case GET_COMMENT: + processComment( line ); + break; + + case GET_PREVIOUS_REV: + processGetPreviousRevision( line ); + break; + } + } + + /** + * Process a line while in "GET_COMMENT" state. + * + * @param line the line + */ + private void processComment( final String line ) + { + final String lineSeparator = System.getProperty( "line.separator" ); + if( line.startsWith( "======" ) || line.startsWith( "------" ) ) + { + final int end = m_comment.length() - lineSeparator.length(); //was -1 + m_comment = m_comment.substring( 0, end ); + m_comment = ""; + m_status = GET_PREVIOUS_REV; + } + else + { + m_comment += line + lineSeparator; + } + } + + /** + * Process a line while in "GET_FILE" state. + * + * @param line the line + */ + private void processFile( final String line ) + { + if( line.startsWith( "Working file:" ) ) + { + m_file = line.substring( 14, line.length() ); + m_status = GET_REVISION; + } + } + + /** + * Process a line while in "REVISION" state. + * + * @param line the line + */ + private void processRevision( final String line ) + { + if( line.startsWith( "revision" ) ) + { + m_revision = line.substring( 9 ); + m_status = GET_DATE; + } + } + + /** + * Process a line while in "DATE" state. + * + * @param line the line + */ + private void processDate( final String line ) + { + if( line.startsWith( "date:" ) ) + { + m_date = line.substring( 6, 16 ); + String lineData = line.substring( line.indexOf( ";" ) + 1 ); + m_author = lineData.substring( 10, lineData.indexOf( ";" ) ); + + if( m_userList.containsKey( m_author ) ) + { + m_author = ""; + } + + m_status = GET_COMMENT; + + //Reset comment to empty here as we can accumulate multiple lines + //in the processComment method + m_comment = ""; + } + } + + /** + * Process a line while in "GET_PREVIOUS_REVISION" state. + * + * @param line the line + */ + private void processGetPreviousRevision( final String line ) + { + final String entryKey = m_date + m_author + m_comment; + if( line.startsWith( "revision" ) ) + { + m_previousRevision = line.substring( 9 ); + m_status = GET_FILE; + + CVSEntry entry; + if( !m_entries.containsKey( entryKey ) ) + { + entry = new CVSEntry( parseDate( m_date ), m_author, m_comment ); + m_entries.put( entryKey, entry ); + } + else + { + entry = (CVSEntry)m_entries.get( entryKey ); + } + entry.addFile( m_file, m_revision, m_previousRevision ); + } + else if( line.startsWith( "======" ) ) + { + m_status = GET_FILE; + CVSEntry entry; + if( !m_entries.containsKey( entryKey ) ) + { + entry = new CVSEntry( parseDate( m_date ), m_author, m_comment ); + m_entries.put( entryKey, entry ); + } + else + { + entry = (CVSEntry)m_entries.get( entryKey ); + } + entry.addFile( m_file, m_revision ); + } + } + + /** + * Receive notification about the process writing + * to standard error. + */ + public void stderr( String line ) + { + //ignored + } + + /** + * Parse date out from expected format. + * + * @param date the string holding dat + * @return the date object or null if unknown date format + */ + private Date parseDate( final String date ) + { + try + { + return c_inputDate.parse( date ); + } + catch( ParseException e ) + { + //final String message = REZ.getString( "changelog.bat-date.error", date ); + //getContext().error( message ); + return null; + } + } +} diff --git a/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLogWriter.java b/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLogWriter.java new file mode 100644 index 000000000..85d78efe9 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/antlib/cvslib/ChangeLogWriter.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.antlib.cvslib; + +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Iterator; + +/** + * Class used to generate an XML changelog. + * + * @author Peter Donald + * @version $Revision$ $Date$ + */ +class ChangeLogWriter +{ + /** output format for dates writtn to xml file */ + private static final SimpleDateFormat c_outputDate = new SimpleDateFormat( "yyyy-MM-dd" ); + /** output format for times writtn to xml file */ + private static final SimpleDateFormat c_outputTime = new SimpleDateFormat( "hh:mm" ); + + /** + * Print out the specifed entrys. + */ + public void printChangeLog( final PrintWriter output, + final CVSEntry[] entries ) + { + output.println( "" ); + for( int i = 0; i < entries.length; i++ ) + { + final CVSEntry entry = entries[ i ]; + printEntry( output, entry ); + } + output.println( "" ); + output.flush(); + output.close(); + } + + /** + * Print out an individual entry in changelog. + * + * @param entry the entry to print + */ + private void printEntry( final PrintWriter output, final CVSEntry entry ) + { + output.println( "\t" ); + output.println( "\t\t" + c_outputDate.format( entry.getDate() ) + "" ); + output.println( "\t\t" ); + output.println( "\t\t" + entry.getAuthor() + "" ); + + final Iterator iterator = entry.getFiles().iterator(); + while( iterator.hasNext() ) + { + final RCSFile file = (RCSFile)iterator.next(); + output.println( "\t\t" ); + output.println( "\t\t\t" + file.getName() + "" ); + output.println( "\t\t\t" + file.getRevision() + "" ); + + final String previousRevision = file.getPreviousRevision(); + if( previousRevision != null ) + { + output.println( "\t\t\t" + previousRevision + "" ); + } + + output.println( "\t\t" ); + } + output.println( "\t\t" + entry.getComment() + "" ); + output.println( "\t" ); + } +}