From 0389ea10a4687f078052de61ff19b5c43171ad44 Mon Sep 17 00:00:00 2001 From: Stephane Bailliez Date: Mon, 14 Jan 2002 22:19:47 +0000 Subject: [PATCH] - New tasks StarTeamCheckin and StarTeamList - Modify StarTeamCheckin, Add ability to check files out either locked or unlocked. (Previously task left lock status alone.) - Modify docs for all of the above. - Fix JavaDoc tags (SB) PR: 5650 Patch by: stevec@ignitesports.com (Steve Cohen) git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270762 13f79535-47bb-0310-9956-ffa450edef68 --- .../optional/starteam/StarTeamCheckin.java | 324 ++++++++++++++++++ .../optional/starteam/StarTeamCheckout.java | 76 +++- .../optional/starteam/StarTeamLabel.java | 38 +- .../optional/starteam/StarTeamList.java | 217 ++++++++++++ .../optional/starteam/StarTeamTask.java | 230 ++++++++----- .../optional/starteam/TreeBasedTask.java | 66 ++-- 6 files changed, 809 insertions(+), 142 deletions(-) create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java new file mode 100644 index 000000000..8da46305a --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckin.java @@ -0,0 +1,324 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.tools.ant.taskdefs.optional.starteam; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; + +import com.starbase.starteam.File; +import com.starbase.starteam.Folder; +import com.starbase.starteam.Item; +import com.starbase.starteam.Status; +import com.starbase.starteam.View; +import com.starbase.starteam.ViewConfiguration; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +/** + * StarTeamCheckIn.java + * + * + * Created: Sat Dec 15 20:26:07 2001 + * + * @author Steve Cohen + * @version 1.0 + */ +public class StarTeamCheckin extends TreeBasedTask { + + public StarTeamCheckin() { + // we want this to have a false default, unlike for Checkin. + setRecursive(false); + } + + private boolean createFolders = true; + + /** + * The comment which will be stored with the checkin. + */ + private String comment = null; + + /** + * holder for the add Uncontrolled attribute. If true, all + * local files not in StarTeam will be added to the repository. + */ + private boolean addUncontrolled = false; + + /** + * Sets the value of createFolders + * + * @param argCreateFolders Value to assign to this.createFolders + */ + public void setCreateFolders(boolean argCreateFolders) { + this.createFolders = argCreateFolders; + } + + + /** + * Get the comment attribute for this operation + * @return value of comment. + */ + public String getComment() { + return this.comment; + } + + /** + * Set the value of comment. + * @param comment Value to assign to comment. + */ + public void setComment(String comment) { + this.comment = comment; + } + + /** + * Get the value of addUncontrolled. + * @return value of addUncontrolled. + */ + public boolean isAddUncontrolled() { + return this.addUncontrolled; + } + + /** + * Set the value of addUncontrolled. + * @param addUncontrolled Value to assign to addUncontrolled. + */ + public void setAddUncontrolled(boolean addUncontrolled) { + this.addUncontrolled = addUncontrolled; + } + + /** + * This attribute tells whether unlocked files on checkin (so that + * other users may access them) checkout or to leave the checkout status + * alone (default). + * @see setUnlocked() + */ + private int lockStatus = Item.LockType.UNCHANGED; + + /** + * Set to do an unlocked checkout. Default is false; + * @param v true means do an unlocked checkout + * false means leave status alone. + */ + public void setUnlocked(boolean v) { + if (v) { + this.lockStatus = Item.LockType.UNLOCKED; + } else { + this.lockStatus = Item.LockType.UNCHANGED; + } + } + + /** + * Override of base-class abstract function creates an + * appropriately configured view. For checkins this is + * always the current or "tip" view. + * + * @param raw the unconfigured View + * @return the snapshot View appropriately configured. + */ + protected View createSnapshotView(View raw) { + return new View(raw, ViewConfiguration.createTip()); + } + + /** + * Implements base-class abstract function to define tests for + * any preconditons required by the task + * + * @exception BuildException not thrown in this implementation + */ + protected void testPreconditions() throws BuildException { + if (null != getRootLocalFolder() && !isForced()) { + log("Warning: rootLocalFolder specified, but forcing off.", + Project.MSG_WARN); + } + } + + /** + * Implements base-class abstract function to perform the checkout + * operation on the files in each folder of the tree. + * + * @param starteamFolder the StarTeam folder to which files + * will be checked in + * @param localFolder local folder from which files will be checked in + * @exception BuildException if any error occurs + */ + protected void visit(Folder starteamFolder, java.io.File targetFolder) + throws BuildException { + try { + Hashtable localFiles = listLocalFiles(targetFolder); + + // If we have been told to create the working folders + // For all Files in this folder, we need to check + // if there have been modifications. + + Item[] files = starteamFolder.getItems("File"); + for (int i = 0; i < files.length; i++) { + File eachFile = (File) files[i]; + String filename = eachFile.getName(); + java.io.File localFile = + new java.io.File(targetFolder, filename); + + delistLocalFile(localFiles, localFile); + + // If the file doesn't pass the include/exclude tests, skip it. + if (!shouldProcess(filename)) { + log("Skipping " + eachFile.toString(), Project.MSG_INFO); + continue; + } + + + // If forced is not set then we may save ourselves some work by + // looking at the status flag. + // Otherwise, we care nothing about these statuses. + + if (!isForced()) { + int fileStatus = (eachFile.getStatus()); + + // We try to update the status once to give StarTeam + // another chance. + if (fileStatus == Status.MERGE + || fileStatus == Status.UNKNOWN) { + eachFile.updateStatus(true, true); + fileStatus = (eachFile.getStatus()); + } + if (fileStatus == Status.CURRENT) { + log("Not processing " + eachFile.toString() + + " as it is current.", + Project.MSG_INFO); + continue; + } + } + + // Check in anything else. + + log("Checking In: " + (localFile.toString()), Project.MSG_INFO); + eachFile.checkinFrom(localFile, this.comment, + this.lockStatus, + true, true, true); + } + + // Now we recursively call this method on all sub folders in this + // folder unless recursive attribute is off. + Folder[] subFolders = starteamFolder.getSubFolders(); + for (int i = 0; i < subFolders.length; i++) { + java.io.File targetSubfolder = + new java.io.File(targetFolder, subFolders[i].getName()); + delistLocalFile(localFiles, targetSubfolder); + + if (isRecursive()) { + visit(subFolders[i], targetSubfolder); + } + } + if (this.addUncontrolled) { + addUncontrolledItems(localFiles, starteamFolder); + } + + + } catch (IOException e) { + throw new BuildException(e); + } + } + + /** + * Adds to the StarTeam repository everything on the local machine that + * is not currently in the repository. + * @param folder - StarTeam folder to which these items are to be added. + */ + private void addUncontrolledItems(Hashtable localFiles, Folder folder) + throws IOException { + try { + Enumeration e = localFiles.keys(); + while (e.hasMoreElements()) { + java.io.File file = + new java.io.File(e.nextElement().toString()); + add(folder, file); + } + } catch (SecurityException e) { + log("Error adding file: " + e, Project.MSG_ERR); + } + } + + /** + * Deletes the file from the local drive. + * @param file the file or directory to delete. + * @return true if the file was successfully deleted otherwise false. + */ + private void add(Folder parentFolder, java.io.File file) + throws IOException { + // If the current file is a Directory, we need to process all + // of its children as well. + if (file.isDirectory()) { + log("Adding new folder to repository: " + file.getAbsolutePath(), + Project.MSG_INFO); + Folder newFolder = new Folder(parentFolder); + newFolder.setName(file.getName()); + newFolder.update(); + + // now visit this new folder to take care of adding any files + // or subfolders within it. + if (isRecursive()) { + visit(newFolder, file); + } + } else { + log("Adding new file to repository: " + file.getAbsolutePath(), + Project.MSG_INFO); + File newFile = new File(parentFolder); + newFile.addFromStream(new FileInputStream(file), + file.getName(), + null, this.comment, 3, true); + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java index 5ffb39bed..58e1efb7d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamCheckout.java @@ -56,6 +56,7 @@ package org.apache.tools.ant.taskdefs.optional.starteam; import java.io.IOException; import java.util.Enumeration; +import java.util.Hashtable; import com.starbase.starteam.File; import com.starbase.starteam.Folder; @@ -79,8 +80,8 @@ import org.apache.tools.ant.Project; * @author Christopher Charlier, ThoughtWorks, Inc. 2001 * @author Jason Yip * @author Jason Pettiss - * @version 1.1 * @author Steve Cohen + * @version 1.1 * @see StarBase Web Site */ public class StarTeamCheckout extends TreeBasedTask { @@ -125,6 +126,49 @@ public class StarTeamCheckout extends TreeBasedTask { _setLabel(label); } + /** + * This attribute tells whether to do a locked checkout, an unlocked + * checkout or to leave the checkout status alone (default). A locked + * checkout locks all other users out from making changes. An unlocked + * checkout reverts all local files to their previous repository status + * and removes the lock. + * @see setLocked() + * @see setUnlocked() + */ + private int lockStatus = Item.LockType.UNCHANGED; + + /** + * Set to do a locked checkout. Default is false. + * @param v True to do a locked checkout, false to checkout without + * changing status/. + * @exception BuildException if both locked and unlocked are set true + */ + public void setLocked(boolean v) throws BuildException { + setLockStatus(v, Item.LockType.EXCLUSIVE); + } + + + /** + * Set to do an unlocked checkout. Default is false; + * @param v True to do an unlocked checkout, false to checkout without + * changing status. + * @exception BuildException if both locked and unlocked are set true + */ + public void setUnlocked(boolean v) throws BuildException { + setLockStatus(v, Item.LockType.UNLOCKED); + } + + private void setLockStatus(boolean v, int newStatus) + throws BuildException { + if (v) { + if (this.lockStatus == Item.LockType.UNCHANGED) { + this.lockStatus = newStatus; + } else if (this.lockStatus != newStatus) { + throw new BuildException( + "Error: cannot set locked and unlocked both true."); + } + } + } /** * Override of base-class abstract function creates an @@ -147,6 +191,19 @@ public class StarTeamCheckout extends TreeBasedTask { } } + /** + * Implements base-class abstract function to define tests for + * any preconditons required by the task + * + * @exception BuildException not thrown in this implementation + */ + protected void testPreconditions() throws BuildException { + if (null != getRootLocalFolder() && !isForced()) { + log("Warning: rootLocalFolder specified, but forcing off.", + Project.MSG_WARN); + } + } + /** * Implements base-class abstract function to perform the checkout * operation on the files in each folder of the tree. @@ -154,11 +211,12 @@ public class StarTeamCheckout extends TreeBasedTask { * @param starteamFolder the StarTeam folder from which files to be * checked out * @param targetFolder the local mapping of rootStarteamFolder + * @exception BuildException if any error occurs */ protected void visit(Folder starteamFolder, java.io.File targetFolder) throws BuildException { try { - listLocalFiles(targetFolder); + Hashtable localFiles = listLocalFiles(targetFolder); // If we have been told to create the working folders if (createDirs) { @@ -177,7 +235,7 @@ public class StarTeamCheckout extends TreeBasedTask { java.io.File localFile = new java.io.File(targetFolder, filename); - delistLocalFile(localFile); + delistLocalFile(localFiles, localFile); // If the file doesn't pass the include/exclude tests, skip it. if (!shouldProcess(filename)) { @@ -221,7 +279,7 @@ public class StarTeamCheckout extends TreeBasedTask { // about losing anything. log("Checking Out: " + (localFile.toString()), Project.MSG_INFO); - eachFile.checkoutTo(localFile, Item.LockType.UNCHANGED, + eachFile.checkoutTo(localFile, this.lockStatus, true, true, true); } @@ -231,14 +289,14 @@ public class StarTeamCheckout extends TreeBasedTask { for (int i = 0; i < subFolders.length; i++) { java.io.File targetSubfolder = new java.io.File(targetFolder, subFolders[i].getName()); - delistLocalFile(targetSubfolder); + delistLocalFile(localFiles, targetSubfolder); if (isRecursive()) { visit(subFolders[i], targetSubfolder); } } if (this.deleteUncontrolled) { - deleteUncontrolledItems(); + deleteUncontrolledItems(localFiles); } } catch (IOException e) { @@ -249,10 +307,12 @@ public class StarTeamCheckout extends TreeBasedTask { /** * Deletes everything on the local machine that is not in the repository. + * + * @param localFiles the list of filenames whose elements are to be deleted */ - private void deleteUncontrolledItems() { + private void deleteUncontrolledItems(Hashtable localFiles) { try { - Enumeration e = getLocalFiles().keys(); + Enumeration e = localFiles.keys(); while (e.hasMoreElements()) { java.io.File file = new java.io.File(e.nextElement().toString()); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java index 6366bef48..efd7660ad 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamLabel.java @@ -59,22 +59,19 @@ import java.text.SimpleDateFormat; import java.util.Date; import com.starbase.starteam.Label; -import com.starbase.starteam.ServerException; -import com.starbase.starteam.StarTeamFinder; import com.starbase.starteam.View; import com.starbase.starteam.ViewConfiguration; -import com.starbase.starteam.vts.comm.CommandException; import com.starbase.util.OLEDate; import org.apache.tools.ant.BuildException; /** * This class logs into StarTeam and creates a label for the repository at the - * time of the last successful build. - * Ant Usage: + * time of the last successful build. + * Ant Usage: * - * @@ -99,9 +96,9 @@ public class StarTeamLabel extends StarTeamTask { * The time of the last successful. The new label will be a snapshot of the * repository at this time. String should be formatted as "yyyyMMddHHmmss" */ - private Date lastBuildTime; + private OLEDate lastBuild = null; - private static final SimpleDateFormat DATE_FORMAT = + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss"); @@ -115,7 +112,8 @@ public class StarTeamLabel extends StarTeamTask { public void setLastBuild(String lastbuild) throws BuildException { try { - lastBuildTime = DATE_FORMAT.parse(lastbuild); + Date lastBuildTime = DATE_FORMAT.parse(lastbuild); + this.lastBuild = new OLEDate(lastBuildTime); } catch (ParseException e) { throw new BuildException("Unable to parse the date '" + lastbuild + "'", e); } @@ -127,16 +125,24 @@ public class StarTeamLabel extends StarTeamTask { * */ public void execute() throws BuildException { - OLEDate buildDate = new OLEDate(lastBuildTime); - // Get view as of the last successful build time. - View view = StarTeamFinder.openView(getUserName() + ":" + getPassword() - + "@" + getURL()); - View snapshot = new View(view, ViewConfiguration.createFromTime(buildDate)); + View snapshot = openView(); // Create the new label and update the repository - new Label(snapshot, labelName, description, buildDate, true).update(); - log("Created Label " + labelName); + new Label(snapshot, labelName, description, this.lastBuild, true).update(); + log("Created Label " + labelName); + } + + /** + * Override of base-class abstract function creates an + * appropriately configured view. For labels this a view + * configured as of this.lastBuild. + * + * @param raw the unconfigured View + * @return the snapshot View appropriately configured. + */ + protected View createSnapshotView(View raw) { + return new View(raw, ViewConfiguration.createFromTime(this.lastBuild)); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java new file mode 100644 index 000000000..68f0c75ef --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java @@ -0,0 +1,217 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.tools.ant.taskdefs.optional.starteam; + +import java.io.IOException; +import java.util.Hashtable; + +import com.starbase.starteam.File; +import com.starbase.starteam.Folder; +import com.starbase.starteam.Item; +import com.starbase.starteam.Status; +import com.starbase.starteam.View; +import com.starbase.starteam.ViewConfiguration; + +import org.apache.tools.ant.BuildException; + +/** + * StarTeamList.java + * + * + * Created: Tue Dec 25 06:51:14 2001 + * + * @author Steve Cohen + * @version 1.0 + */ + +public class StarTeamList extends TreeBasedTask { + /** + * Sets the label StarTeam is to be listed. + * + * @param label the label to be listed + */ + public void setLabel(String label) { + _setLabel(label); + } + + /** + * Override of base-class abstract function creates an + * appropriately configured view for checkoutlists - either + * the current view or a view from this.label. + * + * @param raw the unconfigured View + * @return the snapshot View appropriately configured. + */ + protected View createSnapshotView(View raw) { + + int labelID = getLabelID(raw); + + // if a label has been supplied, use it to configure the view + // otherwise use current view + if (labelID >= 0) { + return new View(raw, ViewConfiguration.createFromLabel(labelID)); + } else { + return new View(raw, ViewConfiguration.createTip()); + } + } + + /** + * Required base-class abstract function implementation is a no-op here. + * + * @exception BuildException not thrown in this implementation + */ + protected void testPreconditions() throws BuildException { + //intentionally do nothing. + } + + /** + * Implements base-class abstract function to perform the checkout + * operation on the files in each folder of the tree. + * + * @param starteamFolder the StarTeam folder from which files to be + * checked out + * @param targetFolder the local mapping of rootStarteamFolder + */ + protected void visit(Folder starteamFolder, java.io.File targetFolder) + throws BuildException { + try { + if (null == getRootLocalFolder()) { + log("Folder: " + starteamFolder.getName() + " (Default folder: " + targetFolder + ")"); + } else { + log("Folder: " + starteamFolder.getName() + " (Local folder: " + targetFolder + ")"); + } + Hashtable localFiles = listLocalFiles(targetFolder); + + // For all Files in this folder, we need to check + // if there have been modifications. + + Item[] files = starteamFolder.getItems("File"); + for (int i = 0; i < files.length; i++) { + File eachFile = (File) files[i]; + String filename = eachFile.getName(); + java.io.File localFile = + new java.io.File(targetFolder, filename); + + delistLocalFile(localFiles, localFile); + + + + // If the file doesn't pass the include/exclude tests, skip it. + if (!shouldProcess(filename)) { + continue; + } + + list(eachFile, localFile); + } + + + // Now we recursively call this method on all sub folders in this + // folder unless recursive attribute is off. + Folder[] subFolders = starteamFolder.getSubFolders(); + for (int i = 0; i < subFolders.length; i++) { + java.io.File targetSubfolder = + new java.io.File(targetFolder, subFolders[i].getName()); + delistLocalFile(localFiles, targetSubfolder); + if (isRecursive()) { + visit(subFolders[i], targetSubfolder); + } + } + + } catch (IOException e) { + throw new BuildException(e); + } + } + + protected void list(File reposFile, java.io.File localFile) + throws IOException { + StringBuffer b = new StringBuffer(); + if (null == getRootLocalFolder()) { + // status is irrelevant to us if we have specified a + // root local folder. + b.append(pad(Status.name(reposFile.getStatus()), 12)).append(' '); + } + b.append(pad(getUserName(reposFile.getLocker()), 20)) + .append(' ') + .append(reposFile.getModifiedTime().toString()) + .append(rpad(String.valueOf(reposFile.getSize()), 9)) + .append(' ') + .append(reposFile.getName()); + + log(b.toString()); + } + + private static final String blankstr = blanks(30); + + private static String blanks(int len) { + StringBuffer b = new StringBuffer(); + for (int i = 0; i < len; i++) { + b.append(' '); + } + return b.toString(); + } + + protected static String pad(String s, int padlen) { + return (s + blankstr).substring(0, padlen); + } + + protected static String rpad(String s, int padlen) { + s = blankstr + s; + return s.substring(s.length() - padlen); + } + + +}// StarTeamList + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java index 67f78e0eb..e52fd5d30 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamTask.java @@ -1,7 +1,7 @@ -/* +/* * The Apache Software License, Version 1.1 * - * Copyright (c) 2001 The Apache Software Foundation. All rights + * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -9,7 +9,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -17,15 +17,15 @@ * distribution. * * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the + * any, must include the following acknowlegement: + * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived - * from this software without prior written permission. For written + * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" @@ -54,26 +54,27 @@ */ package org.apache.tools.ant.taskdefs.optional.starteam; -import com.starbase.starteam.ServerException; -import com.starbase.starteam.vts.comm.CommandException; +import java.util.StringTokenizer; + +import com.starbase.starteam.Server; +import com.starbase.starteam.StarTeamFinder; +import com.starbase.starteam.User; +import com.starbase.starteam.View; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; -import java.io.FileNotFoundException; -import java.util.StringTokenizer; - - /** - * Common super class for all StarTeam tasks. - * At this level of the hierarchy we are concerned only with obtaining a - * connection to the StarTeam server. The subclass TreeBasedTask, - * also abstract defines the tree-walking behavior common to many subtasks. - * - * @see TreeBasedTask - * @author Jason Yip - * @version 1.1 - * @author Steve Cohen - */ +/** + * Common super class for all StarTeam tasks. + * At this level of the hierarchy we are concerned only with obtaining a + * connection to the StarTeam server. The subclass TreeBasedTask, + * also abstract defines the tree-walking behavior common to many subtasks. + * + * @see TreeBasedTask + * @author Jason Yip + * @version 1.1 + * @author Steve Cohen + */ public abstract class StarTeamTask extends Task { @@ -109,144 +110,150 @@ public abstract class StarTeamTask extends Task { */ private String viewname; - ///////////////////////////////////////////////////////// - // GET/SET methods. + /** + *The starteam server through which all activities will be done. + */ + private Server server = null; + + ///////////////////////////////////////////////////////// + // GET/SET methods. // Setters, of course are where ant user passes in values. - ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// /** * Set the name of StarTeamServer * * @param servername a String value - * @see setURL() + * @see #setURL(String) */ public void setServername(String servername) { - this.servername = servername; + this.servername = servername; } /** * returns the name of the StarTeamServer * * @return the name of the StarTeam server - * @see getURL() + * @see #getURL() */ public String getServername() { - return this.servername; + return this.servername; } - + /** * set the port number of the StarTeam connection * * @param serverport port number to be set - * @see setURL() + * @see #setURL(String) */ public void setServerport(String serverport) { - this.serverport = serverport; + this.serverport = serverport; } /** * returns the port number of the StarTeam connection * * @return the port number of the StarTeam connection - * @see getURL() + * @see #getURL() */ public String getServerport() { - return this.serverport; + return this.serverport; } - + /** * set the name of the StarTeam project to be acted on * * @param projectname the name of the StarTeam project to be acted on - * @see setURL() + * @see #setURL(String) */ public void setProjectname(String projectname) { - this.projectname = projectname; + this.projectname = projectname; } /** * returns the name of the StarTeam project to be acted on * * @return the name of the StarTeam project to be acted on - * @see getURL() + * @see #getURL() */ public String getProjectname() { - return this.projectname; + return this.projectname; } - + /** * set the name of the StarTeam view to be acted on * * @param projectname the name of the StarTeam view to be acted on - * @see setURL() + * @see #setURL(String) */ public void setViewname(String viewname) { - this.viewname = viewname; + this.viewname = viewname; } /** * returns the name of the StarTeam view to be acted on * * @return the name of the StarTeam view to be acted on - * @see getURL() - */ public String getViewname() { - return this.viewname; + * @see #getURL() + */ + public String getViewname() { + return this.viewname; } - + /** * This is a convenience method for setting the server name, server port, - * project name and project folder at one shot. + * project name and project folder at one shot. * - * @param url a String of the form + * @param url a String of the form * "servername:portnum/project/view" - * @see setServerame() - * @see setServerport() - * @see setProjectname() - * @see setViewname() + * @see #setServername(String) + * @see #setServerport(String) + * @see #setProjectname(String) + * @see #setViewname(String) */ public void setURL(String url) { - StringTokenizer t = new StringTokenizer(url,"/"); - if (t.hasMoreTokens()) { - String unpw = t.nextToken(); - int pos = unpw.indexOf(":"); - if (pos > 0) { - this.servername = unpw.substring(0,pos); - this.serverport = unpw.substring(pos+1); - if (t.hasMoreTokens()) { - this.projectname=t.nextToken(); - if (t.hasMoreTokens()) { - this.viewname = t.nextToken(); - } - } - } - } + StringTokenizer t = new StringTokenizer(url, "/"); + if (t.hasMoreTokens()) { + String unpw = t.nextToken(); + int pos = unpw.indexOf(":"); + if (pos > 0) { + this.servername = unpw.substring(0, pos); + this.serverport = unpw.substring(pos + 1); + if (t.hasMoreTokens()) { + this.projectname = t.nextToken(); + if (t.hasMoreTokens()) { + this.viewname = t.nextToken(); + } + } + } + } } /** * convenience method returns whole URL at once - * returns + * returns * as a single string */ /** * a convenience method which returns the whole StarTeam * connection information as a single URL string of * - * @return a String of the form + * @return a String of the form * "servername:portnum/project/view" - * @see getServername() - * @see getServerport() - * @see getProjectname() - * @see getViewname() + * @see #getServername() + * @see #getServerport() + * @see #getProjectname() + * @see #getViewname() */ public String getURL() { - return - this.servername + ":" + - this.serverport + "/" + - this.projectname + "/" + - ((null==this.viewname)?"":this.viewname); + return + this.servername + ":" + + this.serverport + "/" + + this.projectname + "/" + + ((null == this.viewname)?"":this.viewname); } - + /** * set the name of the StarTeam user, needed for the connection * @@ -255,7 +262,7 @@ public abstract class StarTeamTask extends Task { public void setUserName(String userName) { this.userName = userName; } - + /** * returns the name of the StarTeam user * @@ -273,7 +280,7 @@ public abstract class StarTeamTask extends Task { public void setPassword(String password) { this.password = password; } - + /** * returns the password used for login * @@ -282,6 +289,67 @@ public abstract class StarTeamTask extends Task { public String getPassword() { return this.password; } + + /** + * returns a reference to the server which may be used for informational + * purposes by subclasses. + * + * @return a reference to the server + */ + protected Server getServer() { + return this.server; + } + + /** + * Derived classes must override createSnapshotView + * defining the kind of configured view appropriate to its task. + * + * @param rawview the unconfigured View + * @return the snapshot View appropriately configured. + */ + protected abstract View createSnapshotView(View rawview); + + /** + * All subclasses will call on this method to open the view needed for + * processing. This method also saves a reference to the + * Server that may be accessed for information at various + * points in the process. + * + * @return the View that will be used for processing. + * @see #createSnapshotView(View) + * @see #getServer() + */ + protected View openView() throws BuildException { + View view = + StarTeamFinder.openView(getUserName() + ":" + + getPassword() + + "@" + getURL()); + + if (null == view) { + throw new BuildException("Cannot find view" + getURL() + + " in repository()"); + } + + View snapshot = createSnapshotView(view); + this.server = snapshot.getServer(); + return snapshot; + } + + /** + * Returns the name of the user with the supplied ID or a blank string + * if user not found. + * + * @param userID a user's ID + * @return the name of the user with ID userID + */ + protected String getUserName(int userID) { + User u = this.server.getUser(userID); + if (null == u) { + return ""; + } + return u.getName(); + } + } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java index 5f49c4531..de556ba72 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java @@ -64,7 +64,6 @@ import com.starbase.starteam.View; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; /** * FileBasedTask.java @@ -152,7 +151,6 @@ public abstract class TreeBasedTask extends StarTeamTask { */ private boolean forced = false; - private Hashtable localFiles = new Hashtable(); /////////////////////////////////////////////////////////////// // GET/SET methods. @@ -161,6 +159,7 @@ public abstract class TreeBasedTask extends StarTeamTask { /** * Set the root folder in the Starteam repository for this operation + * @param rootStarteamFolder the root folder */ public void setRootStarteamFolder(String rootStarteamFolder) { this.rootStarteamFolder = rootStarteamFolder; @@ -169,6 +168,7 @@ public abstract class TreeBasedTask extends StarTeamTask { /** * returns the root folder in the Starteam repository * used for this operation + * @return the root folder in use */ public String getRootStarteamFolder() { return this.rootStarteamFolder; @@ -179,6 +179,8 @@ public abstract class TreeBasedTask extends StarTeamTask { * starteam folder for this operation. * If not specified, the StarTeam default will be used * the default is used. + * @param rootLocalFolder the local folder that will mirror + * this.rootStarteamFolder */ public void setRootLocalFolder(String rootLocalFolder) { this.rootLocalFolder = rootLocalFolder; @@ -188,6 +190,7 @@ public abstract class TreeBasedTask extends StarTeamTask { * Returns the local folder specified by the user, * corresponding to the starteam folder for this operation. * or null if not specified + * @return the local folder that mirrors this.rootStarteamFolder */ public String getRootLocalFolder() { return this.rootLocalFolder; @@ -355,15 +358,6 @@ public abstract class TreeBasedTask extends StarTeamTask { return false; } - /** - * Derived classes must override createSnapshotView - * defining the kind of configured view appropriate to its task. - * - * @param rawview the unconfigured View - * @return the snapshot View appropriately configured. - */ - protected abstract View createSnapshotView(View rawview); - /** * This method does the work of opening the supplied Starteam view and * calling the visit() method to perform the task. @@ -374,22 +368,9 @@ public abstract class TreeBasedTask extends StarTeamTask { public void execute() throws BuildException { try { - if (null != this.rootLocalFolder && !this.forced) { - log("Warning: rootLocalFolder specified, but forcing off.", - Project.MSG_WARN); - } - // Open the view - View view = - StarTeamFinder.openView(getUserName() + ":" - + getPassword() - + "@" + getURL()); - - if (null == view) { - throw new BuildException("Cannot find view" + getURL() + - " in repository()"); - } + testPreconditions(); - View snapshot = createSnapshotView(view); + View snapshot = openView(); // find the starteam folder specified to be the root of the // operation. Throw if it can't be found. @@ -458,9 +439,17 @@ public abstract class TreeBasedTask extends StarTeamTask { throws BuildException; - protected Hashtable getLocalFiles() { - return this.localFiles; - } + /** + * Derived classes must override this method to define tests for + * any preconditons required by the task. This method is called at + * the beginning of the execute() method. + * + * @exception BuildException throw if any fatal error exists in the + * parameters supplied. If there is a non-fatal condition, just writing + * to the log may be appropriate. + * @see execute() + */ + protected abstract void testPreconditions() throws BuildException; /** * Gets the collection of the local file names in the supplied directory. @@ -468,10 +457,12 @@ public abstract class TreeBasedTask extends StarTeamTask { * understand what we need to do in order to synch with the repository. * * @param localFolder - the local folder to scan + * @return an "identity" hashtable whose keys each represent a file or + * directory in localFolder. */ - protected void listLocalFiles(java.io.File localFolder) { + protected static Hashtable listLocalFiles(java.io.File localFolder) { - this.localFiles.clear(); + Hashtable localFileList = new Hashtable(); // we can't use java 2 collections so we will use an identity // Hashtable to hold the file names. We only care about the keys, // not the values (which will all be ""). @@ -479,22 +470,23 @@ public abstract class TreeBasedTask extends StarTeamTask { if (localFolder.exists()) { String[] localFiles = localFolder.list(); for (int i = 0; i < localFiles.length; i++) { - this.localFiles.put(localFolder.toString() + + localFileList.put(localFolder.toString() + java.io.File.separatorChar + localFiles[i], ""); } } + return localFileList; } /** * Removes from the collection of the local file names * the supplied name of a processed file. When we are done, only * files not in StarTeam will remain in localFiles. - * - * @param thisfile - file to remove from list. - * @return - true if file was removed, false if it wasn't found. + * @param localFiles a Hashtable value + * @param thisfile file to remove from list. + * @return true if file was removed, false if it wasn't found. */ - protected boolean delistLocalFile(java.io.File thisfile) { - return null != this.localFiles.remove(thisfile.toString()); + protected boolean delistLocalFile(Hashtable localFiles, java.io.File thisfile) { + return null != localFiles.remove(thisfile.toString()); } }