KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > invicta > project > ComponentDefinition


1 package net.sf.invicta.project;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.HashMap JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.List JavaDoc;
7 import java.util.Map JavaDoc;
8  
9 import org.apache.commons.collections.SequencedHashMap;
10 import net.sf.invicta.InvictaConstants;
11 import net.sf.invicta.Logger;
12 import net.sf.invicta.api.Product;
13 import net.sf.invicta.api.ProductContainer;
14
15
16 /**
17  * A component defined in a project definition file.
18  * Acts as a java bean filled by the digester with the elements of a
19  * component definition.
20  * Also performs the resolving of the component definition:
21  * dependencies resolving, products definition, etc.
22  */

23 public class ComponentDefinition {
24     private static final char COMPONENT_NAME_SEPARATOR = '.';
25     // Digester related members
26
private String JavaDoc name;
27     private String JavaDoc type;
28     private String JavaDoc dir;
29     private List JavaDoc depends = new ArrayList JavaDoc(); // List of Depend objects.
30
private ProductContainer selfProducts = new ProductContainerImpl();
31     private Map JavaDoc properties = new SequencedHashMap(); // Map of Property objects.
32
private ProjectDefinition projDef;
33         
34     // Resolving related members
35
private boolean isResolved = false;
36     private ProductContainer dependExportedProducts = new ProductContainerImpl();
37     private ProductContainer dependPrivateProducts = new ProductContainerImpl();
38     private ProductContainer recursiveProducts = new ProductContainerImpl();
39     private Map JavaDoc dependComponents = new SequencedHashMap(); // Map of ComponentDefinition objects
40
private Map JavaDoc dependComponentNames = new SequencedHashMap(); // Map of String objects
41
private Map JavaDoc recursiveDependComponentNames = new HashMap JavaDoc(); // Map of String
42
private Map JavaDoc recursiveDependComponents = new HashMap JavaDoc(); // Map of ComponentDefinition
43

44     
45     /**
46      * Resolve this component (defined products, dependencies, etc.).
47      *
48      * @param projDef
49      * @param level An increasing level number to prevent endless circles of
50      * dependencies.
51      * @return ComponentDefinition
52      */

53     public ComponentDefinition resolve(ProjectDefinition projDef, int level) throws InvictaProjectException {
54         if (isResolved)
55             return this;
56         
57         this.projDef = projDef;
58         Logger.info(this.name + ", ");
59         // Check if we are in an endless loop
60
if (level > InvictaConstants.MAX_RESOLVE_LEVEL)
61             throw InvictaProjectException.componentDependencyCycle(this.name);
62
63         // Resolve the products defined in this component
64
resolveProducts(projDef);
65         
66         // Resolve the dependencies of this component.
67
resolveDependencies(projDef, level);
68         
69         isResolved = true;
70         
71         // Return the resolved component.
72
return this;
73     }
74     
75     
76     /**
77      * Resolve a single product defined in this component according to a given
78      * name.
79      *
80      *
81      */

82     public ProductContainer resolveProduct(ProjectDefinition projDef, String JavaDoc productName, int productLevel) throws InvictaProjectException {
83         // Look for the product according to the given name.
84
ProductContainer products = (ProductContainer)this.selfProducts.findByName(productName);
85         
86         // Check if the product is not defined.
87
if (products.size() == 0)
88             throw InvictaProjectException.productUndefined(this.name, productName);
89                         
90         // Resolve the product and returns it.
91
for (Iterator JavaDoc iter = products.findAll().iterator(); iter.hasNext();) {
92             BasicProduct product = (BasicProduct) iter.next();
93             product.resolve(projDef, this, productLevel);
94         }
95                         
96         return products;
97     }
98
99
100         
101     /**
102      * Returns the products that the product with the given defined name
103      * depends on recursively (directly and indirectly, exported and non-exported).
104      *
105      * @param productName
106      * @return ProductContainer
107      * @throws InvictaProjectException
108      */

109     public ProductContainer getRecursiveSelfProducts(List JavaDoc productNames) throws InvictaProjectException {
110         ProductContainer newContainer = new ProductContainerImpl();
111         
112         // Go over the given list of product names.
113
for (Iterator JavaDoc iter = productNames.iterator(); iter.hasNext();) {
114             String JavaDoc productName = (String JavaDoc)iter.next();
115                 
116             // Get the product definition
117
ProductContainer products = (ProductContainer)this.selfProducts.findByName(productName);
118                         
119             // Check if this component has no product defined with the given name,
120
if (products.size() == 0)
121                 throw InvictaProjectException.productUndefined(this.name, productName);
122                                                                  
123             // Add the defined product to the return map of products
124
for (Iterator JavaDoc prodIter = products.findAll().iterator(); prodIter.hasNext();) {
125                 Product product = (Product) prodIter.next();
126                 newContainer.insertAll(product.getProducts());
127             }
128         }
129             
130         return newContainer;
131     }
132     
133     /**
134      * Returns the products that the product with the given defined name
135      * depends on recursively (directly and indirectly, exported and non-exported).
136      *
137      * @param productName
138      * @return ProductContainer
139      * @throws InvictaProjectException
140      */

141     public ProductContainer getRecursiveSelfProducts(String JavaDoc productName) throws InvictaProjectException {
142         List JavaDoc productNames = new ArrayList JavaDoc();
143         productNames.add(productName);
144         return getRecursiveSelfProducts(productNames);
145     }
146
147     /**
148      * Returns the products with the given name that are defined in this component
149      *
150      * @param productName
151      * @return ProductContainer
152      */

153     public ProductContainer getSelfProducts(String JavaDoc productName) {
154         ProductContainer products = (ProductContainer)this.selfProducts.findByName(productName);
155         return products;
156     }
157
158     /**
159      * Returns the products that are defined in this component.
160      *
161      * @return ProductContainer
162      */

163     public ProductContainer getSelfProducts() {
164         return this.selfProducts;
165     }
166
167     public List JavaDoc getSelfProductsList() {
168         return this.selfProducts.findAll();
169     }
170     
171     /**
172      * Returns the products that this components requires or defines
173      * (private, exported and self products).
174      *
175      * @return ProductContainer
176      */

177     public ProductContainer getProducts() {
178         ProductContainer allProducts = new ProductContainerImpl();
179         
180         // Add all exported products.
181
allProducts.insertAll(this.dependExportedProducts);
182         
183         // Add all private products.
184
allProducts.insertAll(this.dependPrivateProducts);
185         
186         return allProducts;
187     }
188     
189     /**
190      * Returns the products that this component requires
191      * (for compilation. private and exported without self products).
192      *
193      * @return ProductContainer
194      */

195     public ProductContainer getProductsWithoutSelf() {
196         ProductContainer reqProducts = new ProductContainerImpl();
197         
198         // Add all exported products.
199
reqProducts.insertAll(this.dependExportedProducts);
200         
201         // Add all private products.
202
reqProducts.insertAll(this.dependPrivateProducts);
203         
204         // Remove the 'self' products
205
reqProducts.removeAll(this.selfProducts);
206                                         
207         return reqProducts;
208     }
209     
210     /**
211      * Returns the products that this components depends on and are exported.
212      *
213      * @return ProductContainer
214      */

215     public ProductContainer getExportedProducts() {
216                         
217         return this.dependExportedProducts;
218     }
219     
220     /**
221      * Return a map of all products that this component depends on and also
222      * exports.
223      *
224      * @return Map
225      */

226     public ProductContainer getDependExportedProducts() {
227         return this.dependExportedProducts;
228     }
229     
230     /**
231      * Return a map of all products that this component depends and are
232      * private.
233      *
234      * @return Map
235      */

236     public ProductContainer getDependPrivateProducts() {
237         return this.dependPrivateProducts;
238     }
239         
240
241     /**
242      * Returns the list of dependencies of this object.
243      *
244      * @return Vector
245      */

246     public List JavaDoc getDepends() {
247         return depends;
248     }
249
250     
251     /**
252      * Returns the name.
253      *
254      * @return String
255      */

256     public String JavaDoc getName() {
257         return name;
258     }
259
260
261     /**
262      * Returns the type.
263      *
264      * @return String
265      */

266     public String JavaDoc getType() {
267         return type;
268     }
269
270     /**
271      * Sets the name.
272      *
273      * @param name The name to set
274      */

275     public void setName(String JavaDoc name) {
276         this.name = name;
277     }
278
279     /**
280      * Sets the product.
281      *
282      * @param product The product to set
283      */

284     public void addProduct(BasicProduct product) {
285         this.selfProducts.insert(product);
286     }
287
288     /**
289      * Sets the type.
290      *
291      * @param type The type to set
292      */

293     public void setType(String JavaDoc type) {
294         this.type = type;
295     }
296         
297     /**
298      * Add a Depend defined in this component.
299      * @param product
300      */

301     public void addDepend(Depend depend) {
302         this.depends.add(depend);
303     }
304
305     /**
306      * Add a Property defined in this component.
307      * @param product
308      */

309     public void addProperty(PropertyImpl property) throws InvictaProjectException {
310         if (this.properties.containsKey(property.getName()))
311             throw InvictaProjectException.duplicateProperty(this.name, property.getName());
312         this.properties.put(property.getName(), property.getValue());
313     }
314
315     /**
316      * Returns the relative directory of this component.
317      *
318      * @return String. Relative directory.
319      */

320     public String JavaDoc getDir() {
321         if (this.dir != null)
322             return dir;
323         
324         String JavaDoc dir = this.name;
325         
326         // Remove the first word if a separator exists
327
int dotIndex = dir.indexOf(COMPONENT_NAME_SEPARATOR);
328         if (dotIndex != -1) {
329             dir = dir.substring(dotIndex + 1);
330             // Replace separators with file separators.
331
dir = dir.replace(COMPONENT_NAME_SEPARATOR, InvictaConstants.FILE_SEPARATOR_CHAR);
332         } else
333             dir = ".";
334         
335         return dir;
336     }
337
338     /**
339      * Sets the dir.
340      * @param dir The dir to set
341      */

342     public void setDir(String JavaDoc dir) {
343         this.dir = dir;
344     }
345
346     /**
347      *
348      * @see java.lang.Object#toString()
349      */

350     public String JavaDoc toString() {
351         return "[Component: name=" + getName() +
352                 ", type=" + getType() + ", dir=" + getDir() + "]";
353     }
354
355     /**
356      * Returns a list of component names that this component depends on
357      * (directly).
358      *
359      * @return List of String objects.
360      */

361     public List JavaDoc getDependComponentNames() {
362         return (List JavaDoc)new ArrayList JavaDoc(this.dependComponentNames.values());
363     }
364     
365     /**
366      * Returns a list of components that this component depends on (directly).
367      *
368      * @return List of ComponentDefinition objects.
369      */

370     public List JavaDoc getDependComponents() {
371         return (List JavaDoc)new ArrayList JavaDoc(this.dependComponents.values());
372     }
373         
374     
375     /**
376      * Returns the value of a property (component, project or general) with
377      * the given name.
378      * Returns null if the property is not defined.
379      *
380      * @param propertyName
381      * @return String
382      */

383     public String JavaDoc getPropertyValue(String JavaDoc propertyName) {
384         return (String JavaDoc)this.properties.get(propertyName);
385     }
386     
387     public void setPropertyValue(String JavaDoc name, String JavaDoc value) {
388         if (this.properties.containsKey(name))
389             return;
390             
391         this.properties.put(name, value);
392     }
393     
394     /**
395      * Returns a product with the given type and name.
396      * Returns null if a matching product doesn't exist.
397      *
398      * @param type Optional. Ignored if null.
399      * @param name Optional. Ignored if null.
400      * @return Product
401      */

402     public Product getSelfProduct(String JavaDoc type, String JavaDoc name) {
403         for (Iterator JavaDoc iter = this.selfProducts.iterator(); iter.hasNext();) {
404             Product product = (Product) iter.next();
405         // A product matches if:
406
// type was not specified or the type mathces
407
// // and
408
// name was not specified or the name matches
409
if (((type == null) ||
410              ((product.getType() != null) && (product.getType().equals(type))))
411              &&
412             ((name == null) ||
413              ((product.getName() != null) && (product.getName().equals(name))))
414             )
415             return product;
416             
417         }
418         return null;
419     }
420
421     
422     /**
423      * Returns a list of depend items of dependencies of this component.
424      *
425      * @return List of DependItem objects.
426      */

427     public List JavaDoc getDependItems() {
428         return this.depends;
429     }
430     
431     /**
432      * Returns the products that this components depends on recursively
433      * (directly and indirectly, exported and non-exported by dependent components,
434      * also includes self products).
435      *
436      * @return ProductContainer
437      */

438     public ProductContainer getRecursiveProducts() {
439         return this.recursiveProducts;
440     }
441     
442     /**
443      * Returns the products that this components depends on recursively
444      * (directly and indirectly, exported and non-exported by dependent components,
445      * doesn't include self products).
446      *
447      * @return ProductContainer
448      */

449     public ProductContainer getRecursiveProductsWithoutSelf() {
450         ProductContainer products = new ProductContainerImpl();
451         
452         // Add all exported products.
453
products.insertAll(this.recursiveProducts);
454                 
455         // Remove the 'self' products
456
products.removeAll(this.selfProducts);
457             
458         return products;
459     }
460     
461
462     public Map JavaDoc getRecursiveDependComponentNamesMap() {
463         return this.recursiveDependComponentNames;
464     }
465     
466     public Map JavaDoc getRecursiveDependComponentsMap() {
467         return this.recursiveDependComponents;
468     }
469         
470     public List JavaDoc getRecursiveDependComponentNames() {
471         return (List JavaDoc)new ArrayList JavaDoc(this.recursiveDependComponentNames.values());
472     }
473     
474     /**
475      * Returns a list of components that this componen depends on recursively
476      * (directly of indirectly).
477      *
478      * @return List of ComponentDefinition objects.
479      */

480     public List JavaDoc getRecursiveDependComponents() {
481         return (List JavaDoc)new ArrayList JavaDoc(this.recursiveDependComponents.values());
482     }
483
484     /**
485      * Resolve the dependencies of this component.
486      *
487      * @param components
488      * @param level An increasing level number to prevent endless circles of
489      * dependencies.
490      *
491      */

492     private void resolveDependencies(ProjectDefinition projectDefinition, int level) throws InvictaProjectException {
493     
494         // Add dependency on the global component.
495
if (!this.equals(projectDefinition.getGlobalComponent()))
496             this.depends.add(
497                 new Depend(projectDefinition.getGlobalComponent().getName(), true));
498     
499         // Go over all dependencies
500
for (Iterator JavaDoc iterator = depends.iterator(); iterator.hasNext();) {
501             Depend depend = (Depend) iterator.next();
502             
503             // Resolve a dependency.
504
depend.resolve(projectDefinition, level);
505                                     
506             // Add the name of the dependent component to the list of dependent component names.
507
this.dependComponentNames.put(depend.getName(),depend.getName());
508             this.dependComponents.put(depend.getName(),depend.getComponent());
509
510             // Add products (private and exported) that the new dependency defined.
511
addDependPrivateProducts(depend.getPrivateProducts());
512             addDependExportedProducts(depend.getExportedProducts());
513             addRecursiveProducts(depend.getRecursiveProducts());
514             addRecursiveDependComponentNames(depend.getRecursiveComponents());
515             addRecursiveDependComponents(depend.getRecursiveComponents());
516         }
517     }
518
519     /**
520      *
521      * @param projDef
522      * @throws InvictaProjectException
523      */

524     private void resolveProducts(ProjectDefinition projDef) throws InvictaProjectException {
525         Product potentialPrimary = null;
526         for (Iterator JavaDoc iter = this.selfProducts.iterator(); iter.hasNext();) {
527             BasicProduct product = (BasicProduct) iter.next();
528             product.resolve(projDef, this);
529                             
530             // Add the products of the defined product to the lists of the component's products.
531
addDependPrivateProducts(product.getPrivateProducts());
532             addDependExportedProducts(product.getExportedProducts());
533             addRecursiveProducts(product.getProducts());
534         }
535     }
536
537     /**
538      * Add the given map of products (with unique keys) to the map of
539      * private products of this component.
540      *
541      * @param products
542      */

543     private void addDependPrivateProducts(ProductContainer products) {
544         this.dependPrivateProducts.insertAll(products);
545     }
546     
547     
548     /**
549      * Add the given map of products (with unique keys) to the map of exported
550      * products of this component.
551      *
552      * @param products
553      */

554     private void addDependExportedProducts(ProductContainer products) {
555         this.dependExportedProducts.insertAll(products);
556     }
557
558
559     private void addRecursiveProducts(ProductContainer products) {
560         
561         this.recursiveProducts.insertAll(products);
562     }
563
564     private void addRecursiveDependComponentNames(Map JavaDoc moreDependComponentNames) {
565         this.recursiveDependComponentNames.putAll(moreDependComponentNames);
566     }
567
568     private void addRecursiveDependComponents(Map JavaDoc moreDependComponents) {
569         this.recursiveDependComponents.putAll(moreDependComponents);
570     }
571     
572         
573 }
574
Popular Tags