source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/starteam/TreeBasedTask.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 30.1 KB
Line 
1/*
2 * Copyright 2001-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.optional.starteam;
18
19import com.starbase.starteam.Folder;
20import com.starbase.starteam.Label;
21import com.starbase.starteam.PropertyNames;
22import com.starbase.starteam.StarTeamFinder;
23import com.starbase.starteam.View;
24import com.starbase.starteam.ViewConfiguration;
25import com.starbase.util.OLEDate;
26import java.text.ParseException;
27import java.text.SimpleDateFormat;
28import java.util.Date;
29import java.util.Hashtable;
30import java.util.StringTokenizer;
31import org.apache.tools.ant.BuildException;
32import org.apache.tools.ant.util.DateUtils;
33import org.apache.tools.ant.DirectoryScanner;
34import org.apache.tools.ant.Project;
35
36/**
37 * TreeBasedTask.java
38 * This abstract class is the base for any tasks that are tree-based, that
39 * is, for tasks which iterate over a tree of folders in StarTeam which
40 * is reflected in a tree of folder the local machine.
41 *
42 * This class provides the tree-iteration functionality. Derived classes
43 * will implement their specific task functionality by the visitor pattern,
44 * specifically by implementing the method
45 * <code>visit(Folder rootStarteamFolder, java.io.File rootLocalFolder)</code>
46 *
47 * Created: Sat Dec 15 16:55:19 2001
48 *
49 * @version 1.0
50 * @see <A HREF="http://www.starbase.com/">StarBase Web Site</A>
51 */
52
53public abstract class TreeBasedTask extends StarTeamTask {
54
55
56 ///////////////////////////////////////////////////////////////
57 // default values for attributes.
58 ///////////////////////////////////////////////////////////////
59 /**
60 * This constant sets the filter to include all files. This default has
61 * the same result as <CODE>setIncludes("*")</CODE>.
62 *
63 * @see #getIncludes()
64 * @see #setIncludes(String includes)
65 */
66 public static final String DEFAULT_INCLUDESETTING = "*";
67
68 /**
69 * This disables the exclude filter by default. In other words, no files
70 * are excluded. This setting is equivalent to
71 * <CODE>setExcludes(null)</CODE>.
72 *
73 * @see #getExcludes()
74 * @see #setExcludes(String excludes)
75 */
76 public static final String DEFAULT_EXCLUDESETTING = null;
77
78 //ATTRIBUTES settable from ant.
79
80 /**
81 * The root folder of the operation in StarTeam.
82 */
83 private String rootStarteamFolder = "/";
84
85 /**
86 * The local folder corresponding to starteamFolder. If not specified
87 * the Star Team default folder will be used.
88 */
89 private String rootLocalFolder = null;
90
91 /**
92 * All files that fit this pattern are checked out.
93 */
94 private String includes = DEFAULT_INCLUDESETTING;
95
96 /**
97 * All files fitting this pattern are ignored.
98 */
99 private String excludes = DEFAULT_EXCLUDESETTING;
100
101 /**
102 * StarTeam label on which to perform task.
103 */
104 private String label = null;
105
106 /**
107 * Set recursion to false to check out files in only the given folder
108 * and not in its subfolders.
109 */
110 private boolean recursive = true;
111
112 /**
113 * Set preloadFileInformation to true to load all file information from the server
114 * at once. Increases performance significantly for projects with many files and/or folders.
115 */
116 private boolean preloadFileInformation = true;
117
118 /**
119 * If forced set to true, files in the target directory will
120 * be processed regardless of status in the repository.
121 * Usually this should be true if rootlocalfolder is set
122 * because status will be relative to the default folder, not
123 * to the one being processed.
124 */
125 private boolean forced = false;
126
127 private Label labelInUse = null;
128
129 /**
130 * holder for the asofdate attribute
131 */
132 private String asOfDate = null;
133
134 /**
135 * holder for the asofdateformat attribute
136 */
137 private String asOfDateFormat = null;
138
139
140
141 ///////////////////////////////////////////////////////////////
142 // GET/SET methods.
143 // Setters, of course are where ant user passes in values.
144 ///////////////////////////////////////////////////////////////
145
146 /**
147 * Set the root of the subtree in the StarTeam repository from which to
148 * work; optional. Defaults to the root folder of the view ('/').
149 * @param rootStarteamFolder the root folder
150 */
151 public void setRootStarteamFolder(String rootStarteamFolder) {
152 this.rootStarteamFolder = rootStarteamFolder;
153 }
154
155 /**
156 * returns the root folder in the Starteam repository
157 * used for this operation
158 * @return the root folder in use
159 */
160 public String getRootStarteamFolder() {
161 return this.rootStarteamFolder;
162 }
163
164 /**
165 * Set the local folder that will be the root of the tree
166 * to which files are checked out; optional.
167 * If this is not supplied, then the StarTeam "default folder"
168 * associated with <tt>rootstarteamfolder</tt> is used.
169 *
170 * @param rootLocalFolder
171 * the local folder that will mirror
172 * this.rootStarteamFolder
173 */
174 public void setRootLocalFolder(String rootLocalFolder) {
175 this.rootLocalFolder = rootLocalFolder;
176 }
177
178
179
180 /**
181 * Returns the local folder specified by the user,
182 * corresponding to the starteam folder for this operation
183 * or null if not specified.
184 *
185 * @return the local folder that mirrors this.rootStarteamFolder
186 */
187 public String getRootLocalFolder() {
188 return this.rootLocalFolder;
189 }
190
191
192 /**
193 * Declare files to include using standard <tt>includes</tt> patterns; optional.
194 * @param includes A string of filter patterns to include. Separate the
195 * patterns by spaces.
196 * @see #getIncludes()
197 * @see #setExcludes(String excludes)
198 * @see #getExcludes()
199 */
200 public void setIncludes(String includes) {
201 this.includes = includes;
202 }
203
204 /**
205 * Gets the patterns from the include filter. Rather that duplicate the
206 * details of AntStarTeamCheckOut's filtering here, refer to these
207 * links:
208 *
209 * @return A string of filter patterns separated by spaces.
210 * @see #setIncludes(String includes)
211 * @see #setExcludes(String excludes)
212 * @see #getExcludes()
213 */
214 public String getIncludes() {
215 return includes;
216 }
217
218 /**
219 * if excludes have been specified, emit the list to the log
220 */
221 protected void logIncludes() {
222 if (this.DEFAULT_INCLUDESETTING != this.includes) {
223 log(" Includes specified: " + this.includes);
224 }
225 }
226
227 /**
228 * Declare files to exclude using standard <tt>excludes</tt> patterns; optional.
229 * When filtering files, AntStarTeamCheckOut
230 * uses an unmodified version of <CODE>DirectoryScanner</CODE>'s
231 * <CODE>match</CODE> method, so here are the patterns straight from the
232 * Ant source code:
233 * <BR><BR>
234 * Matches a string against a pattern. The pattern contains two special
235 * characters:
236 * <BR>'*' which means zero or more characters,
237 * <BR>'?' which means one and only one character.
238 * <BR><BR>
239 * For example, if you want to check out all files except .XML and
240 * .HTML files, you would put the following line in your program:
241 * <CODE>setExcludes("*.XML,*.HTML");</CODE>
242 * Finally, note that filters have no effect on the <B>directories</B>
243 * that are scanned; you could not skip over all files in directories
244 * whose names begin with "project," for instance.
245 * <BR><BR>
246 * Treatment of overlapping inlcudes and excludes: To give a simplistic
247 * example suppose that you set your include filter to "*.htm *.html"
248 * and your exclude filter to "index.*". What happens to index.html?
249 * AntStarTeamCheckOut will not check out index.html, as it matches an
250 * exclude filter ("index.*"), even though it matches the include
251 * filter, as well.
252 * <BR><BR>
253 * Please also read the following sections before using filters:
254 *
255 * @param excludes A string of filter patterns to exclude. Separate the
256 * patterns by spaces.
257 * @see #setIncludes(String includes)
258 * @see #getIncludes()
259 * @see #getExcludes()
260 */
261 public void setExcludes(String excludes) {
262 this.excludes = excludes;
263 }
264
265 /**
266 * Gets the patterns from the exclude filter. Rather that duplicate the
267 * details of AntStarTeanCheckOut's filtering here, refer to these
268 * links:
269 *
270 * @return A string of filter patterns separated by spaces.
271 * @see #setExcludes(String excludes)
272 * @see #setIncludes(String includes)
273 * @see #getIncludes()
274 */
275 public String getExcludes() {
276 return excludes;
277 }
278
279 /**
280 * if excludes have been specified, emit the list to the log
281 */
282 protected void logExcludes() {
283 if (this.DEFAULT_EXCLUDESETTING != this.excludes) {
284 log(" Excludes specified: " + this.excludes);
285 }
286 }
287
288
289 /**
290 * protected function to allow subclasses to set the label (or not).
291 * sets the StarTeam label
292 *
293 * @param label name of the StarTeam label to be set
294 */
295 protected void _setLabel(String label) {
296 if (null != label) {
297 label = label.trim();
298 if (label.length() > 0) {
299 this.label = label;
300 }
301 }
302 }
303
304 /**
305 * non-public method callable only by derived classes that implement
306 * setAsOfDate (so that derived tasks that do not accept this
307 * parameter will fail if user attempts to use it.
308 *
309 * @param asOfDate asOfDate entered by user.
310 * @since Ant 1.6
311 */
312 protected void _setAsOfDate(String asOfDate) {
313 if (asOfDate != null && asOfDate.length() > 0) {
314 this.asOfDate = asOfDate;
315 }
316 }
317
318 /**
319 * non-public method callable only by derived classes that implement
320 * setAsOfDateFormat (so that derived tasks that do not accept this
321 * parameter will fail if user attempts to use it.
322 *
323 * @param asOfDateFormat asOfDate format entered by user.
324 * @since Ant 1.6
325 */
326 protected void _setAsOfDateFormat(String asOfDateFormat) {
327 if (asOfDateFormat != null && asOfDateFormat.length() > 0) {
328 this.asOfDateFormat = asOfDateFormat;
329 }
330 }
331
332
333 /**
334 * return the asOfDate entered by the user for internal use by derived
335 * classes.
336 *
337 * @return the asOfDate entered by the user
338 * @since Ant 1.6
339 */
340 protected String getAsOfDate() {
341 return this.asOfDate;
342 }
343
344
345
346 /**
347 * If an asofDate parameter has been supplied by the user return a
348 * StarTeam view based on the configuration of the StarTeam view
349 * specified the user as of the date specified in the parameter.
350 * If no asofDate has been specified, return null.
351 *
352 * This method is meant to be called from within implementations of the
353 * <code>createSnapshotView</code> abstract method.
354 *
355 * @param raw the raw view to be configured as of the supplied date
356 *
357 * @return the view as configured.
358 * @exception BuildException
359 * thrown if the date is not parsable by the default or
360 * supplied format patterns.
361 * @since Ant 1.6
362 */
363 protected View getViewConfiguredByDate(View raw) throws BuildException {
364 if (this.asOfDate == null) {
365 return null;
366 }
367 Date asOfDate = null;
368 SimpleDateFormat fmt = null;
369 if (this.asOfDateFormat != null) {
370 fmt = new SimpleDateFormat(this.asOfDateFormat);
371 try {
372 asOfDate = fmt.parse(this.asOfDate);
373 }
374 catch (ParseException px)
375 {
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 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
398 /**
399 * return the label passed to the task by the user as a string
400 *
401 * @return the label passed to the task by the user as a string
402 */
403 protected String getLabel() {
404 return this.label;
405 }
406
407 /**
408 * Get the value of recursive.
409 * @return value of recursive.
410 */
411 public boolean isRecursive() {
412 return this.recursive;
413 }
414
415 /**
416 * Flag to set to include files in subfolders in the operation; optional,
417 * default true.
418 * @param v Value to assign to recursive.
419 */
420 public void setRecursive(boolean v) {
421 this.recursive = v;
422 }
423
424 /**
425 * Get the value of preloadFileInformation.
426 * @return value of preloadFileInformation.
427 */
428 public boolean isPreloadFileInformation() {
429 return this.preloadFileInformation;
430 }
431
432 /**
433 * Flag to set to preload file information from the server; optional,
434 * default true.
435 * Increases performance significantly for projects with many files
436 * and/or folders.
437 * @param v Value to assign to preloadFileInformation.
438 */
439 public void setPreloadFileInformation(boolean v) {
440 this.preloadFileInformation = v;
441 }
442
443 /**
444 * Get the value of forced.
445 * @return value of forced.
446 */
447 public boolean isForced() {
448 return this.forced;
449 }
450
451 /**
452 * Flag to force actions regardless of the status
453 * that StarTeam is maintaining for the file; optional, default false.
454 * If <tt>rootlocalfolder</tt> is set then
455 * this should be set "true" as otherwise the checkout will be based on statuses
456 * which do not relate to the target folder.
457 * @param v Value to assign to forced.
458 */
459 public void setForced(boolean v) {
460 this.forced = v;
461 }
462
463 /**
464 * returns true if a label has been specified and it is a view label.
465 *
466 * @return true if a label has been specified and it is a view label
467 */
468 protected boolean isUsingViewLabel() {
469 return null != this.labelInUse && this.labelInUse.isViewLabel();
470 }
471 /**
472 * returns true if a label has been specified and it is a revision label.
473 *
474 * @return true if a label has been specified and it is a revision label
475 */
476 protected boolean isUsingRevisionLabel() {
477 return null != this.labelInUse && this.labelInUse.isRevisionLabel();
478 }
479
480 /**
481 * returns the label being used
482 *
483 * @return the label being used
484 */
485 protected Label getLabelInUse() {
486 return this.labelInUse;
487 }
488
489 /**
490 * show the label in the log and its type.
491 */
492 protected void logLabel() {
493 if (this.isUsingViewLabel()) {
494 log(" Using view label " + getLabel());
495 } else if (this.isUsingRevisionLabel()) {
496 log(" Using revision label " + getLabel());
497 }
498 }
499
500 /**
501 * show the asofDate in the log
502 * @since Ant 1.6
503 */
504 protected void logAsOfDate() {
505 if (null != this.asOfDate) {
506 log(" Using view as of date " + getAsOfDate());
507 }
508 }
509
510
511
512
513
514 ///////////////////////////////////////////////////////////////
515 // INCLUDE-EXCLUDE processing
516 ///////////////////////////////////////////////////////////////
517
518 /**
519 * Look if the file should be processed by the task.
520 * Don't process it if it fits no include filters or if
521 * it fits an exclude filter.
522 *
523 * @param pName the item name to look for being included.
524 *
525 * @return whether the file should be processed or not.
526 */
527 protected boolean shouldProcess(String pName) {
528 boolean includeIt = matchPatterns(getIncludes(), pName);
529 boolean excludeIt = matchPatterns(getExcludes(), pName);
530 return (includeIt && !excludeIt);
531 }
532
533 /**
534 * Convenience method to see if a string match a one pattern
535 * in given set of space-separated patterns.
536 * @param patterns the space-separated list of patterns.
537 * @param pName the name to look for matching.
538 * @return whether the name match at least one pattern.
539 */
540 protected boolean matchPatterns(String patterns, String pName) {
541 if (patterns == null) {
542 return false;
543 }
544 StringTokenizer exStr = new StringTokenizer(patterns, ",");
545 while (exStr.hasMoreTokens()) {
546 if (DirectoryScanner.match(exStr.nextToken(), pName)) {
547 return true;
548 }
549 }
550 return false;
551 }
552
553 /**
554 * Finds and opens the root starteam folder of the operation specified
555 * by this task. This will be one of the following cases:
556 *
557 * @return Starteam's root folder for the operation.
558 * @exception BuildException
559 * if the root folder cannot be found in the repository
560 */
561 private final Folder configureRootStarteamFolder()
562 throws BuildException {
563 Folder starteamrootfolder = null;
564 try {
565 // no root local mapping has been specified.
566 View snapshot = openView();
567
568 // find the starteam folder specified to be the root of the
569 // operation. Throw if it can't be found.
570
571 starteamrootfolder =
572 StarTeamFinder.findFolder(snapshot.getRootFolder(),
573 this.rootStarteamFolder);
574
575 if (this.isPreloadFileInformation()) {
576 PropertyNames pn = getServer().getPropertyNames();
577 String[] props = new String[] {pn.FILE_NAME, pn.FILE_PATH,
578 pn.FILE_STATUS, pn.MODIFIED_TIME,
579 pn.FILE_FILE_TIME_AT_CHECKIN,
580 pn.MODIFIED_USER_ID, pn.FILE_SIZE};
581
582 int depth = this.isRecursive() ? -1 : 0;
583 starteamrootfolder.populateNow(getServer().getTypeNames().FILE,
584 props, depth);
585 }
586
587
588 } catch (BuildException e) {
589 throw e;
590 } catch (Exception e) {
591 StringBuffer msg = new StringBuffer("Unable to find root folder ")
592 .append(this.rootStarteamFolder)
593 .append(" in repository at ")
594 .append(getURL());
595 if (this.label != null) {
596 msg.append(" using specified label ").append(this.label);
597 }
598 if (this.asOfDate != null) {
599 msg.append(" as of specified date ")
600 .append(this.asOfDate);
601 }
602 throw new BuildException(msg.toString(), e);
603
604 }
605
606 if (null == starteamrootfolder) {
607 throw new BuildException("Unable to find root folder "
608 + this.rootStarteamFolder + " in repository at " + getURL());
609 }
610
611 return starteamrootfolder;
612 }
613
614 /**
615 * Returns the local folder mapped to the given StarTeam root folder
616 * of the operation. There are two cases here, depending on whether
617 * <code>rootLocalFolder</code> is defined.
618 * If <code>rootLocalFolder</code> is defined, it will be used to
619 * establish a root mapping. Otherwise, the repository's default root
620 * folder will be used.
621 *
622 * @param starteamrootfolder
623 * root Starteam folder initialized for the operation
624 *
625 * @return the local folder corresponding to the root Starteam folder.
626 * @see findRootStarteamFolder
627 */
628 private final java.io.File getLocalRootMapping(Folder starteamrootfolder) {
629 // set the local folder.
630 String localrootfolder;
631 if (null != this.rootLocalFolder) {
632 localrootfolder = rootLocalFolder;
633 } else {
634 // either use default path or root local mapping,
635 // which is now embedded in the root folder
636 localrootfolder = starteamrootfolder.getPathFragment();
637 }
638
639 return new java.io.File(localrootfolder);
640
641 }
642
643 /**
644 * extenders should emit to the log an entry describing the parameters
645 * that will be used by this operation.
646 *
647 * @param starteamrootFolder
648 * root folder in StarTeam for the operation
649 * @param targetrootFolder
650 * root local folder for the operation (whether specified by the user or not.
651 */
652 protected abstract void logOperationDescription(
653 Folder starteamrootFolder, java.io.File targetrootFolder);
654
655 /**
656 * This method does the work of opening the supplied Starteam view and
657 * calling the <code>visit()</code> method to perform the task.
658 * Derived classes can customize the called methods
659 * <code>testPreconditions()</code> and <code>visit()</code>.
660 *
661 * @exception BuildException if any error occurs in the processing
662 * @see <code>testPreconditions()</code>
663 * @see <code>visit()</code>
664 */
665
666 public final void execute() throws BuildException {
667 try {
668
669 Folder starteamrootfolder = configureRootStarteamFolder();
670
671 // set the local folder.
672 java.io.File localrootfolder =
673 getLocalRootMapping(starteamrootfolder);
674
675 testPreconditions();
676
677 // Tell user what he is doing
678 logOperationDescription(starteamrootfolder, localrootfolder);
679
680 // Inspect everything in the root folder and then recursively
681 visit(starteamrootfolder, localrootfolder);
682
683 } catch (Exception e) {
684 throw new BuildException(e);
685 } finally {
686 disconnectFromServer();
687 }
688 }
689
690 private void findLabel(View v) throws BuildException {
691 Label[] allLabels = v.getLabels();
692 for (int i = 0; i < allLabels.length; i++) {
693 Label stLabel = allLabels[i];
694 log("checking label " + stLabel.getName(), Project.MSG_DEBUG);
695 if (stLabel != null && !stLabel.isDeleted() && stLabel.getName().equals(this.label)) {
696 if (!stLabel.isRevisionLabel() && !stLabel.isViewLabel()) {
697 throw new BuildException("Unexpected label type.");
698 }
699 log("using label " + stLabel.getName(), Project.MSG_VERBOSE);
700 this.labelInUse = stLabel;
701 return;
702 }
703 }
704 throw new BuildException("Error: label "
705 + this.label
706 + " does not exist in view "
707 + v.getFullName());
708
709 }
710
711 /**
712 * Helper method calls on the StarTeam API to retrieve an ID number
713 * for the specified view, corresponding to this.label.
714 * @param v the <code>View</code> in which to search for <code>this.label</code>
715 * @return the ID number corresponding to <code>this.label</code> or -1 if
716 * no label was provided.
717 * @exception BuildException if <code>this.label</code> does not correspond
718 * to any label in the supplied view
719 */
720 protected int getLabelID(View v) throws BuildException {
721 if (null != this.label) {
722 findLabel(v);
723 return this.labelInUse.getID();
724 }
725 return -1;
726 }
727
728 protected int getIDofLabelInUse() {
729 if (null != this.labelInUse) {
730 return this.labelInUse.getID();
731 }
732 return -1;
733 }
734
735 /**
736 * Derived classes must override this class to define actual processing
737 * to be performed on each folder in the tree defined for the task
738 *
739 * @param rootStarteamFolder
740 * the StarTeam folderto be visited
741 * @param rootLocalFolder
742 * the local mapping of rootStarteamFolder
743 *
744 * @exception BuildException
745 */
746 protected abstract void visit(Folder rootStarteamFolder,
747 java.io.File rootLocalFolder)
748 throws BuildException;
749
750
751
752
753 /**
754 * Derived classes must override this method to define tests for
755 * any preconditons required by the task. This method is called at
756 * the beginning of the execute() method.
757 *
758 * @exception BuildException throw if any fatal error exists in the
759 * parameters supplied. If there is a non-fatal condition, just writing
760 * to the log may be appropriate.
761 * @see <code>execute()</code>
762 */
763 protected abstract void testPreconditions() throws BuildException;
764
765
766 /**
767 * Return the full repository path name of a file. Surprisingly there's
768 * no method in com.starbase.starteam.File to provide this.
769 *
770 * @param remotefile the Star Team file whose path is to be returned
771 *
772 * @return the full repository path name of a file.
773 */
774 public static String getFullRepositoryPath(
775 com.starbase.starteam.File remotefile) {
776 StringBuffer sb = new StringBuffer();
777 sb.append(remotefile.getParentFolderHierarchy())
778 .append(remotefile.getName());
779 return sb.toString();
780 }
781
782 /**
783 * This class implements a map of existing local files to possibly
784 * existing repository files. The map is created by a TreeBasedTask
785 * upon recursing into a directory. Each local item is mapped to an
786 * unattached StarTeam object of the proper type, File->File and
787 * Directory->Folder.
788 *
789 * As the TreeBased does its work, it deletes from the map all items
790 * it has processed.
791 *
792 * When the TreeBased task processes all the items from the repository,
793 * whatever items left in the UnmatchedFileMap are uncontrolled items
794 * and can be processed as appropriate to the task. In the case of
795 * Checkouts, they can be optionally deleted from the local tree. In the
796 * case of Checkins they can optionally be added to the repository.
797 */
798 protected abstract class UnmatchedFileMap extends Hashtable {
799
800 /**
801 * initializes the UnmatchedFileMap with entries from the local folder
802 * These will be mapped to the corresponding StarTeam entry even though
803 * it will not, in fact, exist in the repository. But through it, it
804 * can be added, listed, etc.
805 *
806 * @param localFolder
807 * the local folder from which the mappings will be made.
808 * @param remoteFolder
809 * the corresponding StarTeam folder which will be processed.
810 */
811 UnmatchedFileMap init(java.io.File localFolder, Folder remoteFolder) {
812 if (!localFolder.exists()) {
813 return this;
814 }
815
816 String[] localFiles = localFolder.list();
817
818 for (int i = 0; i < localFiles.length; i++) {
819 String fn = localFiles[i];
820 java.io.File localFile =
821 new java.io.File(localFolder, localFiles[i]).getAbsoluteFile();
822
823 log("adding " + localFile + " to UnmatchedFileMap",
824 Project.MSG_DEBUG);
825
826 if (localFile.isDirectory()) {
827 this.put(localFile, new Folder(remoteFolder, fn, fn));
828 } else {
829 com.starbase.starteam.File remoteFile =
830 new com.starbase.starteam.File(remoteFolder);
831 remoteFile.setName(fn);
832 this.put(localFile, remoteFile);
833 }
834 }
835 return this;
836 }
837
838 /**
839 * remove an item found to be controlled from the map.
840 *
841 * @param localFile the local item found to be controlled.
842 */
843 void removeControlledItem(java.io.File localFile) {
844 if (isActive()) {
845 log("removing processed " + localFile.getAbsoluteFile()
846 + " from UnmatchedFileMap", Project.MSG_DEBUG);
847 this.remove(localFile.getAbsoluteFile());
848 }
849 }
850 /**
851 * override will perform the action appropriate for its task to perform
852 * on items which are on the local tree but not in StarTeam. It is
853 * assumed that this method will not be called until all the items in
854 * the corresponding folder have been processed, and that the internal
855 * map * will contain only uncontrolled items.
856 */
857 abstract void processUncontrolledItems() throws BuildException;
858
859 /**
860 * overrides must define this to declare how this method knows if it
861 * is active. This presents extra clock cycles when the functionality
862 * is not called for.
863 *
864 * @return True if this object is to perform its functionality.
865 */
866 protected abstract boolean isActive();
867
868 }
869
870}
871
872
873
Note: See TracBrowser for help on using the repository browser.