git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272464 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,11 +0,0 @@ | |||
| design* | |||
| ant.properties | |||
| *.el | |||
| test | |||
| dist | |||
| build | |||
| distributions | |||
| *.ipr | |||
| velocity.log | |||
| project.properties | |||
| ant_vfs_cache | |||
| @@ -1,28 +0,0 @@ | |||
| ***************************** W A R N I N G ********************************** | |||
| All user accessible points in this software package are to be considered | |||
| "alpha". This means that the developer team is not investing _any_ effort | |||
| in providing back compatibility between alpha releases. | |||
| This software will continue to be released as "alpha" until both code, | |||
| schemas and APIs will be considered stable. | |||
| Until then, there will be no warranty that newer versions will maintain back | |||
| compatibility even in the most simple cases. | |||
| On the other hand, once "beta" status is reached, back incompatible changes | |||
| will be made only if absolutely necessary to reach "final" status. | |||
| The Ant development team understands the importance of reliable | |||
| software as well as the importance of protecting user investiments by the | |||
| creation of a solid development platform that doesn't change. | |||
| On the other hand, being the Ant project a pioneer in many fields, this | |||
| cannot be guaranteed before a final status is reached for the software. | |||
| Until then, no effort will be provided to guarantee back compatibility. | |||
| You have been warned. | |||
| ***************************** W A R N I N G ********************************** | |||
| @@ -1,68 +0,0 @@ | |||
| /* | |||
| * 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.util.ArrayList; | |||
| import java.util.Date; | |||
| /** | |||
| * CVS Entry. | |||
| * | |||
| * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> | |||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @version $Revision$ $Date$ | |||
| */ | |||
| class CVSEntry | |||
| { | |||
| private Date m_date; | |||
| private final String m_author; | |||
| private final String m_comment; | |||
| private final ArrayList m_files = new ArrayList(); | |||
| public CVSEntry( Date date, String author, String comment ) | |||
| { | |||
| m_date = date; | |||
| m_author = author; | |||
| m_comment = comment; | |||
| } | |||
| public void addFile( String file, String revision ) | |||
| { | |||
| m_files.add( new RCSFile( file, revision ) ); | |||
| } | |||
| public void addFile( String file, String revision, String previousRevision ) | |||
| { | |||
| m_files.add( new RCSFile( file, revision, previousRevision ) ); | |||
| } | |||
| Date getDate() | |||
| { | |||
| return m_date; | |||
| } | |||
| String getAuthor() | |||
| { | |||
| return m_author; | |||
| } | |||
| String getComment() | |||
| { | |||
| return m_comment; | |||
| } | |||
| ArrayList getFiles() | |||
| { | |||
| return m_files; | |||
| } | |||
| public String toString() | |||
| { | |||
| return getAuthor() + "\n" + getDate() + "\n" + getFiles() + "\n" + getComment(); | |||
| } | |||
| } | |||
| @@ -1,206 +0,0 @@ | |||
| /* | |||
| * 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.BufferedReader; | |||
| import java.io.File; | |||
| import java.io.FileReader; | |||
| import java.io.FileWriter; | |||
| import java.io.IOException; | |||
| import java.io.PrintWriter; | |||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
| import org.apache.avalon.excalibur.i18n.Resources; | |||
| import org.apache.avalon.excalibur.util.StringUtil; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| /** | |||
| * CVSLogin Adds an new entry to a CVS password file | |||
| * | |||
| * @author <a href="jeff@custommonkey.org">Jeff Martin</a> | |||
| * @version $Revision$ $Date$ | |||
| * @ant.task name="cvs-pass" | |||
| */ | |||
| public class CVSPass | |||
| extends AbstractTask | |||
| { | |||
| private static final Resources REZ = | |||
| ResourceManager.getPackageResources( CVSPass.class ); | |||
| /** | |||
| * CVS Root | |||
| */ | |||
| private String m_cvsRoot; | |||
| /** | |||
| * Password file to add password to | |||
| */ | |||
| private File m_passwordFile; | |||
| /** | |||
| * Password to add to file | |||
| */ | |||
| private String m_password; | |||
| /** | |||
| * Array contain char conversion data | |||
| */ | |||
| private static final char[] c_shifts = new char[] | |||
| { | |||
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | |||
| 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, | |||
| 114, 120, 53, 79, 96, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87, | |||
| 111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105, | |||
| 41, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35, | |||
| 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 78, 88, 107, 106, 56, | |||
| 36, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, | |||
| 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85, 223, | |||
| 225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190, | |||
| 199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193, | |||
| 174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212, | |||
| 207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246, | |||
| 192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176, | |||
| 227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127, | |||
| 182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195, | |||
| 243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152 | |||
| }; | |||
| public CVSPass() | |||
| { | |||
| final String location = System.getProperty( "user.home" ) + "/.cvspass"; | |||
| m_passwordFile = new File( location ); | |||
| } | |||
| /** | |||
| * Sets cvs root to be added to the password file | |||
| */ | |||
| public void setCvsroot( final String cvsRoot ) | |||
| { | |||
| m_cvsRoot = cvsRoot; | |||
| } | |||
| /** | |||
| * Sets the password file attribute. | |||
| */ | |||
| public void setPassfile( final File passFile ) | |||
| { | |||
| m_passwordFile = passFile; | |||
| } | |||
| /** | |||
| * Sets the password attribute. | |||
| */ | |||
| public void setPassword( final String password ) | |||
| { | |||
| m_password = password; | |||
| } | |||
| /** | |||
| * Does the work. | |||
| * | |||
| * @exception TaskException if someting goes wrong with the build | |||
| */ | |||
| public final void execute() | |||
| throws TaskException | |||
| { | |||
| validate(); | |||
| notify( "root", m_cvsRoot ); | |||
| notify( "password", m_password ); | |||
| notify( "passFile", m_passwordFile ); | |||
| //FIXME: Should not be writing the whole file - Just append to the file | |||
| //Also should have EOL configurable | |||
| try | |||
| { | |||
| final StringBuffer sb = new StringBuffer(); | |||
| if( m_passwordFile.exists() ) | |||
| { | |||
| final BufferedReader reader = | |||
| new BufferedReader( new FileReader( m_passwordFile ) ); | |||
| String line = null; | |||
| while( ( line = reader.readLine() ) != null ) | |||
| { | |||
| if( !line.startsWith( m_cvsRoot ) ) | |||
| { | |||
| sb.append( line + StringUtil.LINE_SEPARATOR ); | |||
| } | |||
| } | |||
| reader.close(); | |||
| } | |||
| final String pwdfile = | |||
| sb.toString() + m_cvsRoot + " A" + mangle( m_password ); | |||
| notify( "write", pwdfile ); | |||
| final PrintWriter writer = | |||
| new PrintWriter( new FileWriter( m_passwordFile ) ); | |||
| writer.println( pwdfile ); | |||
| writer.close(); | |||
| } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new TaskException( ioe.toString(), ioe ); | |||
| } | |||
| } | |||
| /** | |||
| * Utility method that looks specified key up in resources and | |||
| * prints it out adding specified value as param. | |||
| * | |||
| * @param key the key into resource file | |||
| * @param value the accompanying value | |||
| */ | |||
| private void notify( final String key, final Object value ) | |||
| { | |||
| final String message = REZ.getString( "cvspass." + key + ".notice", value ); | |||
| getContext().debug( message ); | |||
| } | |||
| /** | |||
| * Validate the attributes of the task. | |||
| * | |||
| * @throws TaskException if invalid parameters supplied | |||
| */ | |||
| private void validate() throws TaskException | |||
| { | |||
| if( null == m_cvsRoot ) | |||
| { | |||
| final String message = REZ.getString( "cvspass.noroot.error" ); | |||
| throw new TaskException( message ); | |||
| } | |||
| if( null == m_password ) | |||
| { | |||
| final String message = REZ.getString( "cvspass.nopassword.error" ); | |||
| throw new TaskException( message ); | |||
| } | |||
| } | |||
| /** | |||
| * This encoding method and the accompanying LUT should | |||
| * be pushed into another method ... somewhere. | |||
| */ | |||
| private final String mangle( final String password ) | |||
| { | |||
| final int size = password.length(); | |||
| final StringBuffer sb = new StringBuffer(); | |||
| for( int i = 0; i < size; i++ ) | |||
| { | |||
| sb.append( c_shifts[ password.charAt( i ) ] ); | |||
| } | |||
| return sb.toString(); | |||
| } | |||
| } | |||
| @@ -1,347 +0,0 @@ | |||
| /* | |||
| * 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.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.SimpleDateFormat; | |||
| import java.util.ArrayList; | |||
| import java.util.Date; | |||
| import java.util.Enumeration; | |||
| import java.util.Properties; | |||
| import java.util.Vector; | |||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
| import org.apache.avalon.excalibur.i18n.Resources; | |||
| import org.apache.avalon.excalibur.io.IOUtil; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.framework.nativelib.Execute; | |||
| import org.apache.myrmidon.framework.FileSet; | |||
| import org.apache.myrmidon.framework.nativelib.Commandline; | |||
| /** | |||
| * Change log task. | |||
| * The task will examine the output of cvs log and group related changes together. | |||
| * It produces an XML output representing the list of changes. | |||
| * <PRE> | |||
| * <FONT color=#0000ff><!-- Root element --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> changelog <FONT color=#ff00ff>(entry</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- CVS Entry --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> entry <FONT color=#ff00ff>(date,author,file</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>,msg)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- Date of cvs entry --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> date <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- Author of change --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> author <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- List of files affected --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> msg <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- File changed --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> file <FONT color=#ff00ff>(name,revision,prevrevision</FONT><FONT color=#ff00ff>?</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- Name of the file --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> name <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- Revision number --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> revision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>></FONT> | |||
| * <FONT color=#0000ff><!-- Previous revision number --></FONT> | |||
| * <FONT color=#6a5acd><!ELEMENT</FONT> prevrevision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>></FONT> | |||
| * </PRE> | |||
| * | |||
| * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> | |||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @version $Revision$ $Date$ | |||
| * @ant.task name="changelog" | |||
| */ | |||
| public class ChangeLog | |||
| extends AbstractTask | |||
| { | |||
| private static final Resources REZ = | |||
| ResourceManager.getPackageResources( ChangeLog.class ); | |||
| /** User list */ | |||
| private File m_usersFile; | |||
| /** User list */ | |||
| private Vector m_cvsUsers = new Vector(); | |||
| /** Input dir */ | |||
| private File m_dir; | |||
| /** Output file */ | |||
| private File m_destfile; | |||
| /** | |||
| * The earliest date at which to start processing entrys. | |||
| */ | |||
| private Date m_start; | |||
| /** | |||
| * The latest date at which to stop processing entrys. | |||
| */ | |||
| private Date m_stop; | |||
| /** | |||
| * Filesets containting list of files against which the cvs log will be | |||
| * performed. If empty then all files will in the working directory will | |||
| * be checked. | |||
| */ | |||
| private final Vector m_filesets = new Vector(); | |||
| /** | |||
| * Set the base dir for cvs. | |||
| */ | |||
| public void setDir( final File dir ) | |||
| { | |||
| m_dir = dir; | |||
| } | |||
| /** | |||
| * Set the output file for the log. | |||
| */ | |||
| public void setDestfile( final File destfile ) | |||
| { | |||
| m_destfile = destfile; | |||
| } | |||
| /** | |||
| * Set a lookup list of user names & addresses | |||
| */ | |||
| public void setUsersfile( final File usersFile ) | |||
| { | |||
| m_usersFile = usersFile; | |||
| } | |||
| /** | |||
| * Add a user to list changelog knows about. | |||
| * | |||
| * @param user the user | |||
| */ | |||
| public void addUser( final CvsUser user ) | |||
| { | |||
| m_cvsUsers.addElement( user ); | |||
| } | |||
| /** | |||
| * Set the date at which the changelog should start. | |||
| * | |||
| * @param start The date at which the changelog should start. | |||
| */ | |||
| public void setStart( final Date start ) | |||
| { | |||
| m_start = start; | |||
| } | |||
| /** | |||
| * Set the date at which the changelog should stop. | |||
| * | |||
| * @param stop The date at which the changelog should stop. | |||
| */ | |||
| public void setEnd( final Date stop ) | |||
| { | |||
| m_stop = stop; | |||
| } | |||
| /** | |||
| * Set the numbers of days worth of log entries to process. | |||
| */ | |||
| public void setDaysinpast( final int days ) | |||
| { | |||
| final long time = System.currentTimeMillis() - (long)days * 24 * 60 * 60 * 1000; | |||
| setStart( new Date( time ) ); | |||
| } | |||
| /** | |||
| * Adds a set of files about which cvs logs will be generated. | |||
| * | |||
| * @param fileSet a set of files about which cvs logs will be generated. | |||
| */ | |||
| public void addFileset( final FileSet fileSet ) | |||
| { | |||
| m_filesets.addElement( fileSet ); | |||
| } | |||
| /** | |||
| * Execute task | |||
| */ | |||
| public void execute() throws TaskException | |||
| { | |||
| validate(); | |||
| final Properties userList = new Properties(); | |||
| loadUserlist( userList ); | |||
| for( Enumeration e = m_cvsUsers.elements(); e.hasMoreElements(); ) | |||
| { | |||
| final CvsUser user = (CvsUser)e.nextElement(); | |||
| user.validate(); | |||
| userList.put( user.getUserID(), user.getDisplayname() ); | |||
| } | |||
| final Execute exe = new Execute(); | |||
| exe.setWorkingDirectory( m_dir ); | |||
| exe.setExecutable( "cvs" ); | |||
| exe.addArgument( "log" ); | |||
| if( null != m_start ) | |||
| { | |||
| final SimpleDateFormat outputDate = | |||
| new SimpleDateFormat( "yyyy-MM-dd" ); | |||
| // We want something of the form: -d ">=YYYY-MM-dd" | |||
| final String dateRange = "-d >=" + outputDate.format( m_start ); | |||
| exe.addArgument( dateRange ); | |||
| } | |||
| // Check if list of files to check has been specified | |||
| /* | |||
| if( !m_filesets.isEmpty() ) | |||
| { | |||
| final Enumeration e = m_filesets.elements(); | |||
| while( e.hasMoreElements() ) | |||
| { | |||
| final FileSet fileSet = (FileSet)e.nextElement(); | |||
| //FIXME: DOES NOT WORK | |||
| final DirectoryScanner scanner = new DirectoryScanner(); | |||
| //fileSet.getDirectoryScanner( null ); | |||
| final String[] files = scanner.getIncludedFiles(); | |||
| for( int i = 0; i < files.length; i++ ) | |||
| { | |||
| command.addArgument( files[ i ] ); | |||
| } | |||
| } | |||
| } | |||
| */ | |||
| final ChangeLogParser parser = new ChangeLogParser( userList, getContext() ); | |||
| exe.setExecOutputHandler( parser ); | |||
| exe.execute( getContext() ); | |||
| final CVSEntry[] entrySet = parser.getEntrySetAsArray(); | |||
| final CVSEntry[] filteredEntrySet = filterEntrySet( entrySet ); | |||
| writeChangeLog( filteredEntrySet ); | |||
| } | |||
| /** | |||
| * Validate the parameters specified for task. | |||
| * | |||
| * @throws TaskException if fails validation checks | |||
| */ | |||
| private void validate() | |||
| throws TaskException | |||
| { | |||
| if( null == m_dir ) | |||
| { | |||
| m_dir = getContext().getBaseDirectory(); | |||
| } | |||
| if( null == m_destfile ) | |||
| { | |||
| final String message = REZ.getString( "changelog.missing-destfile.error" ); | |||
| throw new TaskException( message ); | |||
| } | |||
| if( !m_dir.exists() ) | |||
| { | |||
| final String message = | |||
| REZ.getString( "changelog.bad-basedir.error", m_dir.getAbsolutePath() ); | |||
| throw new TaskException( message ); | |||
| } | |||
| if( null != m_usersFile && !m_usersFile.exists() ) | |||
| { | |||
| final String message = | |||
| REZ.getString( "changelog.bad-userlist.error", m_usersFile.getAbsolutePath() ); | |||
| throw new TaskException( message ); | |||
| } | |||
| } | |||
| /** | |||
| * Load the userli4st from the userList file (if specified) and | |||
| * add to list of users. | |||
| * | |||
| * @throws TaskException if file can not be loaded for some reason | |||
| */ | |||
| private void loadUserlist( final Properties userList ) | |||
| throws TaskException | |||
| { | |||
| if( null != m_usersFile ) | |||
| { | |||
| try | |||
| { | |||
| userList.load( new FileInputStream( m_usersFile ) ); | |||
| } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new TaskException( ioe.toString(), ioe ); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Filter the specified entrys accoridn to an appropriate | |||
| * rule. | |||
| * | |||
| * @param entrySet the entry set to filter | |||
| * @return the filtered entry set | |||
| */ | |||
| private CVSEntry[] filterEntrySet( final CVSEntry[] entrySet ) | |||
| { | |||
| final ArrayList results = new ArrayList(); | |||
| for( int i = 0; i < entrySet.length; i++ ) | |||
| { | |||
| final CVSEntry cvsEntry = entrySet[ i ]; | |||
| final Date date = cvsEntry.getDate(); | |||
| if( null != m_start && m_start.after( date ) ) | |||
| { | |||
| //Skip dates that are too early | |||
| continue; | |||
| } | |||
| if( null != m_stop && m_stop.before( date ) ) | |||
| { | |||
| //Skip dates that are too late | |||
| continue; | |||
| } | |||
| results.add( cvsEntry ); | |||
| } | |||
| return (CVSEntry[])results.toArray( new CVSEntry[ results.size() ] ); | |||
| } | |||
| /** | |||
| * Print changelog to file specified in task. | |||
| * | |||
| * @throws TaskException if theres an error writing changelog | |||
| */ | |||
| private void writeChangeLog( final CVSEntry[] entrySet ) | |||
| throws TaskException | |||
| { | |||
| FileOutputStream output = null; | |||
| try | |||
| { | |||
| output = new FileOutputStream( m_destfile ); | |||
| final PrintWriter writer = | |||
| new PrintWriter( new OutputStreamWriter( output, "UTF-8" ) ); | |||
| ChangeLogWriter serializer = new ChangeLogWriter(); | |||
| serializer.printChangeLog( writer, entrySet ); | |||
| } | |||
| catch( final UnsupportedEncodingException uee ) | |||
| { | |||
| getContext().error( uee.toString(), uee ); | |||
| } | |||
| catch( final IOException ioe ) | |||
| { | |||
| throw new TaskException( ioe.toString(), ioe ); | |||
| } | |||
| finally | |||
| { | |||
| IOUtil.shutdownStream( output ); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,269 +0,0 @@ | |||
| /* | |||
| * 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; | |||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
| import org.apache.avalon.excalibur.i18n.Resources; | |||
| import org.apache.myrmidon.api.TaskContext; | |||
| /** | |||
| * A class used to parse the output of the CVS log command. | |||
| * | |||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @version $Revision$ $Date$ | |||
| */ | |||
| class ChangeLogParser | |||
| implements ExecOutputHandler | |||
| { | |||
| private final static Resources REZ = | |||
| ResourceManager.getPackageResources( ChangeLogParser.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 hh:mm:ss" ); | |||
| //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; | |||
| private final TaskContext m_context; | |||
| /** 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 | |||
| */ | |||
| ChangeLogParser( final Properties userList, | |||
| final TaskContext context ) | |||
| { | |||
| m_userList = userList; | |||
| m_context = context; | |||
| } | |||
| /** | |||
| * 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 error. | |||
| */ | |||
| public void stderr( String line ) | |||
| { | |||
| m_context.error( line ); | |||
| } | |||
| /** | |||
| * 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 ); | |||
| 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( "======" ) ) | |||
| { | |||
| //We have ended changelog for that particular file | |||
| //so we can save it | |||
| final int end = m_comment.length() - lineSeparator.length(); //was -1 | |||
| m_comment = m_comment.substring( 0, end ); | |||
| saveEntry(); | |||
| m_status = GET_FILE; | |||
| } | |||
| else if( line.startsWith( "------" ) ) | |||
| { | |||
| final int end = m_comment.length() - lineSeparator.length(); //was -1 | |||
| m_comment = m_comment.substring( 0, end ); | |||
| 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; | |||
| } | |||
| else if( line.startsWith( "======" ) ) | |||
| { | |||
| //There was no revisions in this changelog | |||
| //entry so lets move unto next file | |||
| m_status = GET_FILE; | |||
| } | |||
| } | |||
| /** | |||
| * 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, 25 ); | |||
| String lineData = line.substring( line.indexOf( ";" ) + 1 ); | |||
| m_author = lineData.substring( 10, lineData.indexOf( ";" ) ); | |||
| if( m_userList.containsKey( m_author ) ) | |||
| { | |||
| m_author = m_userList.getProperty( 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 ) | |||
| { | |||
| if( !line.startsWith( "revision" ) ) | |||
| { | |||
| final String message = | |||
| REZ.getString( "changelog.unexpected.line", line ); | |||
| throw new IllegalStateException( message ); | |||
| } | |||
| m_previousRevision = line.substring( 9 ); | |||
| saveEntry(); | |||
| m_revision = m_previousRevision; | |||
| m_status = GET_DATE; | |||
| } | |||
| /** | |||
| * Utility method that saves the current entry. | |||
| */ | |||
| private void saveEntry() | |||
| { | |||
| final String entryKey = m_date + m_author + m_comment; | |||
| 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 ); | |||
| } | |||
| /** | |||
| * 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; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,75 +0,0 @@ | |||
| /* | |||
| * 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 <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @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( "<changelog>" ); | |||
| for( int i = 0; i < entries.length; i++ ) | |||
| { | |||
| final CVSEntry 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 | |||
| */ | |||
| private void printEntry( final PrintWriter output, final CVSEntry entry ) | |||
| { | |||
| output.println( "\t<entry>" ); | |||
| output.println( "\t\t<date>" + c_outputDate.format( entry.getDate() ) + "</date>" ); | |||
| output.println( "\t\t<time>" + c_outputTime.format( entry.getDate() ) + "</time>" ); | |||
| output.println( "\t\t<author><![CDATA[" + entry.getAuthor() + "]]></author>" ); | |||
| final Iterator iterator = entry.getFiles().iterator(); | |||
| while( iterator.hasNext() ) | |||
| { | |||
| final RCSFile file = (RCSFile)iterator.next(); | |||
| output.println( "\t\t<file>" ); | |||
| output.println( "\t\t\t<name>" + file.getName() + "</name>" ); | |||
| output.println( "\t\t\t<revision>" + file.getRevision() + "</revision>" ); | |||
| final String previousRevision = file.getPreviousRevision(); | |||
| if( previousRevision != null ) | |||
| { | |||
| output.println( "\t\t\t<prevrevision>" + previousRevision + "</prevrevision>" ); | |||
| } | |||
| output.println( "\t\t</file>" ); | |||
| } | |||
| output.println( "\t\t<msg><![CDATA[" + entry.getComment() + "]]></msg>" ); | |||
| output.println( "\t</entry>" ); | |||
| } | |||
| } | |||
| @@ -1,231 +0,0 @@ | |||
| /* | |||
| * 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.File; | |||
| import java.util.Properties; | |||
| import org.apache.myrmidon.api.AbstractTask; | |||
| import org.apache.myrmidon.api.TaskException; | |||
| import org.apache.myrmidon.framework.nativelib.Execute; | |||
| import org.apache.myrmidon.framework.nativelib.Commandline; | |||
| import org.apache.tools.todo.util.FileUtils; | |||
| /** | |||
| * Task to interact with a CVS repository. | |||
| * | |||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @author <a href="mailto:costin@dnt.ro">costin@dnt.ro</a> | |||
| * @author <a href="mailto:stefano@apache.org">stefano@apache.org</a> | |||
| * @author <a href="mailto:wwerner@picturesafe.de">Wolfgang Werner</a> | |||
| * @version $Revision$ $Date$ | |||
| * @ant.task name="cvs" | |||
| */ | |||
| public class Cvs | |||
| extends AbstractTask | |||
| { | |||
| /** | |||
| * the CVS command to execute. | |||
| */ | |||
| private String m_command = "checkout"; | |||
| /** | |||
| * suppress information messages. | |||
| */ | |||
| private boolean m_quiet; | |||
| /** | |||
| * report only, don't change any files. | |||
| */ | |||
| private boolean m_noexec; | |||
| /** | |||
| * CVS port | |||
| */ | |||
| private int m_port; | |||
| /** | |||
| * CVS password file | |||
| */ | |||
| private File m_passwordFile; | |||
| /** | |||
| * the CVSROOT variable. | |||
| */ | |||
| private String m_cvsRoot; | |||
| /** | |||
| * the CVS_RSH variable. | |||
| */ | |||
| private String m_cvsRsh; | |||
| /** | |||
| * the directory where the checked out files should be placed. | |||
| */ | |||
| private File m_dest; | |||
| /** | |||
| * the module to check out. | |||
| */ | |||
| private String m_module; | |||
| /** | |||
| * the date at which to extract files from repository | |||
| */ | |||
| private String m_date; | |||
| /** | |||
| * the tag with which to extract files from the repository | |||
| */ | |||
| private String m_tag; | |||
| public void setCommand( final String command ) | |||
| { | |||
| m_command = command; | |||
| } | |||
| public void setCvsRoot( final String cvsRoot ) | |||
| { | |||
| // Check if not real cvsroot => set it to null | |||
| m_cvsRoot = getNonEmptyString( cvsRoot ); | |||
| } | |||
| public void setCvsRsh( final String cvsRsh ) | |||
| { | |||
| // Check if not real cvsrsh => set it to null | |||
| m_cvsRsh = getNonEmptyString( cvsRsh ); | |||
| } | |||
| public void setDate( final String date ) | |||
| { | |||
| m_date = getNonEmptyString( date ); | |||
| } | |||
| public void setDest( final File dest ) | |||
| { | |||
| m_dest = dest; | |||
| } | |||
| public void setNoexec( final boolean noexec ) | |||
| { | |||
| m_noexec = noexec; | |||
| } | |||
| public void setModule( final String module ) | |||
| { | |||
| m_module = module; | |||
| } | |||
| public void setPassfile( final File passwordFile ) | |||
| { | |||
| m_passwordFile = passwordFile; | |||
| } | |||
| public void setPort( final int port ) | |||
| { | |||
| m_port = port; | |||
| } | |||
| public void setQuiet( final boolean quiet ) | |||
| { | |||
| m_quiet = quiet; | |||
| } | |||
| public void setTag( final String tag ) | |||
| { | |||
| m_tag = getNonEmptyString( tag ); | |||
| } | |||
| public void execute() | |||
| throws TaskException | |||
| { | |||
| final Execute exe = new Execute(); | |||
| buildCommandline( exe ); | |||
| final Properties env = buildEnvironment(); | |||
| exe.setWorkingDirectory( m_dest ); | |||
| exe.setEnvironment( env ); | |||
| exe.execute( getContext() ); | |||
| } | |||
| private Properties buildEnvironment() | |||
| { | |||
| final Properties env = new Properties(); | |||
| if( 0 < m_port ) | |||
| { | |||
| env.setProperty( "CVS_CLIENT_PORT", String.valueOf( m_port ) ); | |||
| } | |||
| if( null != m_passwordFile ) | |||
| { | |||
| env.setProperty( "CVS_PASSFILE", String.valueOf( m_passwordFile ) ); | |||
| } | |||
| if( null != m_cvsRsh ) | |||
| { | |||
| env.setProperty( "CVS_RSH", String.valueOf( m_cvsRsh ) ); | |||
| } | |||
| return env; | |||
| } | |||
| private void buildCommandline( final Commandline command ) throws TaskException | |||
| { | |||
| command.setExecutable( "cvs" ); | |||
| if( m_cvsRoot != null ) | |||
| { | |||
| command.addArgument( "-d" ); | |||
| command.addArgument( m_cvsRoot ); | |||
| } | |||
| if( m_noexec ) | |||
| { | |||
| command.addArgument( "-n" ); | |||
| } | |||
| if( m_quiet ) | |||
| { | |||
| command.addArgument( "-q" ); | |||
| } | |||
| command.addArguments( FileUtils.translateCommandline( m_command ) ); | |||
| if( null != m_date ) | |||
| { | |||
| command.addArgument( "-D" ); | |||
| command.addArgument( m_date ); | |||
| } | |||
| if( null != m_tag ) | |||
| { | |||
| command.addArgument( "-r" ); | |||
| command.addArgument( m_tag ); | |||
| } | |||
| if( m_module != null ) | |||
| { | |||
| command.addArguments( FileUtils.translateCommandline( m_module ) ); | |||
| } | |||
| } | |||
| private String getNonEmptyString( final String value ) | |||
| { | |||
| if( isEmpty( value ) ) | |||
| { | |||
| return null; | |||
| } | |||
| else | |||
| { | |||
| return value; | |||
| } | |||
| } | |||
| private boolean isEmpty( final String value ) | |||
| { | |||
| return ( null == value ) || ( 0 == value.trim().length() ); | |||
| } | |||
| } | |||
| @@ -1,64 +0,0 @@ | |||
| /* | |||
| * 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 org.apache.myrmidon.api.TaskException; | |||
| import org.apache.avalon.excalibur.i18n.Resources; | |||
| import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
| /** | |||
| * Represents a CVS user with a userID and a full name. | |||
| * | |||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> | |||
| * @version $Revision$ $Date$ | |||
| */ | |||
| public class CvsUser | |||
| { | |||
| private static final Resources REZ = | |||
| ResourceManager.getPackageResources( CvsUser.class ); | |||
| private String m_userID; | |||
| private String m_displayName; | |||
| public void setDisplayname( final String displayName ) | |||
| { | |||
| m_displayName = displayName; | |||
| } | |||
| public void setUserid( final String userID ) | |||
| { | |||
| m_userID = userID; | |||
| } | |||
| String getUserID() | |||
| { | |||
| return m_userID; | |||
| } | |||
| String getDisplayname() | |||
| { | |||
| return m_displayName; | |||
| } | |||
| void validate() | |||
| throws TaskException | |||
| { | |||
| if( null == m_userID ) | |||
| { | |||
| final String message = REZ.getString( "changelog.nouserid.error" ); | |||
| throw new TaskException( message ); | |||
| } | |||
| if( null == m_displayName ) | |||
| { | |||
| final String message = | |||
| REZ.getString( "changelog.nodisplayname.error", m_userID ); | |||
| throw new TaskException( message ); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,54 +0,0 @@ | |||
| /* | |||
| * 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; | |||
| /** | |||
| * Represents a RCS File cheange. | |||
| * | |||
| * @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
| * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> | |||
| * @version $Revision$ $Date$ | |||
| */ | |||
| class RCSFile | |||
| { | |||
| private final String m_name; | |||
| private final String m_revision; | |||
| private String m_previousRevision; | |||
| RCSFile( final String name, final String rev ) | |||
| { | |||
| this( name, rev, null ); | |||
| } | |||
| RCSFile( final String name, | |||
| final String revision, | |||
| final String previousRevision ) | |||
| { | |||
| m_name = name; | |||
| m_revision = revision; | |||
| if( !revision.equals( previousRevision ) ) | |||
| { | |||
| m_previousRevision = previousRevision; | |||
| } | |||
| } | |||
| String getName() | |||
| { | |||
| return m_name; | |||
| } | |||
| String getRevision() | |||
| { | |||
| return m_revision; | |||
| } | |||
| String getPreviousRevision() | |||
| { | |||
| return m_previousRevision; | |||
| } | |||
| } | |||
| @@ -1,14 +0,0 @@ | |||
| changelog.nodisplayname.error=Displayname attribute must be set for userID "{0}". | |||
| changelog.nouserid.error=Username attribute must be set. | |||
| changelog.missing-destfile.error=Destfile must be set. | |||
| changelog.bad-basedir.error=Cannot find base dir {0} | |||
| changelog.bad-userlist.error=Cannot find user lookup list {0}. | |||
| changelog.bat-date.error=I don't understand this date -> {0} | |||
| changelog.unexpected.line=Unexpected line from CVS: {0} | |||
| cvspass.nopassword.error=Password is required. | |||
| cvspass.noroot.error=Cvsroot is required. | |||
| cvspass.root.notice=cvsRoot: {0} | |||
| cvspass.password.notice=password: {0} | |||
| cvspass.passFile.notice=passFile: {0} | |||
| cvspass.write.notice=Writing -> {0} | |||