KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > starteam > TreeBasedTask


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional.starteam;
19
20 import com.starbase.starteam.Folder;
21 import com.starbase.starteam.Label;
22 import com.starbase.starteam.PropertyNames;
23 import com.starbase.starteam.StarTeamFinder;
24 import com.starbase.starteam.View;
25 import com.starbase.starteam.ViewConfiguration;
26 import com.starbase.util.OLEDate;
27 import java.text.ParseException JavaDoc;
28 import java.text.SimpleDateFormat JavaDoc;
29 import java.util.Date JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32 import org.apache.tools.ant.BuildException;
33 import org.apache.tools.ant.util.DateUtils;
34 import org.apache.tools.ant.DirectoryScanner;
35 import org.apache.tools.ant.Project;
36
37 /**
38  * TreeBasedTask.java
39  * This abstract class is the base for any tasks that are tree-based, that
40  * is, for tasks which iterate over a tree of folders in StarTeam which
41  * is reflected in a tree of folder the local machine.
42  *
43  * This class provides the tree-iteration functionality. Derived classes
44  * will implement their specific task functionality by the visitor pattern,
45  * specifically by implementing the method
46  * <code>visit(Folder rootStarteamFolder, java.io.File rootLocalFolder)</code>
47  *
48  * Created: Sat Dec 15 16:55:19 2001
49  *
50  * @see <a HREF="http://www.borland.com/us/products/starteam/index.html"
51  * >borland StarTeam Web Site</a>
52  */

53
54 public abstract class TreeBasedTask extends StarTeamTask {
55
56
57     ///////////////////////////////////////////////////////////////
58
// default values for attributes.
59
///////////////////////////////////////////////////////////////
60
/**
61      * This constant sets the filter to include all files. This default has
62      * the same result as <code>setIncludes("*")</code>.
63      *
64      * @see #getIncludes()
65      * @see #setIncludes(String includes)
66      */

67     public static final String JavaDoc DEFAULT_INCLUDESETTING = "*";
68
69     /**
70      * This disables the exclude filter by default. In other words, no files
71      * are excluded. This setting is equivalent to
72      * <code>setExcludes(null)</code>.
73      *
74      * @see #getExcludes()
75      * @see #setExcludes(String excludes)
76      */

77     public static final String JavaDoc DEFAULT_EXCLUDESETTING = null;
78
79     //ATTRIBUTES settable from ant.
80

81     /**
82      * The root folder of the operation in StarTeam.
83      */

84     private String JavaDoc rootStarteamFolder = "/";
85
86     /**
87      * The local folder corresponding to starteamFolder. If not specified
88      * the Star Team default folder will be used.
89      */

90     private String JavaDoc rootLocalFolder = null;
91
92     /**
93      * All files that fit this pattern are checked out.
94      */

95     private String JavaDoc includes = DEFAULT_INCLUDESETTING;
96
97     /**
98      * All files fitting this pattern are ignored.
99      */

100     private String JavaDoc excludes = DEFAULT_EXCLUDESETTING;
101
102     /**
103      * StarTeam label on which to perform task.
104      */

105     private String JavaDoc label = null;
106
107     /**
108      * Set recursion to false to check out files in only the given folder
109      * and not in its subfolders.
110      */

111     private boolean recursive = true;
112
113     /**
114      * Set preloadFileInformation to true to load all file information from the server
115      * at once. Increases performance significantly for projects with many files and/or folders.
116      */

117     private boolean preloadFileInformation = true;
118
119     /**
120      * If forced set to true, files in the target directory will
121      * be processed regardless of status in the repository.
122      * Usually this should be true if rootlocalfolder is set
123      * because status will be relative to the default folder, not
124      * to the one being processed.
125      */

126     private boolean forced = false;
127
128     private Label labelInUse = null;
129
130     /**
131      * holder for the asofdate attribute
132      */

133     private String JavaDoc asOfDate = null;
134
135     /**
136      * holder for the asofdateformat attribute
137      */

138     private String JavaDoc asOfDateFormat = null;
139
140
141
142     ///////////////////////////////////////////////////////////////
143
// GET/SET methods.
144
// Setters, of course are where ant user passes in values.
145
///////////////////////////////////////////////////////////////
146

147     /**
148      * Set the root of the subtree in the StarTeam repository from which to
149      * work; optional. Defaults to the root folder of the view ('/').
150      * @param rootStarteamFolder the root folder
151      */

152     public void setRootStarteamFolder(String JavaDoc rootStarteamFolder) {
153         this.rootStarteamFolder = rootStarteamFolder;
154     }
155
156     /**
157      * returns the root folder in the Starteam repository
158      * used for this operation
159      * @return the root folder in use
160      */

161     public String JavaDoc getRootStarteamFolder() {
162         return this.rootStarteamFolder;
163     }
164
165     /**
166      * Set the local folder that will be the root of the tree
167      * to which files are checked out; optional.
168      * If this is not supplied, then the StarTeam "default folder"
169      * associated with <tt>rootstarteamfolder</tt> is used.
170      *
171      * @param rootLocalFolder
172      * the local folder that will mirror
173      * this.rootStarteamFolder
174      */

175     public void setRootLocalFolder(String JavaDoc rootLocalFolder) {
176         this.rootLocalFolder = rootLocalFolder;
177     }
178
179
180
181     /**
182      * Returns the local folder specified by the user,
183      * corresponding to the starteam folder for this operation
184      * or null if not specified.
185      *
186      * @return the local folder that mirrors this.rootStarteamFolder
187      */

188     public String JavaDoc getRootLocalFolder() {
189         return this.rootLocalFolder;
190     }
191
192
193     /**
194      * Declare files to include using standard <tt>includes</tt> patterns; optional.
195      * @param includes A string of filter patterns to include. Separate the
196      * patterns by spaces.
197      * @see #getIncludes()
198      * @see #setExcludes(String excludes)
199      * @see #getExcludes()
200      */

201     public void setIncludes(String JavaDoc includes) {
202         this.includes = includes;
203     }
204
205     /**
206      * Gets the patterns from the include filter. Rather that duplicate the
207      * details of AntStarTeamCheckOut's filtering here, refer to these
208      * links:
209      *
210      * @return A string of filter patterns separated by spaces.
211      * @see #setIncludes(String includes)
212      * @see #setExcludes(String excludes)
213      * @see #getExcludes()
214      */

215     public String JavaDoc getIncludes() {
216         return includes;
217     }
218
219     /**
220      * if excludes have been specified, emit the list to the log
221      */

222     protected void logIncludes() {
223         if (DEFAULT_INCLUDESETTING != this.includes) {
224             log(" Includes specified: " + this.includes);
225         }
226     }
227
228     /**
229      * Declare files to exclude using standard <tt>excludes</tt> patterns; optional.
230      * When filtering files, AntStarTeamCheckOut
231      * uses an unmodified version of <code>DirectoryScanner</code>'s
232      * <code>match</code> method, so here are the patterns straight from the
233      * Ant source code:
234      * <br/>
235      * Matches a string against a pattern. The pattern contains two special
236      * characters:
237      * <br/>'*' which means zero or more characters,
238      * <br/>'?' which means one and only one character.
239      * <br/>
240      * For example, if you want to check out all files except .XML and
241      * .HTML files, you would put the following line in your program:
242      * <code>setExcludes("*.XML,*.HTML");</code>
243      * Finally, note that filters have no effect on the <b>directories</b>
244      * that are scanned; you could not skip over all files in directories
245      * whose names begin with "project," for instance.
246      * <br/>
247      * Treatment of overlapping inlcudes and excludes: To give a simplistic
248      * example suppose that you set your include filter to "*.htm *.html"
249      * and your exclude filter to "index.*". What happens to index.html?
250      * AntStarTeamCheckOut will not check out index.html, as it matches an
251      * exclude filter ("index.*"), even though it matches the include
252      * filter, as well.
253      * <br/>
254      * Please also read the following sections before using filters:
255      *
256      * @param excludes A string of filter patterns to exclude. Separate the
257      * patterns by spaces.
258      * @see #setIncludes(String includes)
259      * @see #getIncludes()
260      * @see #getExcludes()
261      */

262     public void setExcludes(String JavaDoc excludes) {
263         this.excludes = excludes;
264     }
265
266     /**
267      * Gets the patterns from the exclude filter. Rather that duplicate the
268      * details of AntStarTeanCheckOut's filtering here, refer to these
269      * links:
270      *
271      * @return A string of filter patterns separated by spaces.
272      * @see #setExcludes(String excludes)
273      * @see #setIncludes(String includes)
274      * @see #getIncludes()
275      */

276     public String JavaDoc getExcludes() {
277         return excludes;
278     }
279
280     /**
281      * if excludes have been specified, emit the list to the log
282      */

283     protected void logExcludes() {
284         if (DEFAULT_EXCLUDESETTING != this.excludes) {
285             log(" Excludes specified: " + this.excludes);
286         }
287     }
288
289     // CheckStyle:MethodNameCheck OFF - bc
290

291     /**
292      * protected function to allow subclasses to set the label (or not).
293      * sets the StarTeam label
294      *
295      * @param label name of the StarTeam label to be set
296      */

297     protected void _setLabel(String JavaDoc label) {
298         if (null != label) {
299             label = label.trim();
300             if (label.length() > 0) {
301                 this.label = label;
302             }
303         }
304     }
305
306     /**
307      * non-public method callable only by derived classes that implement
308      * setAsOfDate (so that derived tasks that do not accept this
309      * parameter will fail if user attempts to use it.
310      *
311      * @param asOfDate asOfDate entered by user.
312      * @since Ant 1.6
313      */

314     protected void _setAsOfDate(String JavaDoc asOfDate) {
315         if (asOfDate != null && asOfDate.length() > 0) {
316             this.asOfDate = asOfDate;
317         }
318     }
319
320     /**
321      * non-public method callable only by derived classes that implement
322      * setAsOfDateFormat (so that derived tasks that do not accept this
323      * parameter will fail if user attempts to use it.
324      *
325      * @param asOfDateFormat asOfDate format entered by user.
326      * @since Ant 1.6
327      */

328     protected void _setAsOfDateFormat(String JavaDoc asOfDateFormat) {
329         if (asOfDateFormat != null && asOfDateFormat.length() > 0) {
330             this.asOfDateFormat = asOfDateFormat;
331         }
332     }
333
334     // CheckStyle:VisibilityModifier ON
335

336
337     /**
338      * return the asOfDate entered by the user for internal use by derived
339      * classes.
340      *
341      * @return the asOfDate entered by the user
342      * @since Ant 1.6
343      */

344     protected String JavaDoc getAsOfDate() {
345         return this.asOfDate;
346     }
347
348     /**
349      * If an asofDate parameter has been supplied by the user return a
350      * StarTeam view based on the configuration of the StarTeam view
351      * specified the user as of the date specified in the parameter.
352      * If no asofDate has been specified, return null.
353      *
354      * This method is meant to be called from within implementations of the
355      * <code>createSnapshotView</code> abstract method.
356      *
357      * @param raw the raw view to be configured as of the supplied date
358      *
359      * @return the view as configured.
360      * @exception BuildException
361      * thrown if the date is not parsable by the default or
362      * supplied format patterns.
363      * @since Ant 1.6
364      */

365     protected View getViewConfiguredByDate(View raw) throws BuildException {
366         if (this.asOfDate == null) {
367             return null;
368         }
369         Date asOfDate = null;
370         SimpleDateFormat JavaDoc fmt = null;
371         if (this.asOfDateFormat != null) {
372             fmt = new SimpleDateFormat JavaDoc(this.asOfDateFormat);
373             try {
374                 asOfDate = fmt.parse(this.asOfDate);
375             } catch (ParseException JavaDoc px) {
376                 throw new BuildException("AsOfDate "
377                                          + this.asOfDate
378                                          + " not parsable by supplied format "
379                                          + this.asOfDateFormat);
380             }
381         } else {
382             try {
383                 asOfDate = DateUtils.parseIso8601DateTimeOrDate(
384                     this.asOfDate);
385             } catch (ParseException JavaDoc px) {
386                 throw new BuildException("AsOfDate "
387                                          + this.asOfDate
388                                          + " not parsable by default"
389                                          + " ISO8601 formats");
390             }
391         }
392         return new View(raw, ViewConfiguration.createFromTime(
393             new OLEDate(asOfDate)));
394     }
395
396     /**
397      * return the label passed to the task by the user as a string
398      *
399      * @return the label passed to the task by the user as a string
400      */

401     protected String JavaDoc getLabel() {
402         return this.label;
403     }
404
405     /**
406      * Get the value of recursive.
407      * @return value of recursive.
408      */

409     public boolean isRecursive() {
410         return this.recursive;
411     }
412
413     /**
414      * Flag to set to include files in subfolders in the operation; optional,
415      * default true.
416      * @param v Value to assign to recursive.
417      */

418     public void setRecursive(boolean v) {
419         this.recursive = v;
420     }
421
422     /**
423      * Get the value of preloadFileInformation.
424      * @return value of preloadFileInformation.
425      */

426     public boolean isPreloadFileInformation() {
427         return this.preloadFileInformation;
428     }
429
430     /**
431      * Flag to set to preload file information from the server; optional,
432      * default true.
433      * Increases performance significantly for projects with many files
434      * and/or folders.
435      * @param v Value to assign to preloadFileInformation.
436      */

437     public void setPreloadFileInformation(boolean v) {
438         this.preloadFileInformation = v;
439     }
440
441     /**
442      * Get the value of forced.
443      * @return value of forced.
444      */

445     public boolean isForced() {
446         return this.forced;
447     }
448
449     /**
450      * Flag to force actions regardless of the status
451      * that StarTeam is maintaining for the file; optional, default false.
452      * If <tt>rootlocalfolder</tt> is set then
453      * this should be set "true" as otherwise the checkout will be based on statuses
454      * which do not relate to the target folder.
455      * @param v Value to assign to forced.
456      */

457     public void setForced(boolean v) {
458         this.forced = v;
459     }
460
461     /**
462      * returns true if a label has been specified and it is a view label.
463      *
464      * @return true if a label has been specified and it is a view label
465      */

466     protected boolean isUsingViewLabel() {
467         return null != this.labelInUse && this.labelInUse.isViewLabel();
468     }
469
470     /**
471      * returns true if a label has been specified and it is a revision label.
472      *
473      * @return true if a label has been specified and it is a revision label
474      */

475     protected boolean isUsingRevisionLabel() {
476         return null != this.labelInUse && this.labelInUse.isRevisionLabel();
477     }
478
479     /**
480      * returns the label being used
481      *
482      * @return the label being used
483      */

484     protected Label getLabelInUse() {
485         return this.labelInUse;
486     }
487
488     /**
489      * show the label in the log and its type.
490      */

491     protected void logLabel() {
492         if (this.isUsingViewLabel()) {
493             log(" Using view label " + getLabel());
494         } else if (this.isUsingRevisionLabel()) {
495             log(" Using revision label " + getLabel());
496         }
497     }
498
499     /**
500      * show the asofDate in the log
501      * @since Ant 1.6
502      */

503     protected void logAsOfDate() {
504         if (null != this.asOfDate) {
505             log(" Using view as of date " + getAsOfDate());
506         }
507     }
508
509     ///////////////////////////////////////////////////////////////
510
// INCLUDE-EXCLUDE processing
511
///////////////////////////////////////////////////////////////
512

513     /**
514      * Look if the file should be processed by the task.
515      * Don't process it if it fits no include filters or if
516      * it fits an exclude filter.
517      *
518      * @param pName the item name to look for being included.
519      *
520      * @return whether the file should be processed or not.
521      */

522     protected boolean shouldProcess(String JavaDoc pName) {
523         boolean includeIt = matchPatterns(getIncludes(), pName);
524         boolean excludeIt = matchPatterns(getExcludes(), pName);
525         return (includeIt && !excludeIt);
526     }
527
528     /**
529      * Convenience method to see if a string match a one pattern
530      * in given set of space-separated patterns.
531      * @param patterns the space-separated list of patterns.
532      * @param pName the name to look for matching.
533      * @return whether the name match at least one pattern.
534      */

535     protected boolean matchPatterns(String JavaDoc patterns, String JavaDoc pName) {
536         if (patterns == null) {
537             return false;
538         }
539         StringTokenizer JavaDoc exStr = new StringTokenizer JavaDoc(patterns, ",");
540         while (exStr.hasMoreTokens()) {
541             if (DirectoryScanner.match(exStr.nextToken(), pName)) {
542                 return true;
543             }
544         }
545         return false;
546     }
547
548     /**
549      * Finds and opens the root starteam folder of the operation specified
550      * by this task. This will be one of the following cases:
551      *
552      * @return Starteam's root folder for the operation.
553      * @exception BuildException
554      * if the root folder cannot be found in the repository
555      */

556     private Folder configureRootStarteamFolder()
557         throws BuildException {
558         Folder starteamrootfolder = null;
559         try {
560             // no root local mapping has been specified.
561
View snapshot = openView();
562
563             // find the starteam folder specified to be the root of the
564
// operation. Throw if it can't be found.
565

566             starteamrootfolder =
567                     StarTeamFinder.findFolder(snapshot.getRootFolder(),
568                             this.rootStarteamFolder);
569
570             if (this.isPreloadFileInformation()) {
571                 PropertyNames pn = getServer().getPropertyNames();
572                 String JavaDoc[] props = new String JavaDoc[] {pn.FILE_NAME, pn.FILE_PATH,
573                                                pn.FILE_STATUS, pn.MODIFIED_TIME,
574                                                pn.FILE_FILE_TIME_AT_CHECKIN,
575                                                pn.MODIFIED_USER_ID, pn.FILE_SIZE,
576                                                pn.FILE_ENCODING};
577
578                 int depth = this.isRecursive() ? -1 : 0;
579                 starteamrootfolder.populateNow(getServer().getTypeNames().FILE,
580                                                 props, depth);
581             }
582
583
584         } catch (BuildException e) {
585             throw e;
586         } catch (Exception JavaDoc e) {
587             StringBuffer JavaDoc msg = new StringBuffer JavaDoc("Unable to find root folder ")
588                     .append(this.rootStarteamFolder)
589                     .append(" in repository at ")
590                     .append(getURL());
591             if (this.label != null) {
592                 msg.append(" using specified label ").append(this.label);
593             }
594             if (this.asOfDate != null) {
595                 msg.append(" as of specified date ")
596                     .append(this.asOfDate);
597             }
598             throw new BuildException(msg.toString(), e);
599
600         }
601
602         if (null == starteamrootfolder) {
603             throw new BuildException("Unable to find root folder "
604                 + this.rootStarteamFolder + " in repository at " + getURL());
605         }
606
607         return starteamrootfolder;
608     }
609
610     /**
611      * Returns the local folder mapped to the given StarTeam root folder
612      * of the operation. There are two cases here, depending on whether
613      * <code>rootLocalFolder</code> is defined.
614      * If <code>rootLocalFolder</code> is defined, it will be used to
615      * establish a root mapping. Otherwise, the repository's default root
616      * folder will be used.
617      *
618      * @param starteamrootfolder
619      * root Starteam folder initialized for the operation
620      *
621      * @return the local folder corresponding to the root Starteam folder.
622      * @see findRootStarteamFolder
623      */

624     private java.io.File JavaDoc getLocalRootMapping(Folder starteamrootfolder) {
625         // set the local folder.
626
String JavaDoc localrootfolder;
627         if (null != this.rootLocalFolder) {
628             localrootfolder = rootLocalFolder;
629         } else {
630             // either use default path or root local mapping,
631
// which is now embedded in the root folder
632
localrootfolder = starteamrootfolder.getPathFragment();
633         }
634
635         return new java.io.File JavaDoc(localrootfolder);
636
637     }
638
639     /**
640      * extenders should emit to the log an entry describing the parameters
641      * that will be used by this operation.
642      *
643      * @param starteamrootFolder
644      * root folder in StarTeam for the operation
645      * @param targetrootFolder
646      * root local folder for the operation (whether specified by the user or not.
647      */

648     protected abstract void logOperationDescription(
649         Folder starteamrootFolder, java.io.File JavaDoc targetrootFolder);
650
651     /**
652      * This method does the work of opening the supplied Starteam view and
653      * calling the <code>visit()</code> method to perform the task.
654      * Derived classes can customize the called methods
655      * <code>testPreconditions()</code> and <code>visit()</code>.
656      *
657      * @exception BuildException if any error occurs in the processing
658      * @see <code>testPreconditions()</code>
659      * @see <code>visit()</code>
660      */

661
662     public final void execute() throws BuildException {
663         try {
664
665             Folder starteamrootfolder = configureRootStarteamFolder();
666
667             // set the local folder.
668
java.io.File JavaDoc localrootfolder =
669                 getLocalRootMapping(starteamrootfolder);
670
671             testPreconditions();
672
673             // Tell user what he is doing
674
logOperationDescription(starteamrootfolder, localrootfolder);
675
676             // Inspect everything in the root folder and then recursively
677
visit(starteamrootfolder, localrootfolder);
678
679         } catch (Exception JavaDoc e) {
680             throw new BuildException(e);
681         } finally {
682             disconnectFromServer();
683         }
684     }
685
686     private void findLabel(View v) throws BuildException {
687         Label[] allLabels = v.getLabels();
688         for (int i = 0; i < allLabels.length; i++) {
689             Label stLabel = allLabels[i];
690             log("checking label " + stLabel.getName(), Project.MSG_DEBUG);
691             if (stLabel != null && !stLabel.isDeleted() && stLabel.getName().equals(this.label)) {
692                 if (!stLabel.isRevisionLabel() && !stLabel.isViewLabel()) {
693                     throw new BuildException("Unexpected label type.");
694                 }
695                 log("using label " + stLabel.getName(), Project.MSG_VERBOSE);
696                 this.labelInUse = stLabel;
697                 return;
698             }
699         }
700         throw new BuildException("Error: label "
701                 + this.label
702                 + " does not exist in view "
703                 + v.getFullName());
704
705     }
706
707     /**
708      * Helper method calls on the StarTeam API to retrieve an ID number
709      * for the specified view, corresponding to this.label.
710      * @param v the <code>View</code> in which to search for <code>this.label</code>
711      * @return the ID number corresponding to <code>this.label</code> or -1 if
712      * no label was provided.
713      * @exception BuildException if <code>this.label</code> does not correspond
714      * to any label in the supplied view
715      */

716     protected int getLabelID(View v) throws BuildException {
717         if (null != this.label) {
718             findLabel(v);
719             return this.labelInUse.getID();
720         }
721         return -1;
722     }
723
724     /**
725      * Get the id of the label in use.
726      * @return id of the label in use, if labelinuse is present,
727      * otherwise return null
728      */

729     protected int getIDofLabelInUse() {
730         if (null != this.labelInUse) {
731             return this.labelInUse.getID();
732         }
733         return -1;
734     }
735
736     /**
737      * Derived classes must override this class to define actual processing
738      * to be performed on each folder in the tree defined for the task
739      *
740      * @param rootStarteamFolder
741      * the StarTeam folderto be visited
742      * @param rootLocalFolder
743      * the local mapping of rootStarteamFolder
744      *
745      * @throws BuildException on error
746      */

747     protected abstract void visit(Folder rootStarteamFolder,
748                                   java.io.File JavaDoc rootLocalFolder)
749             throws BuildException;
750
751     /**
752      * Derived classes must override this method to define tests for
753      * any preconditons required by the task. This method is called at
754      * the beginning of the execute() method.
755      *
756      * @exception BuildException throw if any fatal error exists in the
757      * parameters supplied. If there is a non-fatal condition, just writing
758      * to the log may be appropriate.
759      * @see <code>execute()</code>
760      */

761     protected abstract void testPreconditions() throws BuildException;
762
763     /**
764      * Return the full repository path name of a file. Surprisingly there's
765      * no method in com.starbase.starteam.File to provide this.
766      *
767      * @param remotefile the Star Team file whose path is to be returned
768      *
769      * @return the full repository path name of a file.
770      */

771     public static String JavaDoc getFullRepositoryPath(
772         com.starbase.starteam.File remotefile) {
773         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
774         sb.append(remotefile.getParentFolderHierarchy())
775           .append(remotefile.getName());
776         return sb.toString();
777     }
778
779     /**
780      * This class implements a map of existing local files to possibly
781      * existing repository files. The map is created by a TreeBasedTask
782      * upon recursing into a directory. Each local item is mapped to an
783      * unattached StarTeam object of the proper type, File->File and
784      * Directory->Folder.
785      *
786      * As the TreeBased does its work, it deletes from the map all items
787      * it has processed.
788      *
789      * When the TreeBased task processes all the items from the repository,
790      * whatever items left in the UnmatchedFileMap are uncontrolled items
791      * and can be processed as appropriate to the task. In the case of
792      * Checkouts, they can be optionally deleted from the local tree. In the
793      * case of Checkins they can optionally be added to the repository.
794      */

795     protected abstract class UnmatchedFileMap extends Hashtable JavaDoc {
796
797         /**
798          * initializes the UnmatchedFileMap with entries from the local folder
799          * These will be mapped to the corresponding StarTeam entry even though
800          * it will not, in fact, exist in the repository. But through it, it
801          * can be added, listed, etc.
802          *
803          * @param localFolder
804          * the local folder from which the mappings will be made.
805          * @param remoteFolder
806          * the corresponding StarTeam folder which will be processed.
807          */

808         UnmatchedFileMap init(java.io.File JavaDoc localFolder, Folder remoteFolder) {
809             if (!localFolder.exists()) {
810                 return this;
811             }
812
813             String JavaDoc[] localFiles = localFolder.list();
814
815             for (int i = 0; i < localFiles.length; i++) {
816                 String JavaDoc fn = localFiles[i];
817                 java.io.File JavaDoc localFile =
818                     new java.io.File JavaDoc(localFolder, localFiles[i]).getAbsoluteFile();
819
820                 log("adding " + localFile + " to UnmatchedFileMap",
821                     Project.MSG_DEBUG);
822
823                 if (localFile.isDirectory()) {
824                     this.put(localFile, new Folder(remoteFolder, fn, fn));
825                 } else {
826                     com.starbase.starteam.File remoteFile =
827                         new com.starbase.starteam.File(remoteFolder);
828                     remoteFile.setName(fn);
829                     this.put(localFile, remoteFile);
830                 }
831             }
832             return this;
833         }
834
835         /**
836          * remove an item found to be controlled from the map.
837          *
838          * @param localFile the local item found to be controlled.
839          */

840         void removeControlledItem(java.io.File JavaDoc localFile) {
841             if (isActive()) {
842                 log("removing processed " + localFile.getAbsoluteFile()
843                     + " from UnmatchedFileMap", Project.MSG_DEBUG);
844                 this.remove(localFile.getAbsoluteFile());
845             }
846         }
847         /**
848          * override will perform the action appropriate for its task to perform
849          * on items which are on the local tree but not in StarTeam. It is
850          * assumed that this method will not be called until all the items in
851          * the corresponding folder have been processed, and that the internal
852          * map * will contain only uncontrolled items.
853          */

854         abstract void processUncontrolledItems() throws BuildException;
855
856         /**
857          * overrides must define this to declare how this method knows if it
858          * is active. This presents extra clock cycles when the functionality
859          * is not called for.
860          *
861          * @return True if this object is to perform its functionality.
862          */

863         protected abstract boolean isActive();
864
865     }
866
867 }
868
Popular Tags