- 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-ffa450edef68master
@@ -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 | |||
* <http://www.apache.org/>. | |||
* | |||
*/ | |||
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 <a href="mailto:scohen@localhost.localdomain">Steve Cohen</a> | |||
* @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 <code>View</code> | |||
* @return the snapshot <code>View</code> 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); | |||
} | |||
} | |||
} |
@@ -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 <a href="mailto:jcyip@thoughtworks.com">Jason Yip</a> | |||
* @author Jason Pettiss | |||
* @version 1.1 | |||
* @author <a href="mailto:stevec@ignitesports.com">Steve Cohen</a> | |||
* @version 1.1 | |||
* @see <A HREF="http://www.starbase.com/">StarBase Web Site</A> | |||
*/ | |||
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()); | |||
@@ -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: | |||
* <taskdef name="stlabel" | |||
* classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamLabel"/> | |||
* <stlabel | |||
* <stlabel | |||
* label="1.0" lastbuild="20011514100000" description="Successful Build" | |||
* username="BuildMaster" password="ant" | |||
* starteamurl="server:port/project/view"/> | |||
@@ -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 <code>View</code> | |||
* @return the snapshot <code>View</code> appropriately configured. | |||
*/ | |||
protected View createSnapshotView(View raw) { | |||
return new View(raw, ViewConfiguration.createFromTime(this.lastBuild)); | |||
} | |||
} | |||
@@ -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 | |||
* <http://www.apache.org/>. | |||
* | |||
*/ | |||
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 <a href="mailto:stevec@ignitesports.com">Steve Cohen</a> | |||
* @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 <code>View</code> | |||
* @return the snapshot <code>View</code> 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 | |||
@@ -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 <code>TreeBasedTask</code>, | |||
* also abstract defines the tree-walking behavior common to many subtasks. | |||
* | |||
* @see TreeBasedTask | |||
* @author <a href="mailto:jcyip@thoughtworks.com">Jason Yip</a> | |||
* @version 1.1 | |||
* @author <a href="mailto:stevec@ignitesports.com">Steve Cohen</a> | |||
*/ | |||
/** | |||
* 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 <code>TreeBasedTask</code>, | |||
* also abstract defines the tree-walking behavior common to many subtasks. | |||
* | |||
* @see TreeBasedTask | |||
* @author <a href="mailto:jcyip@thoughtworks.com">Jason Yip</a> | |||
* @version 1.1 | |||
* @author <a href="mailto:stevec@ignitesports.com">Steve Cohen</a> | |||
*/ | |||
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 <code>String</code> 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 <code>String</code> of the form | |||
* @param url a <code>String</code> 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 <code>String</code> of the form | |||
* @return a <code>String</code> 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 <code>createSnapshotView</code> | |||
* defining the kind of configured view appropriate to its task. | |||
* | |||
* @param rawview the unconfigured <code>View</code> | |||
* @return the snapshot <code>View</code> 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 | |||
* <code>Server</code> that may be accessed for information at various | |||
* points in the process. | |||
* | |||
* @return the <code>View</code> 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(); | |||
} | |||
} | |||
@@ -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 <code>createSnapshotView</code> | |||
* defining the kind of configured view appropriate to its task. | |||
* | |||
* @param rawview the unconfigured <code>View</code> | |||
* @return the snapshot <code>View</code> appropriately configured. | |||
*/ | |||
protected abstract View createSnapshotView(View rawview); | |||
/** | |||
* This method does the work of opening the supplied Starteam view and | |||
* calling the <code>visit()</code> 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 <code>execute()</code> | |||
*/ | |||
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 <code>Hashtable</code> 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()); | |||
} | |||
} | |||