KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > inversoft > savant > ant > taskdefs > ForeachTask


1 /*
2  * Copyright (c) 2003-2004, Inversoft, All Rights Reserved
3  *
4  * This software is distribuable under the GNU Lesser General Public License.
5  * For more information visit gnu.org.
6  */

7 package com.inversoft.savant.ant.taskdefs;
8
9
10 import java.io.File JavaDoc;
11 import java.util.ArrayList JavaDoc;
12 import java.util.Arrays JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.StringTokenizer JavaDoc;
16
17 import org.apache.tools.ant.BuildException;
18 import org.apache.tools.ant.Project;
19 import org.apache.tools.ant.Task;
20 import org.apache.tools.ant.taskdefs.Ant;
21 import org.apache.tools.ant.taskdefs.Property;
22 import org.apache.tools.ant.types.FileSet;
23 import org.apache.tools.ant.types.Mapper;
24 import org.apache.tools.ant.util.FileNameMapper;
25 import org.apache.tools.ant.util.IdentityMapper;
26
27
28 /**
29  * <p>
30  * Run an Ant task several times, setting a param from a
31  * tokenized list or fileset each time.
32  * </p>
33  *
34  * <ul>
35  * <li>target - target to be called, like antcall. Required.</li>
36  * <li>property - name of property to set to value on each call.
37  * Required.</li>
38  * <li>mappedproperty - name of property to be set to mapped
39  * value on each call.</li>
40  * <li>delims - delimiters for tokenizing values. Defaults
41  * to "\t\n, ".</li>
42  * <li>list - a delimited list of values. target is called
43  * once with each of these values setting property.</li>
44  * <li>fileset - target is called once for each file, with
45  * property set to the full path to the file.</li>
46  * <li>dirset - target is called once for each file, with
47  * property set to the full path to the directory.</li>
48  * </ul>
49  *
50  * <p>
51  * An optional mapper is allowed, the default is Identity.
52  * If specified, then target is only called for those values
53  * or files which match the mapper, and mappedproperty is
54  * set to the result "to" value on each call. Works for
55  * both filesets and values.
56  * </li>
57  *
58  * @author Brian Pontarelli
59  */

60 public class ForeachTask extends Task {
61
62     private String JavaDoc target;
63     private boolean inheritAll = true;
64     private boolean inheritRefs = false;
65     private String JavaDoc delims = ", \t\n";
66     private String JavaDoc property = null;
67     private String JavaDoc mappedProperty = null;
68     private String JavaDoc list = null;
69     private final List JavaDoc filesets = new ArrayList JavaDoc();
70     private final List JavaDoc dirsets = new ArrayList JavaDoc();
71     private Mapper mapperElement;
72     private int verbosity = Project.MSG_VERBOSE;
73     private Ant antTarget;
74
75
76     /**
77      * Set target to call.
78      */

79     public void setTarget(String JavaDoc target) {
80         this.target = target;
81     }
82
83     /**
84      * Sets the inheritAll property
85      */

86     public void setInheritAll(boolean inheritAll) {
87         this.inheritAll = inheritAll;
88     }
89
90     /**
91      * Sets the inheritRefs property
92      */

93     public void setInheritRefs(boolean inheritRefs) {
94         this.inheritRefs = inheritRefs;
95     }
96
97     /**
98      * Sets the property to be set with each call.
99      */

100     public void setProperty(String JavaDoc property) {
101         this.property = property;
102     }
103
104     /**
105      * Sets the property to be set with each call.
106      */

107     public void setMappedproperty(String JavaDoc property) {
108         this.mappedProperty = property;
109     }
110
111     /**
112      * Sets the list of values to iterate over
113      */

114     public void setList(String JavaDoc list) {
115         this.list = list;
116     }
117
118     /**
119      * Sets tokens.
120      */

121     public void setDelims(String JavaDoc delims) {
122         this.delims = delims;
123     }
124
125     /**
126      * Adds a set of files (nested fileset attribute).
127      */

128     public void addFileset(FileSet set) {
129         filesets.add(set);
130     }
131
132     /**
133      * Create param.
134      */

135     public Property createParam() {
136         return antTarget.createProperty();
137     }
138
139     /**
140      * Adds a new nested dirset
141      */

142     public void addDirset(FileSet set) {
143         dirsets.add(set);
144     }
145
146     /**
147      * Creates a new nested mapper
148      */

149     public Mapper createMapper() throws BuildException {
150         if (mapperElement != null) {
151             throw new BuildException("Cannot define more than one mapper",
152                 getLocation());
153         } else {
154             mapperElement = new Mapper(getProject());
155             return mapperElement;
156         }
157     }
158
159     /**
160      * Used to force reporting of each call
161      */

162     public void setVerbose(boolean verbose) {
163         this.verbosity = verbose ? Project.MSG_INFO : Project.MSG_VERBOSE;
164     }
165
166     /**
167      * Initializes the Ant target that we will be calling during the loops
168      */

169     public void init() {
170         antTarget = (Ant) getProject().createTask("ant");
171         antTarget.setOwningTarget(super.getOwningTarget());
172         antTarget.setTaskName(getTaskName());
173         antTarget.setLocation(getLocation());
174         antTarget.init();
175     }
176
177     /**
178      * Do the looping
179      */

180     public void execute() throws BuildException {
181
182         // Must have a sub target, property and some vals
183
if (target == null) {
184             throw new BuildException("Attribute target is required.", getLocation());
185         }
186
187         if (property == null && mappedProperty == null) {
188             throw new BuildException( "Specify a property or mappedproperty name.",
189                 getLocation());
190         }
191
192         if (!(list == null ^ (filesets.size() == 0 && dirsets.size() == 0))) {
193             throw new BuildException("Specify either list or a fileset.", getLocation());
194         }
195
196         antTarget.setInheritAll(inheritAll);
197         antTarget.setInheritRefs(inheritRefs);
198         antTarget.setDir(getProject().getBaseDir());
199         antTarget.setAntfile(getProject().getProperty("ant.file"));
200         antTarget.setTarget(target);
201         Project proj = antTarget.getProject();
202
203         // Set up mapper
204
FileNameMapper mapper = null;
205         if (mapperElement != null) {
206             mapper = mapperElement.getImplementation();
207         } else {
208             mapper = new IdentityMapper();
209         }
210
211         // Loop for tokenized values
212
if (list != null) {
213             for (StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(list, delims);
214                     st.hasMoreTokens(); ) {
215                 String JavaDoc val = st.nextToken();
216                 String JavaDoc[] val2 = mapper.mapFileName(val);
217
218                 callTarget(val, val2, antTarget, proj, target);
219             }
220         }
221
222         // loop for fileset
223
if (filesets.size() != 0) {
224
225             // Walk thru the filesets
226
for (Iterator JavaDoc sets = filesets.iterator(); sets.hasNext() ;) {
227                 FileSet fs = (FileSet) sets.next();
228                 File JavaDoc fromDir = fs.getDir(getProject());
229                 ArrayList JavaDoc fromFiles = new ArrayList JavaDoc();
230
231                 fromFiles.addAll(
232                     Arrays.asList(fs.getDirectoryScanner(getProject()).getIncludedFiles()));
233
234                 for (Iterator JavaDoc files = fromFiles.iterator(); files.hasNext();) {
235                     String JavaDoc f = (String JavaDoc) files.next();
236                     String JavaDoc val = new File JavaDoc(fromDir, f).getPath();
237                     String JavaDoc[] val2 = mapper.mapFileName(val);
238
239                     callTarget(val, val2, antTarget, proj, target);
240                 }
241             }
242         }
243
244         // loop for dirset
245
if (dirsets.size() != 0) {
246
247             // Walk thru the dirsets
248
for (Iterator JavaDoc sets = dirsets.iterator(); sets.hasNext() ;) {
249                 FileSet fs = (FileSet) sets.next();
250                 File JavaDoc fromDir = fs.getDir(getProject());
251                 ArrayList JavaDoc fromFiles = new ArrayList JavaDoc();
252
253                 fromFiles.addAll(
254                     Arrays.asList(fs.getDirectoryScanner(getProject()).getIncludedDirectories()));
255
256                 for (Iterator JavaDoc files = fromFiles.iterator(); files.hasNext(); ) {
257                     String JavaDoc f = (String JavaDoc) files.next();
258                     String JavaDoc val = new File JavaDoc(fromDir, f).getPath();
259                     String JavaDoc[] val2 = mapper.mapFileName(val);
260
261                     callTarget(val, val2, antTarget, proj, target);
262                 }
263             }
264         }
265     }
266
267     /**
268      * Calls the ant target that the loop is setup to call
269      */

270     protected void callTarget(String JavaDoc val, String JavaDoc[] val2, Ant antTarget,
271             Project proj, String JavaDoc target) {
272
273         if (val2 == null || val2.length == 0) {
274             log("Skipping unmapped " + val, verbosity);
275             return;
276         }
277
278         for (int j = 0; j < val2.length; ++j) {
279             if (property != null) {
280                 proj.setProperty(property, val);
281             }
282
283             if (mappedProperty != null) {
284                 proj.setProperty(mappedProperty, val2[j]);
285             }
286
287             log( "Calling " + target + " with "
288                  + ( property == null ? "" :
289                      property + "=" + proj.getProperty( property )
290                      + ( mappedProperty == null ? "" : " and " ) )
291                  + ( mappedProperty == null ? "" :
292                      mappedProperty + "=" + proj.getProperty( mappedProperty ) ),
293                  verbosity );
294
295             antTarget.execute();
296         }
297     }
298 }
Popular Tags