KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > ExecuteOn


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
19 package org.apache.tools.ant.taskdefs;
20
21 import java.io.File JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Vector JavaDoc;
26 import org.apache.tools.ant.BuildException;
27 import org.apache.tools.ant.DirectoryScanner;
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.types.Commandline;
30 import org.apache.tools.ant.types.AbstractFileSet;
31 import org.apache.tools.ant.types.DirSet;
32 import org.apache.tools.ant.types.EnumeratedAttribute;
33 import org.apache.tools.ant.types.FileList;
34 import org.apache.tools.ant.types.FileSet;
35 import org.apache.tools.ant.types.Mapper;
36 import org.apache.tools.ant.types.Resource;
37 import org.apache.tools.ant.types.ResourceCollection;
38 import org.apache.tools.ant.types.resources.FileResource;
39 import org.apache.tools.ant.types.resources.Union;
40 import org.apache.tools.ant.util.FileNameMapper;
41 import org.apache.tools.ant.util.SourceFileScanner;
42
43 /**
44  * Executes a given command, supplying a set of files as arguments.
45  *
46  * @since Ant 1.2
47  *
48  * @ant.task category="control" name="apply"
49  */

50 public class ExecuteOn extends ExecTask {
51
52     // CheckStyle:VisibilityModifier OFF - bc
53

54     // filesets has been protected so we need to keep that even after
55
// switching to resource collections. In fact, they will still
56
// get a different treatment form the other resource collections
57
// even in execute since we have some subtle special features like
58
// switching type to "dir" when we encounter a DirSet that would
59
// be more difficult to achieve otherwise.
60

61     protected Vector JavaDoc filesets = new Vector JavaDoc(); // contains AbstractFileSet
62
// (both DirSet and FileSet)
63
private Union resources = null;
64     private boolean relative = false;
65     private boolean parallel = false;
66     private boolean forwardSlash = false;
67     protected String JavaDoc type = FileDirBoth.FILE;
68     protected Commandline.Marker srcFilePos = null;
69     private boolean skipEmpty = false;
70     protected Commandline.Marker targetFilePos = null;
71     protected Mapper mapperElement = null;
72     protected FileNameMapper mapper = null;
73     protected File JavaDoc destDir = null;
74     private int maxParallel = -1;
75     private boolean addSourceFile = true;
76     private boolean verbose = false;
77     private boolean ignoreMissing = true;
78     private boolean force = false;
79
80     /**
81      * Has <srcfile> been specified before <targetfile>
82      */

83     protected boolean srcIsFirst = true;
84
85     // CheckStyle:VisibilityModifier ON
86
/**
87      * Add a set of files upon which to operate.
88      * @param set the FileSet to add.
89      */

90     public void addFileset(FileSet set) {
91         filesets.addElement(set);
92     }
93
94     /**
95      * Add a set of directories upon which to operate.
96      *
97      * @param set the DirSet to add.
98      *
99      * @since Ant 1.6
100      */

101     public void addDirset(DirSet set) {
102         filesets.addElement(set);
103     }
104
105     /**
106      * Add a list of source files upon which to operate.
107      * @param list the FileList to add.
108      */

109     public void addFilelist(FileList list) {
110         add(list);
111     }
112
113     /**
114      * Add a collection of resources upon which to operate.
115      * @param rc resource collection to add.
116      * @since Ant 1.7
117      */

118     public void add(ResourceCollection rc) {
119         if (resources == null) {
120             resources = new Union();
121         }
122         resources.add(rc);
123     }
124
125     /**
126      * Set whether the filenames should be passed on the command line as
127      * absolute or relative pathnames. Paths are relative to the base
128      * directory of the corresponding fileset for source files or the
129      * dest attribute for target files.
130      * @param relative whether to pass relative pathnames.
131      */

132     public void setRelative(boolean relative) {
133         this.relative = relative;
134     }
135
136
137     /**
138      * Set whether to execute in parallel mode.
139      * If true, run the command only once, appending all files as arguments.
140      * If false, command will be executed once for every file. Defaults to false.
141      * @param parallel whether to run in parallel.
142      */

143     public void setParallel(boolean parallel) {
144         this.parallel = parallel;
145     }
146
147     /**
148      * Set whether the command works only on files, directories or both.
149      * @param type a FileDirBoth EnumeratedAttribute.
150      */

151     public void setType(FileDirBoth type) {
152         this.type = type.getValue();
153     }
154
155     /**
156      * Set whether empty filesets will be skipped. If true and
157      * no source files have been found or are newer than their
158      * corresponding target files, the command will not be run.
159      * @param skip whether to skip empty filesets.
160      */

161     public void setSkipEmptyFilesets(boolean skip) {
162         skipEmpty = skip;
163     }
164
165     /**
166      * Specify the directory where target files are to be placed.
167      * @param destDir the File object representing the destination directory.
168      */

169     public void setDest(File JavaDoc destDir) {
170         this.destDir = destDir;
171     }
172
173     /**
174      * Set whether the source and target file names on Windows and OS/2
175      * must use the forward slash as file separator.
176      * @param forwardSlash whether the forward slash will be forced.
177      */

178     public void setForwardslash(boolean forwardSlash) {
179         this.forwardSlash = forwardSlash;
180     }
181
182     /**
183      * Limit the command line length by passing at maximum this many
184      * sourcefiles at once to the command.
185      *
186      * <p>Set to &lt;= 0 for unlimited - this is the default.</p>
187      *
188      * @param max <code>int</code> maximum number of sourcefiles
189      * passed to the executable.
190      *
191      * @since Ant 1.6
192      */

193     public void setMaxParallel(int max) {
194         maxParallel = max;
195     }
196
197     /**
198      * Set whether to send the source file name on the command line.
199      *
200      * <p>Defaults to <code>true</code>.
201      *
202      * @param b whether to add the source file to the command line.
203      *
204      * @since Ant 1.6
205      */

206     public void setAddsourcefile(boolean b) {
207         addSourceFile = b;
208     }
209
210     /**
211      * Set whether to operate in verbose mode.
212      * If true, a verbose summary will be printed after execution.
213      * @param b whether to operate in verbose mode.
214      *
215      * @since Ant 1.6
216      */

217     public void setVerbose(boolean b) {
218         verbose = b;
219     }
220
221     /**
222      * Set whether to ignore nonexistent files from filelists.
223      * @param b whether to ignore missing files.
224      *
225      * @since Ant 1.6.2
226      */

227     public void setIgnoremissing(boolean b) {
228         ignoreMissing = b;
229     }
230
231     /**
232      * Set whether to bypass timestamp comparisons for target files.
233      * @param b whether to bypass timestamp comparisons.
234      *
235      * @since Ant 1.6.3
236      */

237     public void setForce(boolean b) {
238         force = b;
239     }
240
241     /**
242      * Create a placeholder indicating where on the command line
243      * the name of the source file should be inserted.
244      * @return <code>Commandline.Marker</code>.
245      */

246     public Commandline.Marker createSrcfile() {
247         if (srcFilePos != null) {
248             throw new BuildException(getTaskType() + " doesn\'t support multiple "
249                                      + "srcfile elements.", getLocation());
250         }
251         srcFilePos = cmdl.createMarker();
252         return srcFilePos;
253     }
254
255     /**
256      * Create a placeholder indicating where on the command line
257      * the name of the target file should be inserted.
258      * @return <code>Commandline.Marker</code>.
259      */

260     public Commandline.Marker createTargetfile() {
261         if (targetFilePos != null) {
262             throw new BuildException(getTaskType() + " doesn\'t support multiple "
263                                      + "targetfile elements.", getLocation());
264         }
265         targetFilePos = cmdl.createMarker();
266         srcIsFirst = (srcFilePos != null);
267         return targetFilePos;
268     }
269
270     /**
271      * Create a nested Mapper element to use for mapping
272      * source files to target files.
273      * @return <code>Mapper</code>.
274      * @throws BuildException if more than one mapper is defined.
275      */

276     public Mapper createMapper() throws BuildException {
277         if (mapperElement != null) {
278             throw new BuildException("Cannot define more than one mapper",
279                                      getLocation());
280         }
281         mapperElement = new Mapper(getProject());
282         return mapperElement;
283     }
284
285     /**
286      * Add a nested FileNameMapper.
287      * @param fileNameMapper the mapper to add.
288      * @since Ant 1.6.3
289      */

290     public void add(FileNameMapper fileNameMapper) {
291         createMapper().add(fileNameMapper);
292     }
293
294     /**
295      * Check the configuration of this ExecuteOn instance.
296      */

297     protected void checkConfiguration() {
298 // * @TODO using taskName here is brittle, as a user could override it.
299
// * this should probably be modified to use the classname instead.
300
if ("execon".equals(getTaskName())) {
301             log("!! execon is deprecated. Use apply instead. !!");
302         }
303         super.checkConfiguration();
304         if (filesets.size() == 0 && resources == null) {
305             throw new BuildException("no resources specified",
306                                      getLocation());
307         }
308         if (targetFilePos != null && mapperElement == null) {
309             throw new BuildException("targetfile specified without mapper",
310                                      getLocation());
311         }
312         if (destDir != null && mapperElement == null) {
313             throw new BuildException("dest specified without mapper",
314                                      getLocation());
315         }
316         if (mapperElement != null) {
317             mapper = mapperElement.getImplementation();
318         }
319     }
320
321     /**
322      * Create the ExecuteStreamHandler instance that will be used
323      * during execution.
324      * @return <code>ExecuteStreamHandler</code>.
325      * @throws BuildException on error.
326      */

327     protected ExecuteStreamHandler createHandler() throws BuildException {
328         //if we have a RedirectorElement, return a decoy
329
return (redirectorElement == null)
330             ? super.createHandler() : new PumpStreamHandler();
331     }
332
333     /**
334      * Set up the I/O Redirector.
335      */

336     protected void setupRedirector() {
337         super.setupRedirector();
338         redirector.setAppendProperties(true);
339     }
340
341     /**
342      * Run the specified Execute object.
343      * @param exe the Execute instance representing the external process.
344      * @throws BuildException on error
345      */

346     protected void runExec(Execute exe) throws BuildException {
347         int totalFiles = 0;
348         int totalDirs = 0;
349         boolean haveExecuted = false;
350         try {
351             Vector JavaDoc fileNames = new Vector JavaDoc();
352             Vector JavaDoc baseDirs = new Vector JavaDoc();
353             for (int i = 0; i < filesets.size(); i++) {
354                 String JavaDoc currentType = type;
355                 AbstractFileSet fs = (AbstractFileSet) filesets.elementAt(i);
356                 if (fs instanceof DirSet) {
357                     if (!FileDirBoth.DIR.equals(type)) {
358                         log("Found a nested dirset but type is " + type + ". "
359                             + "Temporarily switching to type=\"dir\" on the"
360                             + " assumption that you really did mean"
361                             + " <dirset> not <fileset>.", Project.MSG_DEBUG);
362                         currentType = FileDirBoth.DIR;
363                     }
364                 }
365                 File JavaDoc base = fs.getDir(getProject());
366
367                 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
368
369                 if (!FileDirBoth.DIR.equals(currentType)) {
370                     String JavaDoc[] s = getFiles(base, ds);
371                     for (int j = 0; j < s.length; j++) {
372                         totalFiles++;
373                         fileNames.addElement(s[j]);
374                         baseDirs.addElement(base);
375                     }
376                 }
377                 if (!FileDirBoth.FILE.equals(currentType)) {
378                     String JavaDoc[] s = getDirs(base, ds);
379                     for (int j = 0; j < s.length; j++) {
380                         totalDirs++;
381                         fileNames.addElement(s[j]);
382                         baseDirs.addElement(base);
383                     }
384                 }
385                 if (fileNames.size() == 0 && skipEmpty) {
386                     int includedCount
387                         = ((!FileDirBoth.DIR.equals(currentType))
388                         ? ds.getIncludedFilesCount() : 0)
389                         + ((!FileDirBoth.FILE.equals(currentType))
390                         ? ds.getIncludedDirsCount() : 0);
391
392                     log("Skipping fileset for directory " + base + ". It is "
393                         + ((includedCount > 0) ? "up to date." : "empty."),
394                         Project.MSG_INFO);
395                     continue;
396                 }
397                 if (!parallel) {
398                     String JavaDoc[] s = new String JavaDoc[fileNames.size()];
399                     fileNames.copyInto(s);
400                     for (int j = 0; j < s.length; j++) {
401                         String JavaDoc[] command = getCommandline(s[j], base);
402                         log(Commandline.describeCommand(command),
403                             Project.MSG_VERBOSE);
404                         exe.setCommandline(command);
405
406                         if (redirectorElement != null) {
407                             setupRedirector();
408                             redirectorElement.configure(redirector, s[j]);
409                         }
410                         if (redirectorElement != null || haveExecuted) {
411                             // need to reset the stream handler to restart
412
// reading of pipes;
413
// go ahead and do it always w/ nested redirectors
414
exe.setStreamHandler(redirector.createHandler());
415                         }
416                         runExecute(exe);
417                         haveExecuted = true;
418                     }
419                     fileNames.removeAllElements();
420                     baseDirs.removeAllElements();
421                 }
422             }
423
424             if (resources != null) {
425                 Iterator JavaDoc iter = resources.iterator();
426                 while (iter.hasNext()) {
427                     Resource res = (Resource) iter.next();
428
429                     if (!res.isExists() && ignoreMissing) {
430                         continue;
431                     }
432
433                     File JavaDoc base = null;
434                     String JavaDoc name = res.getName();
435                     if (res instanceof FileResource) {
436                         FileResource fr = (FileResource) res;
437                         base = fr.getBaseDir();
438                         if (base == null) {
439                             name = fr.getFile().getAbsolutePath();
440                         }
441                     }
442
443                     if (restrict(new String JavaDoc[] {name}, base).length == 0) {
444                         continue;
445                     }
446
447                     if ((!res.isDirectory() || !res.isExists())
448                         && !FileDirBoth.DIR.equals(type)) {
449                         totalFiles++;
450                     } else if (res.isDirectory()
451                                && !FileDirBoth.FILE.equals(type)) {
452                         totalDirs++;
453                     } else {
454                         continue;
455                     }
456
457                     baseDirs.add(base);
458                     fileNames.add(name);
459
460                     if (!parallel) {
461                         String JavaDoc[] command = getCommandline(name, base);
462                         log(Commandline.describeCommand(command),
463                             Project.MSG_VERBOSE);
464                         exe.setCommandline(command);
465
466                         if (redirectorElement != null) {
467                             setupRedirector();
468                             redirectorElement.configure(redirector, name);
469                         }
470                         if (redirectorElement != null || haveExecuted) {
471                             // need to reset the stream handler to restart
472
// reading of pipes;
473
// go ahead and do it always w/ nested redirectors
474
exe.setStreamHandler(redirector.createHandler());
475                         }
476                         runExecute(exe);
477                         haveExecuted = true;
478                         fileNames.removeAllElements();
479                         baseDirs.removeAllElements();
480                     }
481                 }
482             }
483             if (parallel && (fileNames.size() > 0 || !skipEmpty)) {
484                 runParallel(exe, fileNames, baseDirs);
485                 haveExecuted = true;
486             }
487             if (haveExecuted) {
488                 log("Applied " + cmdl.getExecutable() + " to "
489                     + totalFiles + " file"
490                     + (totalFiles != 1 ? "s" : "") + " and "
491                     + totalDirs + " director"
492                     + (totalDirs != 1 ? "ies" : "y") + ".",
493                     verbose ? Project.MSG_INFO : Project.MSG_VERBOSE);
494             }
495         } catch (IOException JavaDoc e) {
496             throw new BuildException("Execute failed: " + e, e, getLocation());
497         } finally {
498             // close the output file if required
499
logFlush();
500             redirector.setAppendProperties(false);
501             redirector.setProperties();
502         }
503     }
504
505     /**
506      * Construct the command line for parallel execution.
507      *
508      * @param srcFiles The filenames to add to the commandline.
509      * @param baseDirs filenames are relative to this dir.
510      * @return the command line in the form of a String[].
511      */

512     protected String JavaDoc[] getCommandline(String JavaDoc[] srcFiles, File JavaDoc[] baseDirs) {
513         final char fileSeparator = File.separatorChar;
514         Vector JavaDoc targets = new Vector JavaDoc();
515         if (targetFilePos != null) {
516             Hashtable JavaDoc addedFiles = new Hashtable JavaDoc();
517             for (int i = 0; i < srcFiles.length; i++) {
518                 String JavaDoc[] subTargets = mapper.mapFileName(srcFiles[i]);
519                 if (subTargets != null) {
520                     for (int j = 0; j < subTargets.length; j++) {
521                         String JavaDoc name = null;
522                         if (!relative) {
523                             name = (new File JavaDoc(destDir, subTargets[j])).getAbsolutePath();
524                         } else {
525                             name = subTargets[j];
526                         }
527                         if (forwardSlash && fileSeparator != '/') {
528                             name = name.replace(fileSeparator, '/');
529                         }
530                         if (!addedFiles.contains(name)) {
531                             targets.addElement(name);
532                             addedFiles.put(name, name);
533                         }
534                     }
535                 }
536             }
537         }
538         String JavaDoc[] targetFiles = new String JavaDoc[targets.size()];
539         targets.copyInto(targetFiles);
540
541         if (!addSourceFile) {
542             srcFiles = new String JavaDoc[0];
543         }
544         String JavaDoc[] orig = cmdl.getCommandline();
545         String JavaDoc[] result
546             = new String JavaDoc[orig.length + srcFiles.length + targetFiles.length];
547
548         int srcIndex = orig.length;
549         if (srcFilePos != null) {
550             srcIndex = srcFilePos.getPosition();
551         }
552         if (targetFilePos != null) {
553             int targetIndex = targetFilePos.getPosition();
554
555             if (srcIndex < targetIndex
556                 || (srcIndex == targetIndex && srcIsFirst)) {
557
558                 // 0 --> srcIndex
559
System.arraycopy(orig, 0, result, 0, srcIndex);
560
561                 // srcIndex --> targetIndex
562
System.arraycopy(orig, srcIndex, result,
563                                  srcIndex + srcFiles.length,
564                                  targetIndex - srcIndex);
565
566                 // targets are already absolute file names
567
System.arraycopy(targetFiles, 0, result,
568                                  targetIndex + srcFiles.length,
569                                  targetFiles.length);
570
571                 // targetIndex --> end
572
System.arraycopy(orig, targetIndex, result,
573                     targetIndex + srcFiles.length + targetFiles.length,
574                     orig.length - targetIndex);
575             } else {
576                 // 0 --> targetIndex
577
System.arraycopy(orig, 0, result, 0, targetIndex);
578
579                 // targets are already absolute file names
580
System.arraycopy(targetFiles, 0, result,
581                                  targetIndex,
582                                  targetFiles.length);
583
584                 // targetIndex --> srcIndex
585
System.arraycopy(orig, targetIndex, result,
586                                  targetIndex + targetFiles.length,
587                                  srcIndex - targetIndex);
588
589                 // srcIndex --> end
590
System.arraycopy(orig, srcIndex, result,
591                     srcIndex + srcFiles.length + targetFiles.length,
592                     orig.length - srcIndex);
593                 srcIndex += targetFiles.length;
594             }
595
596         } else { // no targetFilePos
597

598             // 0 --> srcIndex
599
System.arraycopy(orig, 0, result, 0, srcIndex);
600             // srcIndex --> end
601
System.arraycopy(orig, srcIndex, result,
602                              srcIndex + srcFiles.length,
603                              orig.length - srcIndex);
604         }
605         // fill in source file names
606
for (int i = 0; i < srcFiles.length; i++) {
607             if (!relative) {
608                 result[srcIndex + i] =
609                     (new File JavaDoc(baseDirs[i], srcFiles[i])).getAbsolutePath();
610             } else {
611                 result[srcIndex + i] = srcFiles[i];
612             }
613             if (forwardSlash && fileSeparator != '/') {
614                 result[srcIndex + i] =
615                     result[srcIndex + i].replace(fileSeparator, '/');
616             }
617         }
618         return result;
619     }
620
621     /**
622      * Construct the command line for serial execution.
623      *
624      * @param srcFile The filename to add to the commandline.
625      * @param baseDir filename is relative to this dir.
626      * @return the command line in the form of a String[].
627      */

628     protected String JavaDoc[] getCommandline(String JavaDoc srcFile, File JavaDoc baseDir) {
629         return getCommandline(new String JavaDoc[] {srcFile}, new File JavaDoc[] {baseDir});
630     }
631
632     /**
633      * Return the list of files from this DirectoryScanner that should
634      * be included on the command line.
635      * @param baseDir the File base directory.
636      * @param ds the DirectoryScanner to use for file scanning.
637      * @return a String[] containing the filenames.
638      */

639     protected String JavaDoc[] getFiles(File JavaDoc baseDir, DirectoryScanner ds) {
640         return restrict(ds.getIncludedFiles(), baseDir);
641     }
642
643     /**
644      * Return the list of Directories from this DirectoryScanner that
645      * should be included on the command line.
646      * @param baseDir the File base directory.
647      * @param ds the DirectoryScanner to use for file scanning.
648      * @return a String[] containing the directory names.
649      */

650     protected String JavaDoc[] getDirs(File JavaDoc baseDir, DirectoryScanner ds) {
651         return restrict(ds.getIncludedDirectories(), baseDir);
652     }
653
654     /**
655      * Return the list of files or directories from this FileList that
656      * should be included on the command line.
657      * @param list the FileList to check.
658      * @return a String[] containing the directory names.
659      *
660      * @since Ant 1.6.2
661      */

662     protected String JavaDoc[] getFilesAndDirs(FileList list) {
663         return restrict(list.getFiles(getProject()), list.getDir(getProject()));
664     }
665
666     private String JavaDoc[] restrict(String JavaDoc[] s, File JavaDoc baseDir) {
667         return (mapper == null || force) ? s
668             : new SourceFileScanner(this).restrict(s, baseDir, destDir, mapper);
669     }
670
671     /**
672      * Run the command in "parallel" mode, making sure that at most
673      * maxParallel sourcefiles get passed on the command line.
674      * @param exe the Executable to use.
675      * @param fileNames the Vector of filenames.
676      * @param baseDirs the Vector of base directories corresponding to fileNames.
677      * @throws IOException on I/O errors.
678      * @throws BuildException on other errors.
679      * @since Ant 1.6
680      */

681     protected void runParallel(Execute exe, Vector JavaDoc fileNames,
682                                Vector JavaDoc baseDirs)
683         throws IOException JavaDoc, BuildException {
684         String JavaDoc[] s = new String JavaDoc[fileNames.size()];
685         fileNames.copyInto(s);
686         File JavaDoc[] b = new File JavaDoc[baseDirs.size()];
687         baseDirs.copyInto(b);
688
689         if (maxParallel <= 0
690             || s.length == 0 /* this is skipEmpty == false */) {
691             String JavaDoc[] command = getCommandline(s, b);
692             log(Commandline.describeCommand(command), Project.MSG_VERBOSE);
693             exe.setCommandline(command);
694             runExecute(exe);
695         } else {
696             int stillToDo = fileNames.size();
697             int currentOffset = 0;
698             while (stillToDo > 0) {
699                 int currentAmount = Math.min(stillToDo, maxParallel);
700                 String JavaDoc[] cs = new String JavaDoc[currentAmount];
701                 System.arraycopy(s, currentOffset, cs, 0, currentAmount);
702                 File JavaDoc[] cb = new File JavaDoc[currentAmount];
703                 System.arraycopy(b, currentOffset, cb, 0, currentAmount);
704                 String JavaDoc[] command = getCommandline(cs, cb);
705                 log(Commandline.describeCommand(command), Project.MSG_VERBOSE);
706                 exe.setCommandline(command);
707                 if (redirectorElement != null) {
708                     setupRedirector();
709                     redirectorElement.configure(redirector, null);
710                 }
711                 if (redirectorElement != null || currentOffset > 0) {
712                     // need to reset the stream handler to restart
713
// reading of pipes;
714
// go ahead and do it always w/ nested redirectors
715
exe.setStreamHandler(redirector.createHandler());
716                 }
717                 runExecute(exe);
718
719                 stillToDo -= currentAmount;
720                 currentOffset += currentAmount;
721             }
722         }
723     }
724
725     /**
726      * Enumerated attribute with the values "file", "dir" and "both"
727      * for the type attribute.
728      */

729     public static class FileDirBoth extends EnumeratedAttribute {
730         /** File value */
731         public static final String JavaDoc FILE = "file";
732         /** Dir value */
733         public static final String JavaDoc DIR = "dir";
734         /**
735          * @see EnumeratedAttribute#getValues
736          */

737         /** {@inheritDoc}. */
738        public String JavaDoc[] getValues() {
739             return new String JavaDoc[] {FILE, DIR, "both"};
740         }
741     }
742 }
743
Popular Tags