FileDocCategorySizeDatePackage
Pvcs.javaAPI DocApache Ant 1.7022597Wed Dec 13 06:16:20 GMT 2006org.apache.tools.ant.taskdefs.optional.pvcs

Pvcs

public class Pvcs extends org.apache.tools.ant.Task
Extracts the latest edition of the source code from a PVCS repository. PVCS is a version control system developed by Merant.
Before using this tag, the user running ant must have access to the commands of PVCS (get and pcli) and must have access to the repository. Note that the way to specify the repository is platform dependent so use property to specify location of repository.
This version has been tested agains PVCS version 6.5 and 6.6 under Windows and Solaris. 19-04-2001

The task now has a more robust parser. It allows for platform independant file paths and supports file names with (). Thanks to Erik Husby for bringing the bug to my attention. 27-04-2001

UNC paths are now handled properly. Fix provided by Don Jeffery. He also added an UpdateOnly flag that, when true, conditions the PVCS get using the -U option to only update those files that have a modification time (in PVCS) that is newer than the existing workfile. 25-10-2002

Added a revision attribute that currently is a synonym for label, but in a future release the behavior of the label attribute will change to use the -v option of GET. See bug #13847 for discussion.

Fields Summary
private static final int
POS_1
private static final int
POS_2
private static final int
POS_3
private String
pvcsbin
private String
repository
private String
pvcsProject
private Vector
pvcsProjects
private String
workspace
private String
force
private String
promotiongroup
private String
label
private String
revision
private boolean
ignorerc
private boolean
updateOnly
private String
filenameFormat
private String
lineStart
private String
userId
private String
config
private static final String
PCLI_EXE
Constant for the thing to execute
private static final String
GET_EXE
Constant for the thing to execute
Constructors Summary
public Pvcs()
Creates a Pvcs object

        super();
        pvcsProject = null;
        pvcsProjects = new Vector();
        workspace = null;
        repository = null;
        pvcsbin = null;
        force = null;
        promotiongroup = null;
        label = null;
        ignorerc = false;
        updateOnly = false;
        lineStart = "\"P:";
        filenameFormat = "{0}-arc({1})";
    
Methods Summary
public voidaddPvcsproject(PvcsProject p)
Specify a project within the PVCS repository to extract files from.

param
p the pvcs project to use.

        pvcsProjects.addElement(p);
    
private voidcreateFolders(java.io.File file)
Parses the file and creates the folders specified in the output section

        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(file));
            MessageFormat mf = new MessageFormat(getFilenameFormat());
            String line = in.readLine();
            while (line != null) {
                log("Considering \"" + line + "\"", Project.MSG_VERBOSE);
                if (line.startsWith("\"\\")    // Checking for "\
                    || line.startsWith("\"/")  // or           "/
                                               // or           "X:\...
                   || (line.length() > POS_3 && line.startsWith("\"")
                        && Character.isLetter(line.charAt(POS_1))
                        && String.valueOf(line.charAt(POS_2)).equals(":")
                        && String.valueOf(line.charAt(POS_3)).equals("\\"))) {
                    Object[] objs = mf.parse(line);
                    String f = (String) objs[1];
                    // Extract the name of the directory from the filename
                    int index = f.lastIndexOf(File.separator);
                    if (index > -1) {
                        File dir = new File(f.substring(0, index));
                        if (!dir.exists()) {
                            log("Creating " + dir.getAbsolutePath(),
                                Project.MSG_VERBOSE);
                            if (dir.mkdirs()) {
                                log("Created " + dir.getAbsolutePath(),
                                    Project.MSG_INFO);
                            } else {
                                log("Failed to create "
                                    + dir.getAbsolutePath(),
                                    Project.MSG_INFO);
                            }
                        } else {
                            log(dir.getAbsolutePath() + " exists. Skipping",
                                Project.MSG_VERBOSE);
                        }
                    } else {
                        log("File separator problem with " + line,
                            Project.MSG_WARN);
                    }
                } else {
                    log("Skipped \"" + line + "\"", Project.MSG_VERBOSE);
                }
                line = in.readLine();
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
    
public voidexecute()

exception
org.apache.tools.ant.BuildException Something is stopping the build...

        int result = 0;

        if (repository == null || repository.trim().equals("")) {
            throw new BuildException("Required argument repository not specified");
        }

        // Check workspace exists
        // Launch PCLI listversionedfiles -z -aw
        // Capture output
        // build the command line from what we got the format is
        Commandline commandLine = new Commandline();
        commandLine.setExecutable(getExecutable(PCLI_EXE));

        commandLine.createArgument().setValue("lvf");
        commandLine.createArgument().setValue("-z");
        commandLine.createArgument().setValue("-aw");
        if (getWorkspace() != null) {
            commandLine.createArgument().setValue("-sp" + getWorkspace());
        }
        commandLine.createArgument().setValue("-pr" + getRepository());

        String uid = getUserId();

        if (uid != null) {
            commandLine.createArgument().setValue("-id" + uid);
        }

        // default pvcs project is "/"
        if (getPvcsproject() == null && getPvcsprojects().isEmpty()) {
            pvcsProject = "/";
        }

        if (getPvcsproject() != null) {
            commandLine.createArgument().setValue(getPvcsproject());
        }
        if (!getPvcsprojects().isEmpty()) {
            Enumeration e = getPvcsprojects().elements();
            while (e.hasMoreElements()) {
                String projectName = ((PvcsProject) e.nextElement()).getName();
                if (projectName == null || (projectName.trim()).equals("")) {
                    throw new BuildException("name is a required attribute "
                        + "of pvcsproject");
                }
                commandLine.createArgument().setValue(projectName);
            }
        }

        File tmp = null;
        File tmp2 = null;
        try {
            Random rand = new Random(System.currentTimeMillis());
            tmp = new File("pvcs_ant_" + rand.nextLong() + ".log");
            FileOutputStream fos = new FileOutputStream(tmp);
            tmp2 = new File("pvcs_ant_" + rand.nextLong() + ".log");
            log(commandLine.describeCommand(), Project.MSG_VERBOSE);
            try {
                result = runCmd(commandLine,
                                new PumpStreamHandler(fos,
                                    new LogOutputStream(this,
                                                        Project.MSG_WARN)));
            } finally {
                fos.close();
            }

            if (Execute.isFailure(result) && !ignorerc) {
                String msg = "Failed executing: " + commandLine.toString();
                throw new BuildException(msg, getLocation());
            }

            if (!tmp.exists()) {
                throw new BuildException("Communication between ant and pvcs "
                    + "failed. No output generated from executing PVCS "
                    + "commandline interface \"pcli\" and \"get\"");
            }

            // Create folders in workspace
            log("Creating folders", Project.MSG_INFO);
            createFolders(tmp);

            // Massage PCLI lvf output transforming '\' to '/' so get command works appropriately
            massagePCLI(tmp, tmp2);

            // Launch get on output captured from PCLI lvf
            commandLine.clearArgs();
            commandLine.setExecutable(getExecutable(GET_EXE));

            if (getConfig() != null && getConfig().length() > 0) {
                commandLine.createArgument().setValue("-c" + getConfig());
            }

            if (getForce() != null && getForce().equals("yes")) {
                commandLine.createArgument().setValue("-Y");
            } else {
                commandLine.createArgument().setValue("-N");
            }

            if (getPromotiongroup() != null) {
                commandLine.createArgument().setValue("-G"
                    + getPromotiongroup());
            } else {
                if (getLabel() != null) {
                    commandLine.createArgument().setValue("-v" + getLabel());
                } else {
                    if (getRevision() != null) {
                        commandLine.createArgument().setValue("-r"
                            + getRevision());
                    }
                }
            }

            if (updateOnly) {
                commandLine.createArgument().setValue("-U");
            }

            commandLine.createArgument().setValue("@" + tmp2.getAbsolutePath());
            log("Getting files", Project.MSG_INFO);
            log("Executing " + commandLine.toString(), Project.MSG_VERBOSE);
            result = runCmd(commandLine,
                new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN));
            if (result != 0 && !ignorerc) {
                String msg = "Failed executing: " + commandLine.toString()
                    + ". Return code was " + result;
                throw new BuildException(msg, getLocation());
            }

        } catch (FileNotFoundException e) {
            String msg = "Failed executing: " + commandLine.toString()
                + ". Exception: " + e.getMessage();
            throw new BuildException(msg, getLocation());
        } catch (IOException e) {
            String msg = "Failed executing: " + commandLine.toString()
                + ". Exception: " + e.getMessage();
            throw new BuildException(msg, getLocation());
        } catch (ParseException e) {
            String msg = "Failed executing: " + commandLine.toString()
                + ". Exception: " + e.getMessage();
            throw new BuildException(msg, getLocation());
        } finally {
            if (tmp != null) {
                tmp.delete();
            }
            if (tmp2 != null) {
                tmp2.delete();
            }
        }
    
public java.lang.StringgetConfig()
returns the path of the configuration file to be used

return
the path of the config file

        return config;
    
private java.lang.StringgetExecutable(java.lang.String exe)

        StringBuffer correctedExe = new StringBuffer();
        if (getPvcsbin() != null) {
            if (pvcsbin.endsWith(File.separator)) {
                correctedExe.append(pvcsbin);
            } else {
                correctedExe.append(pvcsbin).append(File.separator);
            }
        }
        return correctedExe.append(exe).toString();
    
public java.lang.StringgetFilenameFormat()
The filenameFormat attribute defines a MessageFormat string used to parse the output of the pcli command. It defaults to {0}-arc({1}). Repositories where the archive extension is not -arc should set this.

return
the filename format attribute.

        return filenameFormat;
    
public java.lang.StringgetForce()
Get value of force

return
String

        return force;
    
public booleangetIgnoreReturnCode()
Get value of ignorereturncode

return
String

        return ignorerc;
    
public java.lang.StringgetLabel()
Get value of label

return
String

        return label;
    
public java.lang.StringgetLineStart()
The lineStart attribute is used to parse the output of the pcli command. It defaults to "P:. The parser already knows about / and \\, this property is useful in cases where the repository is accessed on a Windows platform via a drive letter mapping.

return
the lineStart attribute.

        return lineStart;
    
public java.lang.StringgetPromotiongroup()
Get value of promotiongroup

return
String

        return promotiongroup;
    
public java.lang.StringgetPvcsbin()
Get name of the PVCS bin directory

return
String

        return pvcsbin;
    
public java.lang.StringgetPvcsproject()
Get name of the project in the PVCS repository

return
String

        return pvcsProject;
    
public java.util.VectorgetPvcsprojects()
Get name of the project in the PVCS repository

return
Vector

        return pvcsProjects;
    
public java.lang.StringgetRepository()
Get network name of the PVCS repository

return
String

        return repository;
    
public java.lang.StringgetRevision()
Get value of revision

return
String

        return revision;
    
public booleangetUpdateOnly()
get the updateOnly attribute.

return
the updateOnly attribute.

        return updateOnly;
    
public java.lang.StringgetUserId()
Get the userid.

return
the userid.

        return userId;
    
public java.lang.StringgetWorkspace()
Get name of the workspace to store the retrieved files

return
String

        return workspace;
    
private voidmassagePCLI(java.io.File in, java.io.File out)
Simple hack to handle the PVCS command-line tools botch when handling UNC notation.

throws
IOException if there is an error.

        BufferedReader inReader = null;
        BufferedWriter outWriter = null;
        try {
            inReader = new BufferedReader(new FileReader(in));
            outWriter = new BufferedWriter(new FileWriter(out));
            String s = null;
            while ((s = inReader.readLine()) != null) {
                String sNormal = s.replace('\\", '/");
                outWriter.write(sNormal);
                outWriter.newLine();
            }
        } finally {
            if (inReader != null) {
                inReader.close();
            }
            if (outWriter != null) {
                outWriter.close();
            }
        }
    
protected intrunCmd(org.apache.tools.ant.types.Commandline cmd, org.apache.tools.ant.taskdefs.ExecuteStreamHandler out)
Run the command.

param
cmd the command line to use.
param
out the output stream handler to use.
return
the exit code of the command.



                                  
          
        try {
            Project aProj = getProject();
            Execute exe = new Execute(out);
            exe.setAntRun(aProj);
            exe.setWorkingDirectory(aProj.getBaseDir());
            exe.setCommandline(cmd.getCommandline());
            return exe.execute();
        } catch (java.io.IOException e) {
            String msg = "Failed executing: " + cmd.toString()
                + ". Exception: " + e.getMessage();
            throw new BuildException(msg, getLocation());
        }
    
public voidsetConfig(java.io.File f)
Sets a configuration file other than the default to be used. These files have a .cfg extension and are often found in archive or pvcsprop folders.

param
f config file - can be given absolute or relative to ant basedir

        config = f.toString();
    
public voidsetFilenameFormat(java.lang.String f)
The format of the folder names; optional. This must be in a format suitable for java.text.MessageFormat. Index 1 of the format will be used as the file name. Defaults to {0}-arc({1})

param
f the format to use.

        filenameFormat = f;
    
public voidsetForce(java.lang.String f)
Specifies the value of the force argument; optional. If set to yes all files that exists and are writable are overwritten. Default no causes the files that are writable to be ignored. This stops the PVCS command get to stop asking questions!

todo
make a boolean setter
param
f String (yes/no)

        if (f != null && f.equalsIgnoreCase("yes")) {
            force = "yes";
        } else {
            force = "no";
        }
    
public voidsetIgnoreReturnCode(boolean b)
If set to true the return value from executing the pvcs commands are ignored; optional, default false.

param
b a boolean value.

        ignorerc = b;
    
public voidsetLabel(java.lang.String l)
Only files marked with this label are extracted; optional.

param
l String

        label = l;
    
public voidsetLineStart(java.lang.String l)
What a valid return value from PVCS looks like when it describes a file. Defaults to "P:. If you are not using an UNC name for your repository and the drive letter P is incorrect for your setup, you may need to change this value, UNC names will always be accepted.

param
l the value to use.

        lineStart = l;
    
public voidsetPromotiongroup(java.lang.String w)
Specifies the name of the promotiongroup argument

param
w String

        promotiongroup = w;
    
public voidsetPvcsbin(java.lang.String bin)
Specifies the location of the PVCS bin directory; optional if on the PATH. On some systems the PVCS executables pcli and get are not found in the PATH. In such cases this attribute should be set to the bin directory of the PVCS installation containing the executables mentioned before. If this attribute isn't specified the tag expects the executables to be found using the PATH environment variable.

param
bin PVCS bin directory
todo
use a File setter and resolve paths.

        pvcsbin = bin;
    
public voidsetPvcsproject(java.lang.String prj)
The project within the PVCS repository to extract files from; optional, default "/"

param
prj String

        pvcsProject = prj;
    
public voidsetRepository(java.lang.String repo)
The network name of the PVCS repository; required.

param
repo String

        repository = repo;
    
public voidsetRevision(java.lang.String r)
Only files with this revision are extract; optional.

param
r String

        revision = r;
    
public voidsetUpdateOnly(boolean l)
If set to true files are fetched only if newer than existing local files; optional, default false.

param
l a boolean value.

        updateOnly = l;
    
public voidsetUserId(java.lang.String u)
User ID

param
u the value to use.

        userId = u;
    
public voidsetWorkspace(java.lang.String ws)
Workspace to use; optional. By specifying a workspace, the files are extracted to that location. A PVCS workspace is a name for a location of the workfiles and isn't as such the location itself. You define the location for a workspace using the PVCS GUI clients. If this isn't specified the default workspace for the current user is used.

param
ws String

        workspace = ws;