KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > types > RedirectorElement


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.types;
19
20 import java.io.File JavaDoc;
21 import java.util.Stack JavaDoc;
22 import java.util.Vector JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.ArrayList JavaDoc;
25
26 import org.apache.tools.ant.Project;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.taskdefs.Redirector;
29
30 /**
31  * Element representation of a <code>Redirector</code>.
32  * @since Ant 1.6.2
33  */

34 public class RedirectorElement extends DataType {
35
36     /**
37      * Whether the input mapper was set via <code>setOutput</code>.
38      */

39     private boolean usingInput = false;
40
41     /**
42      * Whether the output mapper was set via <code>setOutput</code>.
43      */

44     private boolean usingOutput = false;
45
46     /**
47      * Whether the error mapper was set via <code>setError</code>.
48      */

49     private boolean usingError = false;
50
51     /**
52      * Indicates if standard error should be logged to Ant's log system
53      * rather than the output. This has no effect if standard error is
54      * redirected to a file or property.
55      */

56     private Boolean JavaDoc logError;
57
58     /** The name of the property into which output is to be stored */
59     private String JavaDoc outputProperty;
60
61     /** The name of the property into which error output is to be stored */
62     private String JavaDoc errorProperty;
63
64     /** String from which input is taken */
65     private String JavaDoc inputString;
66
67     /** Flag which indicates if error and output files are to be appended. */
68     private Boolean JavaDoc append;
69
70     /** Flag which indicates that output should be always sent to the log */
71     private Boolean JavaDoc alwaysLog;
72
73     /** Flag which indicates whether files should be created even if empty. */
74     private Boolean JavaDoc createEmptyFiles;
75
76     /** Input file mapper. */
77     private Mapper inputMapper;
78
79     /** Output file mapper. */
80     private Mapper outputMapper;
81
82     /** Error file mapper. */
83     private Mapper errorMapper;
84
85     /** input filter chains. */
86     private Vector JavaDoc inputFilterChains = new Vector JavaDoc();
87
88     /** output filter chains. */
89     private Vector JavaDoc outputFilterChains = new Vector JavaDoc();
90
91     /** error filter chains. */
92     private Vector JavaDoc errorFilterChains = new Vector JavaDoc();
93
94     /** The output encoding */
95     private String JavaDoc outputEncoding;
96
97     /** The error encoding */
98     private String JavaDoc errorEncoding;
99
100     /** The input encoding */
101     private String JavaDoc inputEncoding;
102
103     /** whether to log the inputstring */
104     private Boolean JavaDoc logInputString;
105
106     /**
107      * Add the input file mapper.
108      * @param inputMapper <code>Mapper</code>.
109      */

110     public void addConfiguredInputMapper(Mapper inputMapper) {
111         if (isReference()) {
112             throw noChildrenAllowed();
113         }
114         if (this.inputMapper != null) {
115             if (usingInput) {
116                 throw new BuildException("attribute \"input\""
117                     + " cannot coexist with a nested <inputmapper>");
118             } else {
119                 throw new BuildException("Cannot have > 1 <inputmapper>");
120             }
121         }
122         this.inputMapper = inputMapper;
123     }
124
125     /**
126      * Add the output file mapper.
127      * @param outputMapper <code>Mapper</code>.
128      */

129     public void addConfiguredOutputMapper(Mapper outputMapper) {
130         if (isReference()) {
131             throw noChildrenAllowed();
132         }
133         if (this.outputMapper != null) {
134             if (usingOutput) {
135                 throw new BuildException("attribute \"output\""
136                     + " cannot coexist with a nested <outputmapper>");
137             } else {
138                 throw new BuildException("Cannot have > 1 <outputmapper>");
139             }
140         }
141         this.outputMapper = outputMapper;
142     }
143
144     /**
145      * Add the error file mapper.
146      * @param errorMapper <code>Mapper</code>.
147      */

148     public void addConfiguredErrorMapper(Mapper errorMapper) {
149         if (isReference()) {
150             throw noChildrenAllowed();
151         }
152         if (this.errorMapper != null) {
153             if (usingError) {
154                 throw new BuildException("attribute \"error\""
155                     + " cannot coexist with a nested <errormapper>");
156             } else {
157                 throw new BuildException("Cannot have > 1 <errormapper>");
158             }
159         }
160         this.errorMapper = errorMapper;
161     }
162
163     /**
164      * Make this instance in effect a reference to another instance.
165      *
166      * <p>You must not set another attribute or nest elements inside
167      * this element if you make it a reference.</p>
168      * @param r the reference to use.
169      * @throws BuildException on error.
170      */

171     public void setRefid(Reference r) throws BuildException {
172         if (usingInput
173             || usingOutput
174             || usingError
175             || inputString != null
176             || logError != null
177             || append != null
178             || createEmptyFiles != null
179             || inputEncoding != null
180             || outputEncoding != null
181             || errorEncoding != null
182             || outputProperty != null
183             || errorProperty != null
184             || logInputString != null) {
185             throw tooManyAttributes();
186         }
187         super.setRefid(r);
188     }
189
190     /**
191      * Set the input to use for the task.
192      * @param input the file from which input is read.
193      */

194     public void setInput(File JavaDoc input) {
195         if (isReference()) {
196             throw tooManyAttributes();
197         }
198         if (inputString != null) {
199             throw new BuildException("The \"input\" and \"inputstring\" "
200                 + "attributes cannot both be specified");
201         }
202         usingInput = true;
203         inputMapper = createMergeMapper(input);
204     }
205
206     /**
207      * Set the string to use as input
208      * @param inputString the string which is used as the input source
209      */

210     public void setInputString(String JavaDoc inputString) {
211         if (isReference()) {
212             throw tooManyAttributes();
213         }
214         if (usingInput) {
215             throw new BuildException("The \"input\" and \"inputstring\" "
216                 + "attributes cannot both be specified");
217         }
218         this.inputString = inputString;
219     }
220
221     /**
222      * Set whether to include the value of the input string in log messages.
223      * Defaults to true.
224      * @param logInputString true or false.
225      * @since Ant 1.7
226      */

227     public void setLogInputString(boolean logInputString) {
228         if (isReference()) {
229             throw tooManyAttributes();
230         }
231         this.logInputString = logInputString ? Boolean.TRUE : Boolean.FALSE;
232     }
233
234     /**
235      * File the output of the process is redirected to. If error is not
236      * redirected, it too will appear in the output.
237      *
238      * @param out the file to which output stream is written.
239      */

240     public void setOutput(File JavaDoc out) {
241         if (isReference()) {
242             throw tooManyAttributes();
243         }
244         if (out == null) {
245             throw new IllegalArgumentException JavaDoc("output file specified as null");
246         }
247         usingOutput = true;
248         outputMapper = createMergeMapper(out);
249     }
250
251     /**
252      * Set the output encoding.
253      * @param outputEncoding <code>String</code>.
254      */

255     public void setOutputEncoding(String JavaDoc outputEncoding) {
256         if (isReference()) {
257             throw tooManyAttributes();
258         }
259         this.outputEncoding = outputEncoding;
260     }
261
262     /**
263      * Set the error encoding.
264      *
265      * @param errorEncoding <code>String</code>.
266      */

267     public void setErrorEncoding(String JavaDoc errorEncoding) {
268         if (isReference()) {
269             throw tooManyAttributes();
270         }
271         this.errorEncoding = errorEncoding;
272     }
273
274     /**
275      * Set the input encoding.
276      * @param inputEncoding <code>String</code>.
277      */

278     public void setInputEncoding(String JavaDoc inputEncoding) {
279         if (isReference()) {
280             throw tooManyAttributes();
281         }
282         this.inputEncoding = inputEncoding;
283     }
284
285     /**
286      * Controls whether error output of exec is logged. This is only useful
287      * when output is being redirected and error output is desired in the
288      * Ant log.
289      * @param logError if true the standard error is sent to the Ant log system
290      * and not sent to output.
291      */

292     public void setLogError(boolean logError) {
293         if (isReference()) {
294             throw tooManyAttributes();
295         }
296         this.logError = ((logError) ? Boolean.TRUE : Boolean.FALSE);
297     }
298
299     /**
300      * Set the file to which standard error is to be redirected.
301      * @param error the file to which error is to be written.
302      */

303     public void setError(File JavaDoc error) {
304         if (isReference()) {
305             throw tooManyAttributes();
306         }
307         if (error == null) {
308             throw new IllegalArgumentException JavaDoc("error file specified as null");
309         }
310         usingError = true;
311         errorMapper = createMergeMapper(error);
312     }
313
314     /**
315      * Property name whose value should be set to the output of
316      * the process.
317      * @param outputProperty the name of the property to be set with the
318      * task's output.
319      */

320     public void setOutputProperty(String JavaDoc outputProperty) {
321         if (isReference()) {
322             throw tooManyAttributes();
323         }
324         this.outputProperty = outputProperty;
325     }
326
327     /**
328      * Whether output should be appended to or overwrite an existing file.
329      * Defaults to false.
330      * @param append if true output and error streams are appended to their
331      * respective files, if specified.
332      */

333     public void setAppend(boolean append) {
334         if (isReference()) {
335             throw tooManyAttributes();
336         }
337         this.append = ((append) ? Boolean.TRUE : Boolean.FALSE);
338     }
339
340     /**
341      * If true, (error and non-error) output will be "teed", redirected
342      * as specified while being sent to Ant's logging mechanism as if no
343      * redirection had taken place. Defaults to false.
344      * @param alwaysLog <code>boolean</code>
345      * @since Ant 1.6.3
346      */

347     public void setAlwaysLog(boolean alwaysLog) {
348         if (isReference()) {
349             throw tooManyAttributes();
350         }
351         this.alwaysLog = ((alwaysLog) ? Boolean.TRUE : Boolean.FALSE);
352     }
353
354     /**
355      * Whether output and error files should be created even when empty.
356      * Defaults to true.
357      * @param createEmptyFiles <code>boolean</code>.
358      */

359     public void setCreateEmptyFiles(boolean createEmptyFiles) {
360         if (isReference()) {
361             throw tooManyAttributes();
362         }
363         this.createEmptyFiles = ((createEmptyFiles)
364             ? Boolean.TRUE : Boolean.FALSE);
365     }
366
367     /**
368      * Property name whose value should be set to the error of
369      * the process.
370      * @param errorProperty the name of the property to be set
371      * with the error output.
372      */

373     public void setErrorProperty(String JavaDoc errorProperty) {
374         if (isReference()) {
375             throw tooManyAttributes();
376         }
377         this.errorProperty = errorProperty;
378     }
379
380     /**
381      * Create a nested input <code>FilterChain</code>.
382      * @return <code>FilterChain</code>.
383      */

384     public FilterChain createInputFilterChain() {
385         if (isReference()) {
386             throw noChildrenAllowed();
387         }
388         FilterChain result = new FilterChain();
389         result.setProject(getProject());
390         inputFilterChains.add(result);
391         return result;
392     }
393
394     /**
395      * Create a nested output <code>FilterChain</code>.
396      * @return <code>FilterChain</code>.
397      */

398     public FilterChain createOutputFilterChain() {
399         if (isReference()) {
400             throw noChildrenAllowed();
401         }
402         FilterChain result = new FilterChain();
403         result.setProject(getProject());
404         outputFilterChains.add(result);
405         return result;
406     }
407
408     /**
409      * Create a nested error <code>FilterChain</code>.
410      * @return <code>FilterChain</code>.
411      */

412     public FilterChain createErrorFilterChain() {
413         if (isReference()) {
414             throw noChildrenAllowed();
415         }
416         FilterChain result = new FilterChain();
417         result.setProject(getProject());
418         errorFilterChains.add(result);
419         return result;
420     }
421
422     /**
423      * Configure the specified <code>Redirector</code>.
424      * @param redirector <code>Redirector</code>.
425      */

426     public void configure(Redirector redirector) {
427         configure(redirector, null);
428     }
429
430     /**
431      * Configure the specified <code>Redirector</code>
432      * for the specified sourcefile.
433      * @param redirector <code>Redirector</code>.
434      * @param sourcefile <code>String</code>.
435      */

436     public void configure(Redirector redirector, String JavaDoc sourcefile) {
437         if (isReference()) {
438             getRef().configure(redirector, sourcefile);
439             return;
440         }
441         if (alwaysLog != null) {
442             redirector.setAlwaysLog(alwaysLog.booleanValue());
443         }
444         if (logError != null) {
445             redirector.setLogError(logError.booleanValue());
446         }
447         if (append != null) {
448             redirector.setAppend(append.booleanValue());
449         }
450         if (createEmptyFiles != null) {
451             redirector.setCreateEmptyFiles(createEmptyFiles.booleanValue());
452         }
453         if (outputProperty != null) {
454             redirector.setOutputProperty(outputProperty);
455         }
456         if (errorProperty != null) {
457             redirector.setErrorProperty(errorProperty);
458         }
459         if (inputString != null) {
460             redirector.setInputString(inputString);
461         }
462         if (logInputString != null) {
463             redirector.setLogInputString(logInputString.booleanValue());
464         }
465         if (inputMapper != null) {
466             String JavaDoc[] inputTargets = null;
467             try {
468                 inputTargets =
469                     inputMapper.getImplementation().mapFileName(sourcefile);
470             } catch (NullPointerException JavaDoc enPeaEx) {
471                 if (sourcefile != null) {
472                     throw enPeaEx;
473                 }
474             }
475             if (inputTargets != null && inputTargets.length > 0) {
476                 redirector.setInput(toFileArray(inputTargets));
477             }
478         }
479         if (outputMapper != null) {
480             String JavaDoc[] outputTargets = null;
481             try {
482                 outputTargets =
483                     outputMapper.getImplementation().mapFileName(sourcefile);
484             } catch (NullPointerException JavaDoc enPeaEx) {
485                 if (sourcefile != null) {
486                     throw enPeaEx;
487                 }
488             }
489             if (outputTargets != null && outputTargets.length > 0) {
490                 redirector.setOutput(toFileArray(outputTargets));
491             }
492         }
493         if (errorMapper != null) {
494             String JavaDoc[] errorTargets = null;
495             try {
496                 errorTargets =
497                     errorMapper.getImplementation().mapFileName(sourcefile);
498             } catch (NullPointerException JavaDoc enPeaEx) {
499                 if (sourcefile != null) {
500                     throw enPeaEx;
501                 }
502             }
503             if (errorTargets != null && errorTargets.length > 0) {
504                 redirector.setError(toFileArray(errorTargets));
505             }
506         }
507         if (inputFilterChains.size() > 0) {
508             redirector.setInputFilterChains(inputFilterChains);
509         }
510         if (outputFilterChains.size() > 0) {
511             redirector.setOutputFilterChains(outputFilterChains);
512         }
513         if (errorFilterChains.size() > 0) {
514             redirector.setErrorFilterChains(errorFilterChains);
515         }
516         if (inputEncoding != null) {
517             redirector.setInputEncoding(inputEncoding);
518         }
519         if (outputEncoding != null) {
520             redirector.setOutputEncoding(outputEncoding);
521         }
522         if (errorEncoding != null) {
523             redirector.setErrorEncoding(errorEncoding);
524         }
525     }
526
527     /**
528      * Create a merge mapper pointing to the specified destination file.
529      * @param destfile <code>File</code>
530      * @return <code>Mapper</code>.
531      */

532     protected Mapper createMergeMapper(File JavaDoc destfile) {
533         Mapper result = new Mapper(getProject());
534         result.setClassname(
535             org.apache.tools.ant.util.MergingMapper.class.getName());
536         result.setTo(destfile.getAbsolutePath());
537         return result;
538     }
539
540     /**
541      * Return a <code>File[]</code> from the specified set of filenames.
542      * @param name <code>String[]</code>
543      * @return <code>File[]</code>.
544      */

545     protected File JavaDoc[] toFileArray(String JavaDoc[] name) {
546         if (name == null) {
547             return null;
548         }
549         //remove any null elements
550
ArrayList JavaDoc list = new ArrayList JavaDoc(name.length);
551         for (int i = 0; i < name.length; i++) {
552             if (name[i] != null) {
553                 list.add(getProject().resolveFile(name[i]));
554             }
555         }
556         return (File JavaDoc[]) (list.toArray(new File JavaDoc[list.size()]));
557     }
558
559     /**
560      * Overrides the version of DataType to recurse on all DataType
561      * child elements that may have been added.
562      * @param stk the stack of data types to use (recursively).
563      * @param p the project to use to dereference the references.
564      * @throws BuildException on error.
565      */

566     protected void dieOnCircularReference(Stack JavaDoc stk, Project p)
567         throws BuildException {
568         if (isChecked()) {
569             return;
570         }
571         if (isReference()) {
572             super.dieOnCircularReference(stk, p);
573         } else {
574             Mapper[] m = new Mapper[] {inputMapper, outputMapper, errorMapper};
575             for (int i = 0; i < m.length; i++) {
576                 if (m[i] != null) {
577                     stk.push(m[i]);
578                     m[i].dieOnCircularReference(stk, p);
579                     stk.pop();
580                 }
581             }
582             Vector JavaDoc[] v = new Vector JavaDoc[]
583                 {inputFilterChains, outputFilterChains, errorFilterChains};
584             for (int i = 0; i < v.length; i++) {
585                 if (v[i] != null) {
586                     for (Iterator JavaDoc fci = v[i].iterator(); fci.hasNext();) {
587                         FilterChain fc = (FilterChain) fci.next();
588                         stk.push(fc);
589                         fc.dieOnCircularReference(stk, p);
590                         stk.pop();
591                     }
592                 }
593             }
594             setChecked(true);
595         }
596     }
597
598     /**
599      * Perform the check for circular references, returning the
600      * referenced RedirectorElement.
601      * @return the referenced RedirectorElement.
602      */

603     private RedirectorElement getRef() {
604         return (RedirectorElement) getCheckedRef();
605     }
606
607 }
608
Popular Tags