Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 612   Methods: 19
NCLOC: 305   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
StarTeamCheckout.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 package org.apache.tools.ant.taskdefs.optional.starteam;
 55   
 
 56   
 import com.starbase.starteam.File;
 57   
 import com.starbase.starteam.Folder;
 58   
 import com.starbase.starteam.Item;
 59   
 import com.starbase.starteam.Status;
 60   
 import com.starbase.starteam.TypeNames;
 61   
 import com.starbase.starteam.View;
 62   
 import com.starbase.starteam.ViewConfiguration;
 63   
 import java.io.IOException;
 64   
 import java.util.Enumeration;
 65   
 import java.util.Hashtable;
 66   
 import org.apache.tools.ant.BuildException;
 67   
 import org.apache.tools.ant.Project;
 68   
 
 69   
 /**
 70   
  * Checks out files from a StarTeam project.
 71   
  * It also creates all working directories on the
 72   
  * local directory if appropriate. Ant Usage:
 73   
  * <pre>
 74   
  * &lt;taskdef name="starteamcheckout"
 75   
  * classname="org.apache.tools.ant.taskdefs.StarTeamCheckout"/&gt;
 76   
  * &lt;starteamcheckout username="BuildMaster" password="ant" starteamFolder="Source"
 77   
  * starteamurl="servername:portnum/project/view"
 78   
  * createworkingdirectories="true"/&gt;
 79   
  * </pre>
 80   
  *
 81   
  * @author Christopher Charlier, ThoughtWorks, Inc. 2001
 82   
  * @author <a href="mailto:jcyip@thoughtworks.com">Jason Yip</a>
 83   
  * @author Jason Pettiss
 84   
  * @author <a href="mailto:stevec@ignitesports.com">Steve Cohen</a>
 85   
  * @version 1.1
 86   
  * @see <A HREF="http://www.starbase.com/">StarBase Web Site</A>
 87   
  *
 88   
  * @ant.task name="stcheckout" category="scm"
 89   
  */
 90   
 public class StarTeamCheckout extends TreeBasedTask {
 91   
 
 92   
     /**
 93   
      * holder for the createDirs attribute
 94   
      */
 95   
     private boolean createDirs = true;
 96   
 
 97   
     /**
 98   
      * holder for the deleteUncontrolled attribute.  If true,
 99   
      * all local files not in StarTeam will be deleted.
 100   
      */
 101   
     private boolean deleteUncontrolled = true;
 102   
 
 103   
     /**
 104   
      * flag (defaults to true) to create all directories
 105   
      * that are in the Starteam repository even if they are empty.
 106   
      *
 107   
      * @param value  the value to set the attribute to.
 108   
      */
 109  0
     public void setCreateWorkingDirs(boolean value) {
 110  0
         this.createDirs = value;
 111   
     }
 112   
 
 113   
     /**
 114   
      * Whether or not all local files <i>not<i> in StarTeam should be deleted.
 115   
      * Optional, defaults to <code>true</code>.
 116   
      * @param value  the value to set the attribute to.
 117   
      */
 118  0
     public void setDeleteUncontrolled(boolean value) {
 119  0
         this.deleteUncontrolled = value;
 120   
     }
 121   
 
 122   
     /**
 123   
      * Sets the label StarTeam is to use for checkout; defaults to the most recent file.
 124   
      * The label must exist in starteam or an exception will be thrown. 
 125   
      * @param label the label to be used
 126   
      */
 127  0
     public void setLabel(String label) {
 128  0
         _setLabel(label);
 129   
     }
 130   
 
 131   
     /**
 132   
      * This attribute tells whether to do a locked checkout, an unlocked
 133   
      * checkout or to leave the checkout status alone (default).  A locked
 134   
      * checkout locks all other users out from making changes.  An unlocked
 135   
      * checkout reverts all local files to their previous repository status
 136   
      * and removes the lock.
 137   
      * @see #setLocked(boolean)
 138   
      * @see #setUnlocked(boolean)
 139   
      */
 140   
     private int lockStatus = Item.LockType.UNCHANGED;
 141   
 
 142   
     /**
 143   
      * Set to do a locked checkout; optional default is false. 
 144   
      * @param v  True to do a locked checkout, false to checkout without
 145   
      *           changing status/.
 146   
      * @exception BuildException if both locked and unlocked are set true
 147   
      */
 148  0
     public void setLocked(boolean v) throws BuildException {
 149  0
         setLockStatus(v, Item.LockType.EXCLUSIVE);
 150   
     }
 151   
 
 152   
 
 153   
     /**
 154   
      * Set to do an unlocked checkout. Default is false;
 155   
      * @param v  True to do an unlocked checkout, false to checkout without
 156   
      *           changing status.
 157   
      * @exception BuildException if both locked and unlocked are set true
 158   
      */
 159  0
     public void setUnlocked(boolean v) throws BuildException {
 160  0
         setLockStatus(v, Item.LockType.UNLOCKED);
 161   
     }
 162   
 
 163  0
     private void setLockStatus(boolean v, int newStatus)
 164   
             throws BuildException {
 165  0
         if (v) {
 166  0
             if (this.lockStatus == Item.LockType.UNCHANGED) {
 167  0
                 this.lockStatus = newStatus;
 168  0
             } else if (this.lockStatus != newStatus) {
 169  0
                 throw new BuildException(
 170   
                         "Error: cannot set locked and unlocked both true.");
 171   
             }
 172   
         }
 173   
     }
 174   
 
 175   
     /**
 176   
      * should checked out files get the timestamp from the repository
 177   
      * or the time they are checked out.  True means use the repository 
 178   
      * timestamp.
 179   
      */
 180   
     private boolean useRepositoryTimeStamp = false;
 181   
 
 182   
     /**
 183   
      * sets the useRepositoryTimestmp member.
 184   
      * 
 185   
      * @param useRepositoryTimeStamp
 186   
      *               true means checked out files will get the repository timestamp.
 187   
      *               false means the checked out files will be timestamped at the time
 188   
      *               of checkout.
 189   
      */
 190  0
     public void setUseRepositoryTimeStamp(boolean useRepositoryTimeStamp)
 191   
     {
 192  0
         this.useRepositoryTimeStamp = useRepositoryTimeStamp;
 193   
     }
 194   
 
 195   
     /**
 196   
      * returns the value of the useRepositoryTimestamp member
 197   
      * 
 198   
      * @return the value of the useRepositoryTimestamp member
 199   
      */
 200  0
     public boolean getUseRepositoryTimeStamp() {
 201  0
         return this.useRepositoryTimeStamp;
 202   
     }
 203   
     /**
 204   
      * Override of base-class abstract function creates an
 205   
      * appropriately configured view for checkouts - either
 206   
      * the current view or a view from this.label or the raw
 207   
      * view itself in the case of a revision label.
 208   
      * 
 209   
      * @param raw    the unconfigured <code>View</code>
 210   
      * 
 211   
      * @return the snapshot <code>View</code> appropriately configured.
 212   
      * @exception BuildException
 213   
      */
 214  0
     protected View createSnapshotView(View raw) 
 215   
     throws BuildException
 216   
     {
 217   
 
 218  0
         int labelID = getLabelID(raw);
 219   
 
 220   
         // if a label has been supplied and it is a view label, use it 
 221   
         // to configure the view
 222  0
         if (this.isUsingViewLabel()) {
 223  0
             return new View(raw, ViewConfiguration.createFromLabel(labelID));
 224   
         } 
 225   
         // if a label has been supplied and it is a revision label, use the raw 
 226   
         // the view as the snapshot
 227  0
         else if (this.isUsingRevisionLabel()) {
 228  0
             return raw;
 229   
         }
 230   
         // otherwise, use this view configured as the tip.
 231   
         else {
 232  0
             return new View(raw, ViewConfiguration.createTip());
 233   
         }
 234   
     }
 235   
 
 236   
     /**
 237   
      * Implements base-class abstract function to define tests for
 238   
      * any preconditons required by the task.
 239   
      *
 240   
      * @exception BuildException thrown if both rootLocalFolder 
 241   
      * and viewRootLocalFolder are defined
 242   
      */
 243  0
     protected void testPreconditions() throws BuildException {
 244  0
         if (this.isUsingRevisionLabel() && this.createDirs) {
 245  0
             log("Ignoring createworkingdirs while using a revision label." +
 246   
                 "  Folders will be created only as needed.",
 247   
                 Project.MSG_WARN);
 248  0
             this.createDirs=false;
 249   
         }
 250   
     }
 251   
 
 252   
     /**
 253   
      * extenders should emit to the log an entry describing the parameters
 254   
      * that will be used by this operation.
 255   
      * 
 256   
      * @param starteamrootFolder
 257   
      *               root folder in StarTeam for the operation
 258   
      * @param targetrootFolder
 259   
      *               root local folder for the operation (whether specified 
 260   
      * by the user or not.
 261   
      */
 262   
 
 263  0
     protected void logOperationDescription(
 264   
         Folder starteamrootFolder, java.io.File targetrootFolder)
 265   
     {
 266  0
         log((this.isRecursive() ? "Recursive" : "Non-recursive") + 
 267   
             " Checkout from: " + starteamrootFolder.getFolderHierarchy());
 268   
 
 269  0
         log("  Checking out to" 
 270   
             + (null == getRootLocalFolder() ? "(default): " : ": ") 
 271   
             + targetrootFolder.getAbsolutePath());
 272   
 
 273   
 
 274  0
         logLabel();
 275  0
         logIncludes();
 276  0
         logExcludes();
 277   
 
 278  0
         if (this.lockStatus == Item.LockType.EXCLUSIVE) {
 279  0
             log("  Items will be checked out with Exclusive locks.");
 280   
         }
 281  0
         else if (this.lockStatus == Item.LockType.UNLOCKED) {
 282  0
             log("  Items will be checked out unlocked (even if presently locked).");
 283   
         } 
 284   
         else {
 285  0
             log("  Items will be checked out with no change in lock status.");
 286   
         }
 287  0
         log("  Items will be checked out with " + 
 288   
             (this.useRepositoryTimeStamp ? "repository timestamps."  
 289   
                                         : "the current timestamp."));
 290  0
         log("  Items will be checked out " +
 291   
             (this.isForced() ? "regardless of" : "in accordance with") +
 292   
             " repository status.");
 293  0
         if (this.deleteUncontrolled) {
 294  0
             log("  Local items not found in the repository will be deleted.");
 295   
         }
 296  0
         log("  Directories will be created"+
 297   
             (this.createDirs ? " wherever they exist in the repository, even if empty." 
 298   
                              : " only where needed to check out files."));
 299   
         
 300   
     }
 301   
     /**
 302   
      * Implements base-class abstract function to perform the checkout
 303   
      * operation on the files in each folder of the tree.
 304   
      *
 305   
      * @param starteamFolder the StarTeam folder from which files to be
 306   
      *                       checked out
 307   
      * @param targetFolder the local mapping of rootStarteamFolder
 308   
      * @exception BuildException if any error occurs
 309   
      */
 310  0
     protected void visit(Folder starteamFolder, java.io.File targetFolder)
 311   
             throws BuildException 
 312   
     {  
 313  0
         try {
 314   
 
 315   
 
 316  0
             if (null != getRootLocalFolder()) {
 317  0
                 starteamFolder.setAlternatePathFragment(
 318   
                     targetFolder.getAbsolutePath());
 319   
             }
 320   
             
 321  0
             if (!targetFolder.exists()) {
 322  0
                 if (!this.isUsingRevisionLabel()) {
 323  0
                     if (this.createDirs) {
 324  0
                         if (targetFolder.mkdirs()) {
 325  0
                             log("Creating folder: " + targetFolder);
 326   
                         } else {
 327  0
                             throw new BuildException(
 328   
                                 "Failed to create local folder " + targetFolder);
 329   
                         }
 330   
                     }
 331   
                 }
 332   
             }
 333   
             
 334   
             
 335  0
             Folder[] foldersList = starteamFolder.getSubFolders();
 336  0
             Item[] filesList = starteamFolder.getItems(getTypeNames().FILE);
 337   
 
 338  0
             if (this.isUsingRevisionLabel()) {
 339   
 
 340   
                 // prune away any files not belonging to the revision label
 341   
                 // this is one ugly API from Starteam SDK
 342   
                 
 343  0
                 Hashtable labelItems = new Hashtable(filesList.length);
 344  0
                 int s = filesList.length;
 345  0
                 int[] ids = new int[s];
 346  0
                 for (int i=0; i < s; i++) {
 347  0
                     ids[i]=filesList[i].getItemID();
 348  0
                     labelItems.put(new Integer(ids[i]), new Integer(i));
 349   
                 }
 350  0
                 int[] foundIds = getLabelInUse().getLabeledItemIDs(ids);
 351  0
                 s = foundIds.length;
 352  0
                 Item[] labeledFiles = new Item[s];
 353  0
                 for (int i=0; i < s; i++) {
 354  0
                     Integer ID = new Integer(foundIds[i]);
 355  0
                     labeledFiles[i] = 
 356   
                         filesList[((Integer) labelItems.get(ID)).intValue()];
 357   
                 }
 358  0
                 filesList = labeledFiles;
 359   
             }
 360   
             
 361   
             
 362   
             // note, it's important to scan the items BEFORE we make the
 363   
             // Unmatched file map because that creates a bunch of NEW
 364   
             // folders and files (unattached to repository) and we
 365   
             // don't want to include those in our traversal.
 366   
 
 367  0
             UnmatchedFileMap ufm = 
 368   
                 new CheckoutMap().
 369   
                     init(targetFolder.getAbsoluteFile(), starteamFolder);
 370   
 
 371   
 
 372   
 
 373  0
             for (int i = 0; i < foldersList.length; i++) {
 374  0
                 Folder stFolder = foldersList[i];
 375   
 
 376  0
                 java.io.File subfolder = 
 377   
                      new java.io.File(targetFolder, stFolder.getName());
 378   
 
 379  0
                  ufm.removeControlledItem(subfolder);
 380   
 
 381  0
                  if (isRecursive()) {
 382  0
                          visit(stFolder, subfolder);
 383   
                      }
 384   
                  }
 385   
 
 386  0
             for (int i = 0; i < filesList.length; i++) {
 387  0
                 com.starbase.starteam.File stFile = 
 388   
                     (com.starbase.starteam.File) filesList[i];
 389  0
                 processFile( stFile, targetFolder);
 390   
                 
 391  0
                 ufm.removeControlledItem(
 392   
                     new java.io.File(targetFolder, stFile.getName()));
 393   
             }
 394  0
             if (this.deleteUncontrolled) {
 395  0
                 ufm.processUncontrolledItems();
 396   
             }
 397   
         } catch (IOException e) {
 398  0
             throw new BuildException(e);
 399   
         }
 400   
     }
 401   
 
 402   
 
 403   
     /**
 404   
      * provides a string showing from and to full paths for logging
 405   
      * 
 406   
      * @param remotefile the Star Team file being processed.
 407   
      * 
 408   
      * @return a string showing from and to full paths
 409   
      */
 410  0
     private String describeCheckout(com.starbase.starteam.File remotefile,
 411   
                                     java.io.File localFile)
 412   
     {
 413  0
         StringBuffer sb = new StringBuffer();
 414  0
         sb.append(getFullRepositoryPath(remotefile))
 415   
           .append(" --> ");
 416  0
         if (null == localFile) {
 417  0
             sb.append(remotefile.getFullName());
 418   
         } else {
 419  0
             sb.append(localFile);
 420   
         }
 421  0
         return sb.toString();
 422   
     }
 423  0
     private String describeCheckout(com.starbase.starteam.File remotefile) {
 424  0
         return describeCheckout(remotefile,null);
 425   
     }
 426   
     /**
 427   
      * Processes (checks out) <code>stFiles</code>files from StarTeam folder.
 428   
      *
 429   
      * @param eachFile repository file to process
 430   
      * @param targetFolder a java.io.File (Folder) to work
 431   
      * @throws IOException when StarTeam API fails to work with files
 432   
      */
 433  0
     private void processFile(com.starbase.starteam.File eachFile, 
 434   
                              java.io.File targetFolder )
 435   
     throws IOException 
 436   
     {
 437  0
         String filename = eachFile.getName();
 438   
 
 439  0
         java.io.File localFile = new java.io.File(targetFolder, filename);
 440   
 
 441   
         // If the file doesn't pass the include/exclude tests, skip it.
 442  0
         if (!shouldProcess(filename)) {
 443  0
             log("Excluding " + getFullRepositoryPath(eachFile), 
 444   
                 Project.MSG_INFO);
 445  0
                 return;
 446   
         }
 447   
 
 448  0
         if (this.isUsingRevisionLabel()) {
 449  0
             if (!targetFolder.exists()) {
 450  0
                 if (targetFolder.mkdirs()) {
 451  0
                     log("Creating folder: " + targetFolder);
 452   
                 } else {
 453  0
                     throw new BuildException(
 454   
                         "Failed to create local folder " + targetFolder);
 455   
                 }
 456   
             }
 457  0
             boolean success = eachFile.checkoutByLabelID(
 458   
                 localFile,
 459   
                 getIDofLabelInUse(),
 460   
                 this.lockStatus,
 461   
                 !this.useRepositoryTimeStamp,
 462   
                 true,
 463   
                 false);
 464  0
             if (success) {
 465  0
                 log("Checked out " + describeCheckout(eachFile, localFile));
 466   
             }
 467   
         }
 468   
         else {
 469  0
             boolean checkout = true;
 470   
 
 471   
             // Just a note: StarTeam has a status for NEW which implies
 472   
             // that there is an item  on your local machine that is not
 473   
             // in the repository.  These are the items that show up as
 474   
             // NOT IN VIEW in the Starteam GUI.
 475   
             // One would think that we would want to perhaps checkin the
 476   
             // NEW items (not in all cases! - Steve Cohen 15 Dec 2001)
 477   
             // Unfortunately, the sdk doesn't really work, and we can't
 478   
             // actually see  anything with a status of NEW. That is why
 479   
             // we can just check out  everything here without worrying
 480   
             // about losing anything.
 481   
 
 482  0
             int fileStatus = (eachFile.getStatus());
 483   
 
 484   
             // We try to update the status once to give StarTeam
 485   
             // another chance.
 486   
 
 487  0
             if (fileStatus == Status.MERGE || 
 488   
                 fileStatus == Status.UNKNOWN) 
 489   
             {
 490  0
                 eachFile.updateStatus(true, true);
 491  0
                 fileStatus = (eachFile.getStatus());
 492   
             }
 493   
 
 494  0
             log(eachFile.toString() + " has status of " + 
 495   
                 Status.name(fileStatus), Project.MSG_DEBUG);
 496   
 
 497   
 
 498  0
             switch (fileStatus) {
 499   
             case Status.OUTOFDATE:
 500   
             case Status.MISSING:
 501  0
                 log("Checking out: " + describeCheckout(eachFile));
 502  0
                 break;
 503   
             default:
 504  0
                 if (isForced()) {
 505  0
                     log("Forced checkout of " 
 506   
                         + describeCheckout(eachFile) 
 507   
                         + " over status " + Status.name(fileStatus));
 508   
                 } else {
 509  0
                     log("Skipping: " + getFullRepositoryPath(eachFile) + 
 510   
                         " - status: " + Status.name(fileStatus));
 511  0
                     checkout = false;
 512   
                 }
 513   
             }
 514   
 
 515  0
             if (checkout) {
 516  0
                 if (!targetFolder.exists()) {
 517  0
                     if (targetFolder.mkdirs()) {
 518  0
                         log("Creating folder: " + targetFolder);
 519   
                     } else {
 520  0
                         throw new BuildException(
 521   
                             "Failed to create local folder " + targetFolder);
 522   
                     }
 523   
                 }
 524  0
                 eachFile.checkout(this.lockStatus, 
 525   
                                  !this.useRepositoryTimeStamp, true, true);
 526   
             }
 527   
         }
 528   
     }
 529   
     /**
 530   
      * handles the deletion of uncontrolled items
 531   
      */
 532   
     private class CheckoutMap extends UnmatchedFileMap {
 533  0
         protected boolean isActive() {
 534  0
             return StarTeamCheckout.this.deleteUncontrolled;
 535   
         }
 536   
 
 537   
         /**
 538   
          * override of the base class init.  It can be much simpler, since
 539   
          * the action to be taken is simply to delete the local files.  No
 540   
          * further interaction with the repository is necessary.
 541   
          * 
 542   
          * @param localFolder
 543   
          *        the local folder from which the mappings will be made.
 544   
          * @param remoteFolder
 545   
          *        not used in this implementation
 546   
          */
 547  0
         UnmatchedFileMap init(java.io.File localFolder, Folder remoteFolder) {
 548  0
             if (!localFolder.exists()) {
 549  0
                 return this;
 550   
             }
 551   
 
 552  0
             String[] localFiles = localFolder.list();
 553   
     
 554  0
             for (int i=0; i < localFiles.length; i++) {
 555  0
                 java.io.File localFile = 
 556   
                     new java.io.File(localFolder, localFiles[i]).getAbsoluteFile();
 557   
                 
 558  0
                 log("adding " + localFile + " to UnmatchedFileMap",
 559   
                     Project.MSG_DEBUG);
 560   
     
 561  0
                 if (localFile.isDirectory()) {
 562  0
                     this.put(localFile, "");
 563   
                 } 
 564   
                 else {
 565  0
                     this.put(localFile, "");
 566   
                 }
 567   
             }
 568  0
             return this;
 569   
         }
 570   
 
 571   
 
 572   
     
 573   
         /**
 574   
          * deletes uncontrolled items from the local tree.  It is assumed
 575   
          * that this method will not be called until all the items in the
 576   
          * corresponding folder have been processed, and that the internal map
 577   
          * will contain only uncontrolled items.
 578   
          */
 579  0
         void processUncontrolledItems() throws BuildException {
 580  0
             if (this.isActive()) {
 581  0
                 Enumeration e = this.keys();
 582  0
                 while (e.hasMoreElements()) {
 583  0
                     java.io.File local = (java.io.File) e.nextElement();
 584  0
                     delete(local);
 585   
                 }
 586   
             }
 587   
         }
 588   
     
 589   
         /**
 590   
          * deletes all files and if the file is a folder recursively deletes
 591   
          * everything in it.
 592   
          * 
 593   
          * @param local  The local file or folder to be deleted.
 594   
          */
 595  0
         void delete(java.io.File local) {
 596   
             // once we find a folder that isn't in the repository, 
 597   
             // anything below it can be deleted.
 598  0
             if (local.isDirectory() && isRecursive()) {
 599  0
                 String[] contents = local.list();
 600  0
                 for (int i=0; i< contents.length; i++) {
 601  0
                     java.io.File file = new java.io.File(local, contents[i]);
 602  0
                     delete(file);
 603   
                 }
 604   
             } 
 605  0
             local.delete();
 606  0
             log("Deleted uncontrolled item " + local.getAbsolutePath());
 607   
         }
 608   
     }
 609   
 
 610   
 
 611   
 }
 612