diff --git a/WHATSNEW b/WHATSNEW index 6e186d009..0facf307f 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -600,6 +600,10 @@ Other changes: * new selector . "cache" was renamed to "modified". Bugzilla Report 20474. +* and have a new asofdate attribute that can be + used to checkout/list files based on a date instead of a label. + Bugzilla Report 20578. + Changes from Ant 1.5.3 to Ant 1.5.4 =================================== diff --git a/docs/manual/OptionalTasks/starteam.html b/docs/manual/OptionalTasks/starteam.html index 0e17deaf7..64de0f548 100644 --- a/docs/manual/OptionalTasks/starteam.html +++ b/docs/manual/OptionalTasks/starteam.html @@ -145,7 +145,24 @@ See also the required common StarTeam parameters. label - Check out files as of this label. The label must exist in starteam or an exception will be thrown. If either locked or unlocked is true, an exception will be thrown. If not specified, the most recent version of each file will be checked out. + Check out files as of this label. The label must exist in starteam or an exception will be thrown. + Either or neither, but not both, may be specified. Neither locked or unlocked may be true if either label or asofdate is specified. + + + asofdate + Check out files as of this date. The date must + be formatted in ISO8601 datetime + (yyyy-MM-dd'T'HH:mm:ss), ISO8601 + date(yyyy-MM-dd) or a user-defined SimpleDateFormat + defined in the asofDateFormat attribute. If the date + is not parsable by the default or selected format, an exception + will be thrown. Since Ant 1.6. + + + asofdateformat + java.util.SimpleDateFormat compatible string used + to parse the asofdate attribute. Since Ant + 1.6. no @@ -163,7 +180,7 @@ that StarTeam is maintaining for the file. If false, status will be used to de locked If true, file will be locked against changes by other users. If false (default) has no effect. - Either or neither, but not both, may be true. Neither may be true if a label is specified. + Either or neither, but not both, may be true. Neither may be true if a label or an asofdate is specified. unlocked @@ -184,7 +201,7 @@ of checkout. no entire tree prior to beginning action on that tree. Doing so can in some instances lead to substantially faster actions, particularly over large trees. Setting this to "yes" (default) engages this functionality, setting it to "no" turns it off. - yes + no @@ -194,7 +211,7 @@ of checkout. no what you'd want but if for some reason you don't want that to happen, set it to false and the files will be checked out with whatever end-of-line characters are used on the server. - yes + no @@ -385,7 +402,7 @@ change it. If false (default) lock status will not change. entire tree prior to beginning action on that tree. Doing so can in some instances lead to substantially faster actions, particularly over large trees. Setting this to "yes" (default) engages this functionality, setting it to "no" turns it off. - yes + no @@ -663,6 +680,25 @@ See also the required common StarTeam parameters.List files, dates, and statuses as of this label. The label must exist in starteam or an exception will be thrown. If not specified, the most recent version of each file will be listed. no + + asofdate + List files, dates, and statusess as of this date. + The date must be formatted in ISO8601 datetime + (yyyy-MM-dd'T'HH:mm:ss), ISO8601 + date(yyyy-MM-dd) or a user-defined SimpleDateFormat + defined in the asofDateFormat attribute. If the date + is not parsable by the default or selected format, an exception + will be thrown. Since Ant 1.6. + no + + + asofdateformat + java.util.SimpleDateFormat compatible string used + to parse the asofdate attribute. Since Ant + 1.6. + no + + recursive Indicates if subfolders should be searched for files to list. Defaults to "true". @@ -681,7 +717,7 @@ See also the required common StarTeam parameters. - yes + no 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 ea38ea0ad..897ea71c2 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 @@ -65,6 +65,7 @@ import java.util.Hashtable; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; + /** * Checks out files from a StarTeam project. * It also creates all working directories on the @@ -107,6 +108,7 @@ public class StarTeamCheckout extends TreeBasedTask { */ private boolean convertEOL = true; + /** * flag (defaults to true) to create all directories * that are in the Starteam repository even if they are empty. @@ -216,6 +218,31 @@ public class StarTeamCheckout extends TreeBasedTask { public boolean getUseRepositoryTimeStamp() { return this.useRepositoryTimeStamp; } + + /** + * List files, dates, and statuses as of this date; optional. + * If not specified, the most recent version of each file will be listed. + * + * @param asOfDateParam the date as of which the listing to be made + * @since Ant 1.6 + */ + public void setAsOfDate(String asOfDateParam) { + _setAsOfDate(asOfDateParam); + } + + /** + * Date Format with which asOfDate parameter to be parsed; optional. + * Must be a SimpleDateFormat compatible string. + * If not specified, and asOfDateParam is specified, parse will use ISO8601 + * datetime and date formats. + * + * @param asOfDateFormat the SimpleDateFormat-compatible format string + * @since Ant 1.6 + */ + public void setAsOfDateFormat(String asOfDateFormat) { + _setAsOfDateFormat(asOfDateFormat); + } + /** * Override of base-class abstract function creates an * appropriately configured view for checkouts - either @@ -241,12 +268,18 @@ public class StarTeamCheckout extends TreeBasedTask { else if (this.isUsingRevisionLabel()) { return raw; } + // if a date has been supplied use a view configured to the date. + View view = getViewConfiguredByDate(raw); + if (view != null) { + return view; + } // otherwise, use this view configured as the tip. else { return new View(raw, ViewConfiguration.createTip()); } } + /** * Implements base-class abstract function to define tests for * any preconditons required by the task. @@ -261,11 +294,31 @@ public class StarTeamCheckout extends TreeBasedTask { Project.MSG_WARN); this.createDirs = false; } - if (lockStatus != Item.LockType.UNCHANGED && null != getLabel()) { - log("Neither locked nor unlocked may be true when checking out a labeled version.", - Project.MSG_ERR); - throw new BuildException("Lock status may not be changed when checking out a non-current version."); + if (lockStatus != Item.LockType.UNCHANGED) { + boolean lockStatusBad = false; + if (null != getLabel()) { + log("Neither locked nor unlocked may be true" + + " when checking out a labeled version.", + Project.MSG_ERR); + lockStatusBad = true; + } else if (null != getAsOfDate()) { + log("Neither locked nor unlocked may be true" + + " when checking out by date.", + Project.MSG_ERR); + lockStatusBad = true; + } + if (lockStatusBad) { + throw new BuildException( + "Lock status may not be changed" + + " when checking out a non-current version."); + } + } + if (null != getLabel() && null != getAsOfDate()) { + throw new BuildException( + "Both label and asOfDate specified. " + + "Unable to process request."); } + } /** @@ -290,6 +343,7 @@ public class StarTeamCheckout extends TreeBasedTask { logLabel(); + logAsOfDate(); logIncludes(); logExcludes(); @@ -318,6 +372,8 @@ public class StarTeamCheckout extends TreeBasedTask { : " only where needed to check out files.")); } + + /** * Implements base-class abstract function to perform the checkout * operation on the files in each folder of the tree. 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 index 295e26cab..908c83447 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/starteam/StarTeamList.java @@ -90,6 +90,31 @@ public class StarTeamList extends TreeBasedTask { _setLabel(label); } + /** + * List files, dates, and statuses as of this date; optional. + * If not specified, the most recent version of each file will be listed. + * + * @param asOfDateParam the date as of which the listing to be made + * @since Ant 1.6 + */ + public void setAsOfDate(String asOfDateParam) { + _setAsOfDate(asOfDateParam); + } + + /** + * Date Format with which asOfDate parameter to be parsed; optional. + * Must be a SimpleDateFormat compatible string. + * If not specified, and asOfDateParam is specified, parse will use ISO8601 + * datetime and date formats. + * + * @param asOfDateFormat the SimpleDateFormat-compatible format string + * @since Ant 1.6 + */ + public void setAsOfDateFormat(String asOfDateFormat) { + _setAsOfDateFormat(asOfDateFormat); + } + + /** * Override of base-class abstract function creates an * appropriately configured view for checkoutlists - either @@ -106,18 +131,30 @@ public class StarTeamList extends TreeBasedTask { // otherwise use current view if (labelID >= 0) { return new View(raw, ViewConfiguration.createFromLabel(labelID)); - } else { + } + // if a date has been supplied use a view configured to the date. + View view = getViewConfiguredByDate(raw); + if (view != null) { + return view; + } + // otherwise, use this view configured as the tip. + else { return new View(raw, ViewConfiguration.createTip()); } } /** - * Required base-class abstract function implementation is a no-op here. + * Required base-class abstract function implementation checks for + * incompatible parameters. * - * @exception BuildException not thrown in this implementation + * @exception BuildException thrown on incompatible params specified */ protected void testPreconditions() throws BuildException { - //intentionally do nothing. + if (null != getLabel() && null != getAsOfDate()) { + throw new BuildException( + "Both label and asOfDate specified. " + + "Unable to process request."); + } } /** @@ -139,6 +176,7 @@ public class StarTeamList extends TreeBasedTask { + targetrootFolder.getAbsolutePath(), Project.MSG_INFO); logLabel(); + logAsOfDate(); logIncludes(); logExcludes(); 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 bafc193d2..51c9ee16a 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 @@ -58,9 +58,15 @@ import com.starbase.starteam.Label; import com.starbase.starteam.PropertyNames; import com.starbase.starteam.StarTeamFinder; import com.starbase.starteam.View; +import com.starbase.starteam.ViewConfiguration; +import com.starbase.util.OLEDate; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Hashtable; import java.util.StringTokenizer; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.util.DateUtils; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; @@ -158,6 +164,18 @@ public abstract class TreeBasedTask extends StarTeamTask { private Label labelInUse = null; + /** + * holder for the asofdate attribute + */ + private String asOfDate = null; + + /** + * holder for the asofdateformat attribute + */ + private String asOfDateFormat = null; + + + /////////////////////////////////////////////////////////////// // GET/SET methods. // Setters, of course are where ant user passes in values. @@ -324,6 +342,105 @@ public abstract class TreeBasedTask extends StarTeamTask { } } + /** + * non-public method callable only by derived classes that implement + * setAsOfDate (so that derived tasks that do not accept this + * parameter will fail if user attempts to use it. + * + * @param asOfDate asOfDate entered by user. + * @since Ant 1.6 + */ + protected void _setAsOfDate(String asOfDate) { + if (asOfDate != null && asOfDate.length() > 0) { + this.asOfDate = asOfDate; + } + } + + /** + * non-public method callable only by derived classes that implement + * setAsOfDateFormat (so that derived tasks that do not accept this + * parameter will fail if user attempts to use it. + * + * @param asOfDateFormat asOfDate format entered by user. + * @since Ant 1.6 + */ + protected void _setAsOfDateFormat(String asOfDateFormat) { + if (asOfDateFormat != null && asOfDateFormat.length() > 0) { + this.asOfDateFormat = asOfDateFormat; + } + } + + + /** + * return the asOfDate entered by the user for internal use by derived + * classes. + * + * @return the asOfDate entered by the user + * @since Ant 1.6 + */ + protected String getAsOfDate() { + return this.asOfDate; + } + + + + /** + * If an asofDate parameter has been supplied by the user return a + * StarTeam view based on the configuration of the StarTeam view + * specified the user as of the date specified in the parameter. + * If no asofDate has been specified, return null. + * + * This method is meant to be called from within implementations of the + * createSnapshotView abstract method. + * + * @param raw the raw view to be configured as of the supplied date + * + * @return the view as configured. + * @exception BuildException + * thrown if the date is not parsable by the default or + * supplied format patterns. + * @since Ant 1.6 + */ + protected View getViewConfiguredByDate(View raw) throws BuildException { + if (this.asOfDate == null) { + return null; + } + Date asOfDate = null; + SimpleDateFormat fmt = null; + if (this.asOfDateFormat != null) { + fmt = new SimpleDateFormat(this.asOfDateFormat); + try { + asOfDate = fmt.parse(this.asOfDate); + } + catch (ParseException px) + { + throw new BuildException("AsOfDate " + + this.asOfDate + + " not parsable by supplied format " + + this.asOfDateFormat); + } + } else { + try { + asOfDate = DateUtils.parseIso8601DateTimeOrDate( + this.asOfDate); + } catch (ParseException px) { + throw new BuildException("AsOfDate " + + this.asOfDate + + " not parsable by default" + + " ISO8601 formats"); + } + } + return new View(raw, ViewConfiguration.createFromTime( + new OLEDate(asOfDate))); + } + + + + /** + * return the label passed to the task by the user as a string + * + * @return the label passed to the task by the user as a string + */ protected String getLabel() { return this.label; } @@ -421,6 +538,17 @@ public abstract class TreeBasedTask extends StarTeamTask { } } + /** + * show the asofDate in the log + * @since Ant 1.6 + */ + protected void logAsOfDate() { + if (null != this.asOfDate) { + log(" Using view as of date " + getAsOfDate()); + } + } + + @@ -501,8 +629,18 @@ public abstract class TreeBasedTask extends StarTeamTask { } catch (BuildException e) { throw e; } catch (Exception e) { - throw new BuildException("Unable to find root folder " - + this.rootStarteamFolder + " in repository at " + getURL(), e); + StringBuffer msg = new StringBuffer("Unable to find root folder ") + .append(this.rootStarteamFolder) + .append(" in repository at ") + .append(getURL()); + if (this.label != null) { + msg.append(" using specified label ").append(this.label); + } + if (this.asOfDate != null) { + msg.append(" as of specified date ") + .append(this.asOfDate); + } + throw new BuildException(msg.toString(), e); } diff --git a/src/main/org/apache/tools/ant/util/DateUtils.java b/src/main/org/apache/tools/ant/util/DateUtils.java index 71b6ad3e5..ead869131 100644 --- a/src/main/org/apache/tools/ant/util/DateUtils.java +++ b/src/main/org/apache/tools/ant/util/DateUtils.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2002 The Apache Software Foundation. All rights + * Copyright (c) 2002-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,6 +56,7 @@ package org.apache.tools.ant.util; import java.text.ChoiceFormat; import java.text.DateFormat; import java.text.MessageFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @@ -254,4 +255,55 @@ public final class DateUtils { tzMarker.append(minutes); return DATE_HEADER_FORMAT.format(cal.getTime()) + tzMarker.toString(); } + + /** + * Parse a string as a datetime using the ISO8601_DATETIME format which is + * yyyy-MM-dd'T'HH:mm:ss + * + * @param datestr string to be parsed + * + * @return a java.util.Date object as parsed by the format. + * @exception ParseException if the supplied string cannot be parsed by + * this pattern. + * @since Ant 1.6 + */ + public static Date parseIso8601DateTime(String datestr) + throws ParseException { + return new SimpleDateFormat(ISO8601_DATETIME_PATTERN).parse(datestr); + } + + /** + * Parse a string as a date using the ISO8601_DATE format which is + * yyyy-MM-dd + * + * @param datestr string to be parsed + * + * @return a java.util.Date object as parsed by the format. + * @exception ParseException if the supplied string cannot be parsed by + * this pattern. + * @since Ant 1.6 + */ + public static Date parseIso8601Date(String datestr) throws ParseException { + return new SimpleDateFormat(ISO8601_DATE_PATTERN).parse(datestr); + } + + /** + * Parse a string as a date using the either the ISO8601_DATETIME + * or ISO8601_DATE formats. + * + * @param datestr string to be parsed + * + * @return a java.util.Date object as parsed by the formats. + * @exception ParseException if the supplied string cannot be parsed by + * either of these patterns. + * @since Ant 1.6 + */ + public static Date parseIso8601DateTimeOrDate(String datestr) + throws ParseException { + try { + return parseIso8601DateTime(datestr); + } catch (ParseException px) { + return parseIso8601Date(datestr); + } + } }