KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > jayasoft > ivy > ant > IvyBuildList


1 /*
2  * This file is subject to the licence found in LICENCE.TXT in the root directory of the project.
3  * Copyright Jayasoft 2005 - All rights reserved
4  *
5  * #SNAPSHOT#
6  */

7 package fr.jayasoft.ivy.ant;
8
9 import java.io.File JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.Collection JavaDoc;
12 import java.util.Collections JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.ListIterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import org.apache.tools.ant.BuildException;
22 import org.apache.tools.ant.DirectoryScanner;
23 import org.apache.tools.ant.types.FileList;
24 import org.apache.tools.ant.types.FileSet;
25 import org.apache.tools.ant.types.Path;
26
27 import fr.jayasoft.ivy.DependencyDescriptor;
28 import fr.jayasoft.ivy.Ivy;
29 import fr.jayasoft.ivy.ModuleDescriptor;
30 import fr.jayasoft.ivy.ModuleId;
31 import fr.jayasoft.ivy.parser.ModuleDescriptorParserRegistry;
32 import fr.jayasoft.ivy.util.Message;
33
34 /**
35  * Creates an ant filelist of files (usually build.xml) ordered according to the dependencies declared in ivy files.
36  *
37  * @author Xavier Hanin
38  */

39 public class IvyBuildList extends IvyTask {
40     private List JavaDoc _buildFiles = new ArrayList JavaDoc(); // List (FileSet)
41
private String JavaDoc _reference;
42     private boolean _haltOnError = true;
43     private boolean _skipBuildWithoutIvy = false;
44     private boolean _reverse = false;
45     private String JavaDoc _ivyFilePath;
46     private String JavaDoc _root = "*";
47     private boolean _excludeRoot = false;
48     private String JavaDoc _leaf = "*";
49     private boolean _excludeLeaf = false;
50
51
52     public void addFileset(FileSet buildFiles) {
53         _buildFiles.add(buildFiles);
54     }
55
56     public String JavaDoc getReference() {
57         return _reference;
58     }
59
60     public void setReference(String JavaDoc reference) {
61         _reference = reference;
62     }
63
64     public String JavaDoc getRoot() {
65         return _root;
66     }
67
68     public void setRoot(String JavaDoc root) {
69         _root = root;
70     }
71
72     public boolean isExcludeRoot() {
73         return _excludeRoot;
74     }
75
76     public void setExcludeRoot(boolean root) {
77         _excludeRoot = root;
78     }
79
80     public String JavaDoc getLeaf() {
81         return _leaf;
82     }
83
84     public void setLeaf(String JavaDoc leaf) {
85         _leaf = leaf;
86     }
87
88     public boolean isExcludeLeaf() {
89         return _excludeLeaf;
90     }
91
92     public void setExcludeLeaf(boolean excludeLeaf) {
93         _excludeLeaf = excludeLeaf;
94     }
95
96     public void execute() throws BuildException {
97         if (_reference == null) {
98             throw new BuildException("reference should be provided in ivy build list");
99         }
100         if (_buildFiles.isEmpty()) {
101             throw new BuildException("at least one nested fileset should be provided in ivy build list");
102         }
103
104         Ivy ivy = getIvyInstance();
105         _ivyFilePath = getProperty(_ivyFilePath, ivy, "ivy.buildlist.ivyfilepath");
106
107         Path path = new Path(getProject());
108
109         Map JavaDoc buildFiles = new HashMap JavaDoc(); // Map (ModuleDescriptor -> File buildFile)
110
Collection JavaDoc mds = new ArrayList JavaDoc();
111         List JavaDoc independent = new ArrayList JavaDoc();
112         ModuleDescriptor rootModuleDescriptor = null;
113         ModuleDescriptor leafModuleDescriptor = null;
114
115         for (ListIterator JavaDoc iter = _buildFiles.listIterator(); iter.hasNext();) {
116             FileSet fs = (FileSet)iter.next();
117             DirectoryScanner ds = fs.getDirectoryScanner(getProject());
118             String JavaDoc[] builds = ds.getIncludedFiles();
119             for (int i = 0; i < builds.length; i++) {
120                 File JavaDoc buildFile = new File JavaDoc(ds.getBasedir(), builds[i]);
121                 File JavaDoc ivyFile = getIvyFileFor(buildFile);
122                 if (!ivyFile.exists()) {
123                     if (_skipBuildWithoutIvy) {
124                         Message.debug("skipping "+buildFile+": ivy file "+ivyFile+" doesn't exist");
125                     } else {
126                         Message.verbose("no ivy file for "+buildFile+": ivyfile="+ivyFile+": adding it at the beginning of the path");
127                         Message.verbose("\t(set skipbuildwithoutivy to true if you don't want this file to be added to the path)");
128                         independent.add(buildFile);
129                     }
130                 } else {
131                     try {
132                         ModuleDescriptor md = ModuleDescriptorParserRegistry.getInstance().parseDescriptor(ivy, ivyFile.toURL(), doValidate(ivy));
133                         buildFiles.put(md, buildFile);
134                         mds.add(md);
135                         if (_root.equals(md.getModuleRevisionId().getName())) {
136                             rootModuleDescriptor = md;
137                         }
138                         if (_leaf.equals(md.getModuleRevisionId().getName())) {
139                             leafModuleDescriptor = md;
140                         }
141
142                     } catch (Exception JavaDoc ex) {
143                         if (_haltOnError) {
144                             throw new BuildException("impossible to parse ivy file for "+buildFile+": ivyfile="+ivyFile+" exception="+ex, ex);
145                         } else {
146                             Message.warn("impossible to parse ivy file for "+buildFile+": ivyfile="+ivyFile+" exception="+ex.getMessage());
147                             Message.info("\t=> adding it at the beginning of the path");
148                             independent.add(buildFile);
149                         }
150                     }
151                 }
152             }
153         }
154
155         if (!"*".equals(_root) && rootModuleDescriptor == null) {
156             throw new BuildException("unable to find root module " + _root + " in build fileset");
157         }
158         if (!"*".equals(_leaf) && leafModuleDescriptor == null) {
159             throw new BuildException("unable to find leaf module " + _leaf + " in build fileset");
160         }
161
162         if (rootModuleDescriptor != null) {
163             Message.info("Filtering modules based on root " + rootModuleDescriptor.getModuleRevisionId().getName());
164             mds = filterModulesFromRoot(mds, rootModuleDescriptor);
165         }
166         if (leafModuleDescriptor != null) {
167             Message.info("Filtering modules based on leaf " + leafModuleDescriptor.getModuleRevisionId().getName());
168             mds = filterModulesFromLeaf(mds, leafModuleDescriptor);
169         }
170
171         List JavaDoc sortedModules = ivy.sortModuleDescriptors(mds);
172
173         for (ListIterator JavaDoc iter = independent.listIterator(); iter.hasNext();) {
174             File JavaDoc buildFile = (File JavaDoc)iter.next();
175             addBuildFile(path, buildFile);
176         }
177         if (isReverse()) {
178             Collections.reverse(sortedModules);
179         }
180         StringBuffer JavaDoc order = new StringBuffer JavaDoc();
181         for (ListIterator JavaDoc iter = sortedModules.listIterator(); iter.hasNext();) {
182             ModuleDescriptor md = (ModuleDescriptor)iter.next();
183             order.append(md.getModuleRevisionId().getModuleId());
184             if (iter.hasNext()) {
185                 order.append(", ");
186             }
187             File JavaDoc buildFile = (File JavaDoc)buildFiles.get(md);
188             addBuildFile(path, buildFile);
189         }
190
191         getProject().addReference(getReference(), path);
192         getProject().setProperty("ivy.sorted.modules", order.toString());
193     }
194
195     /**
196      * Returns a collection of ModuleDescriptors that are conatined in the input
197      * collection of ModuleDescriptors and upon which the root module depends
198      *
199      * @param mds input collection of ModuleDescriptors
200      * @param rootmd root module
201      * @return filtered list of modules
202      */

203     private Collection JavaDoc filterModulesFromRoot(Collection JavaDoc mds, ModuleDescriptor rootmd) {
204         // Make a map of ModuleId objects -> ModuleDescriptors
205
Map JavaDoc moduleIdMap = new HashMap JavaDoc();
206         for (Iterator JavaDoc iter = mds.iterator(); iter.hasNext();) {
207             ModuleDescriptor md = ((ModuleDescriptor) iter.next());
208             moduleIdMap.put(md.getModuleRevisionId().getModuleId(), md);
209         }
210
211         // recursively process the nodes
212
Set JavaDoc toKeep = new HashSet JavaDoc();
213         processFilterNodeFromRoot(rootmd, toKeep, moduleIdMap);
214
215         // With the excluderoot attribute set to true, take the rootmd out of the toKeep set.
216
if (_excludeRoot) {
217             Message.verbose("Excluded module " + rootmd.getModuleRevisionId().getModuleId().getName());
218             toKeep.remove(rootmd);
219         }
220
221         // just for logging
222
for (Iterator JavaDoc iter = toKeep.iterator(); iter.hasNext();) {
223             ModuleDescriptor md = ((ModuleDescriptor) iter.next());
224             Message.verbose("Kept module " + md.getModuleRevisionId().getModuleId().getName());
225         }
226
227         return toKeep;
228     }
229
230     /**
231      * Adds the current node to the toKeep collection and then processes the each of the direct dependencies
232      * of this node that appear in the moduleIdMap (indicating that the dependency is part of this BuildList)
233      *
234      * @param node the node to be processed
235      * @param toKeep the set of ModuleDescriptors that should be kept
236      * @param moduleIdMap reference mapping of moduleId to ModuleDescriptor that are part of the BuildList
237      */

238     private void processFilterNodeFromRoot(ModuleDescriptor node, Set JavaDoc toKeep, Map JavaDoc moduleIdMap) {
239         toKeep.add(node);
240
241         DependencyDescriptor[] deps = node.getDependencies();
242         for (int i=0; i<deps.length; i++) {
243             ModuleId id = deps[i].getDependencyId();
244             if (moduleIdMap.get(id) != null) {
245                 processFilterNodeFromRoot((ModuleDescriptor) moduleIdMap.get(id), toKeep, moduleIdMap);
246             }
247         }
248     }
249
250     /**
251      * Returns a collection of ModuleDescriptors that are conatined in the input
252      * collection of ModuleDescriptors which depends on the leaf module
253      *
254      * @param mds input collection of ModuleDescriptors
255      * @param leafmd leaf module
256      * @return filtered list of modules
257      */

258     private Collection JavaDoc filterModulesFromLeaf(Collection JavaDoc mds, ModuleDescriptor leafmd) {
259         // Make a map of ModuleId objects -> ModuleDescriptors
260
Map JavaDoc moduleIdMap = new HashMap JavaDoc();
261         for (Iterator JavaDoc iter = mds.iterator(); iter.hasNext();) {
262             ModuleDescriptor md = ((ModuleDescriptor) iter.next());
263             moduleIdMap.put(md.getModuleRevisionId().getModuleId(), md);
264         }
265
266         // recursively process the nodes
267
Set JavaDoc toKeep = new HashSet JavaDoc();
268         // With the excludeleaf attribute set to true, take the rootmd out of the toKeep set.
269
if (_excludeLeaf) {
270             Message.verbose("Excluded module " + leafmd.getModuleRevisionId().getModuleId().getName());
271         } else {
272             toKeep.add(leafmd);
273         }
274         processFilterNodeFromLeaf(leafmd, toKeep, moduleIdMap);
275
276
277         // just for logging
278
for (Iterator JavaDoc iter = toKeep.iterator(); iter.hasNext();) {
279             ModuleDescriptor md = ((ModuleDescriptor) iter.next());
280             Message.verbose("Kept module " + md.getModuleRevisionId().getModuleId().getName());
281         }
282
283         return toKeep;
284     }
285
286     /**
287      * Search in the moduleIdMap modules depending on node, add them to the toKeep set and process them
288      * recursively.
289      *
290      * @param node the node to be processed
291      * @param toKeep the set of ModuleDescriptors that should be kept
292      * @param moduleIdMap reference mapping of moduleId to ModuleDescriptor that are part of the BuildList
293      */

294     private void processFilterNodeFromLeaf(ModuleDescriptor node, Set JavaDoc toKeep, Map JavaDoc moduleIdMap) {
295         for (Iterator JavaDoc iter = moduleIdMap.values().iterator(); iter.hasNext();) {
296             ModuleDescriptor md = (ModuleDescriptor) iter.next();
297             DependencyDescriptor[] deps = md.getDependencies();
298             for (int i=0; i<deps.length; i++) {
299                 ModuleId id = deps[i].getDependencyId();
300                 if (node.getModuleRevisionId().getModuleId().equals(id) && !toKeep.contains(md)) {
301                     toKeep.add(md);
302                     processFilterNodeFromLeaf(md, toKeep, moduleIdMap);
303                 }
304             }
305         }
306     }
307
308     private void addBuildFile(Path path, File JavaDoc buildFile) {
309         FileList fl = new FileList();
310         fl.setDir(buildFile.getParentFile());
311         FileList.FileName fileName = new FileList.FileName();
312         fileName.setName(buildFile.getName());
313         fl.addConfiguredFile(fileName);
314         path.addFilelist(fl);
315     }
316
317     private File JavaDoc getIvyFileFor(File JavaDoc buildFile) {
318         return new File JavaDoc(buildFile.getParentFile(), _ivyFilePath);
319     }
320
321     public boolean isHaltonerror() {
322         return _haltOnError;
323     }
324
325     public void setHaltonerror(boolean haltOnError) {
326         _haltOnError = haltOnError;
327     }
328
329     public String JavaDoc getIvyfilepath() {
330         return _ivyFilePath;
331     }
332
333     public void setIvyfilepath(String JavaDoc ivyFilePath) {
334         _ivyFilePath = ivyFilePath;
335     }
336
337     public boolean isSkipbuildwithoutivy() {
338         return _skipBuildWithoutIvy;
339     }
340
341     public void setSkipbuildwithoutivy(boolean skipBuildFilesWithoutIvy) {
342         _skipBuildWithoutIvy = skipBuildFilesWithoutIvy;
343     }
344
345     public boolean isReverse() {
346         return _reverse;
347     }
348
349
350     public void setReverse(boolean reverse) {
351         _reverse = reverse;
352     }
353
354 }
355
Popular Tags