package org.apache.maven.vsslib;
/*
* ====================================================================
* Copyright 2001-2004 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.
* ====================================================================
*/
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.maven.changelog.AbstractChangeLogGenerator;
import org.apache.maven.changelog.ChangeLogEntry;
import org.apache.maven.changelog.ChangeLogGenerator;
import org.apache.maven.changelog.ChangeLogParser;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.types.Commandline;
/*******************************************************************************
* A Visual Source Safe implementation of the
* {@link org.apache.maven.changelog.ChangeLogGenerator}interface realized
* extending the {@link org.apache.maven.changelog.AbstractChangeLogGenerator}.
*
* The command line build by this class uses the ss History VSS
* command and formats the output in a way the VssChangeLogParser can
* understand. Due to this fact this implementations works only if used within a
* vss view.
*
* The command looks like this:
*
* set ssdir=vssRepositoryPath ss History vssProject -YvssUserId,vssUserPassword * -R -Vd01/12/04~23/11/04 -I-Y * * @author Freddy Mallet */ public class VssChangeLogGenerator extends AbstractChangeLogGenerator { /** * Log */ private static final Log LOG = LogFactory .getLog(VssChangeLogGenerator.class); /*************************************************************************** * Constructs the appropriate command line to execute the scm's log command. * For Clearcase it's lshistory. * * @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmLogCommand() * @return The command line to be executed. */ protected Commandline getScmLogCommand() { VssConnection vssConnection = new VssConnection(getConnection()); Commandline command = new Commandline(); command.setExecutable("ss"); command.createArgument().setValue("History"); command.createArgument().setValue("$" + vssConnection.getVssProject()); //User identification to get access to vss repository if(vssConnection.getVssUserInf() != null){ command.createArgument().setValue("-Y" + vssConnection.getVssUserInf()); } //Display the history of an entire project list command.createArgument().setValue("-R"); //Ignore: Do not ask for input under any circumstances. command.createArgument().setValue("-I-"); //Display only versions that fall within specified data range. if (dateRange != null) { command.createArgument().setValue("-Vd" + dateRange); } return command; } /*************************************************************************** * Construct the command-line argument that is passed to the scm client to * specify the appropriate date range. * * @param before * The starting point. * @param to * The ending point. * @return A string that can be used to specify a date to a scm system. * * @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmDateArgument(java.util.Date, * java.util.Date) */ protected String getScmDateArgument(Date before, Date to) { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH); String result = sdf.format(to) + "~" + sdf.format(before); return result; } /** * Convert date range from 'number of days' format to 'date to date' format * * @param numDaysString * String */ public void setDateRange(String numDaysString) { int days = Integer.parseInt(numDaysString); Date before = new Date(System.currentTimeMillis() - (long) days * 24 * 60 * 60 * 1000); Date to = new Date(System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000); } /*************************************************************************** * Execute vss client driving the given parser. This method has been * overwritten to be able to set 'SSDIR' environment variable. This variable * set the vss repository * * @param parser * A {@link ChangeLogParser parser}to process the vss output. * @return A collection of {@link ChangeLogEntry entries}parsed from the * vss output. * @throws IOException * When there are issues executing vss. * @see ChangeLogGenerator#getEntries(ChangeLogParser) */ public Collection getEntries(ChangeLogParser parser) throws IOException { if (parser == null) { throw new NullPointerException("parser cannot be null"); } if (base == null) { throw new NullPointerException("basedir must be set"); } if (!base.exists()) { throw new FileNotFoundException("Cannot find base dir " + base.getAbsolutePath()); } clParser = parser; try { VssConnection vssConnection = new VssConnection(getConnection()); Execute exe = new Execute(this); String[] env = exe.getEnvironment(); if (env == null) { env = new String[0]; } String[] newEnv = new String[env.length + 1]; for (int i = 0; i < env.length; i++) { newEnv[i] = env[i]; } newEnv[env.length] = "SSDIR=" + vssConnection.getVssDir(); exe.setEnvironment(newEnv); exe.setCommandline(getScmLogCommand().getCommandline()); //exe.setVMLauncher(false); exe.setWorkingDirectory(base); logExecute(exe, base); exe.execute(); // log messages from stderr String errors = errorReader.toString().trim(); if (errors.length() > 0) { LOG.error(errors); } } catch (IOException ioe) { handleParserException(ioe); } return entries; } }