KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > jayasoft > ivy > ModuleDescriptorSorter


1 package fr.jayasoft.ivy;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Collection JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.LinkedHashMap JavaDoc;
7 import java.util.LinkedList JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.Stack JavaDoc;
11
12 import fr.jayasoft.ivy.circular.CircularDependencyException;
13 import fr.jayasoft.ivy.circular.CircularDependencyHelper;
14 import fr.jayasoft.ivy.util.Message;
15 import fr.jayasoft.ivy.version.VersionMatcher;
16
17 /**
18  * Inner helper class for sorting ModuleDescriptors.
19  * @author baumkar (for most of the code)
20  * @author xavier hanin (for the sorting of nodes based upon sort of modules)
21  *
22  */

23 class ModuleDescriptorSorter {
24     public static List JavaDoc sortNodes(VersionMatcher matcher, Collection JavaDoc nodes) {
25         /* here we want to use the sort algorithm which work on module descriptors :
26          * so we first put dependencies on a map from descriptors to dependency, then we
27          * sort the keySet (i.e. a collection of descriptors), then we replace
28          * in the sorted list each descriptor by the corresponding dependency
29          */

30         
31         Map JavaDoc dependenciesMap = new LinkedHashMap JavaDoc();
32         List JavaDoc nulls = new ArrayList JavaDoc();
33         for (Iterator JavaDoc iter = nodes.iterator(); iter.hasNext();) {
34             IvyNode node = (IvyNode)iter.next();
35             if (node.getDescriptor() == null) {
36                 nulls.add(node);
37             } else {
38                 List JavaDoc n = (List JavaDoc)dependenciesMap.get(node.getDescriptor());
39                 if (n == null) {
40                     n = new ArrayList JavaDoc();
41                     dependenciesMap.put(node.getDescriptor(), n);
42                 }
43                 n.add(node);
44             }
45         }
46         List JavaDoc list = sortModuleDescriptors(matcher, dependenciesMap.keySet());
47         List JavaDoc ret = new ArrayList JavaDoc((int)(list.size()*1.3+nulls.size())); //attempt to adjust the size to avoid too much list resizing
48
for (int i=0; i<list.size(); i++) {
49             ModuleDescriptor md = (ModuleDescriptor)list.get(i);
50             List JavaDoc n = (List JavaDoc)dependenciesMap.get(md);
51             ret.addAll(n);
52         }
53         ret.addAll(0, nulls);
54         return ret;
55     }
56
57
58     /**
59      * Sorts the given ModuleDescriptors from the less dependent to the more dependent.
60      * This sort ensures that a ModuleDescriptor is always found in the list before all
61      * ModuleDescriptors depending directly on it.
62      * @param moduleDescriptors a Collection of ModuleDescriptor to sort
63      * @return a List of sorted ModuleDescriptors
64      * @throws CircularDependencyException if a circular dependency exists
65      */

66     public static List JavaDoc sortModuleDescriptors(VersionMatcher matcher, Collection JavaDoc moduleDescriptors) throws CircularDependencyException {
67         return new ModuleDescriptorSorter(moduleDescriptors).sortModuleDescriptors(matcher);
68     }
69     
70     
71     private final Collection JavaDoc moduleDescriptors;
72     private final Iterator JavaDoc moduleDescriptorsIterator;
73     private final List JavaDoc sorted = new LinkedList JavaDoc();
74     
75     public ModuleDescriptorSorter(Collection JavaDoc moduleDescriptors) {
76         this.moduleDescriptors=moduleDescriptors;
77         moduleDescriptorsIterator = new LinkedList JavaDoc(moduleDescriptors).iterator();
78     }
79     
80     /**
81      * Iterates over all modules calling sortModuleDescriptorsHelp.
82      * @return sorted module
83      * @throws CircularDependencyException
84      */

85     public List JavaDoc sortModuleDescriptors(VersionMatcher matcher) throws CircularDependencyException {
86         while (moduleDescriptorsIterator.hasNext()) {
87             sortModuleDescriptorsHelp(matcher, (ModuleDescriptor)moduleDescriptorsIterator.next(), new Stack JavaDoc());
88         }
89         return sorted;
90     }
91
92     /**
93      * If current module has already been added to list, returns,
94      * Otherwise invokes sortModuleDescriptorsHelp for all dependencies
95      * contained within set of moduleDescriptors. Then finally adds self
96      * to list of sorted.
97      * @param current Current module to add to sorted list.
98      * @throws CircularDependencyException
99      */

100     private void sortModuleDescriptorsHelp(VersionMatcher matcher, ModuleDescriptor current, Stack JavaDoc callStack) throws CircularDependencyException {
101         //if already sorted return
102
if (sorted.contains(current)) {
103             return;
104         }
105         if (callStack.contains(current)) {
106             callStack.add(current);
107             Message.verbose("circular dependency ignored during sort: "+CircularDependencyHelper.formatMessage((ModuleDescriptor[]) callStack.toArray(new ModuleDescriptor[callStack.size()])));
108             return;
109         }
110         DependencyDescriptor [] descriptors = current.getDependencies();
111         ModuleDescriptor moduleDescriptorDependency = null;
112         for (int i = 0; descriptors!=null && i < descriptors.length; i++) {
113             moduleDescriptorDependency = getModuleDescriptorDependency(matcher, descriptors[i]);
114             
115             if (moduleDescriptorDependency != null) {
116                 callStack.push(current);
117                 sortModuleDescriptorsHelp(matcher, moduleDescriptorDependency, callStack);
118                 callStack.pop();
119             }
120         }
121         sorted.add(current);
122     }
123
124     /**
125      * @param descriptor
126      * @return a ModuleDescriptor from the collection of module descriptors to sort.
127      * If none exists returns null.
128      */

129     private ModuleDescriptor getModuleDescriptorDependency(VersionMatcher matcher, DependencyDescriptor descriptor) {
130         Iterator JavaDoc i = moduleDescriptors.iterator();
131         ModuleDescriptor md = null;
132         while (i.hasNext()) {
133             md = (ModuleDescriptor) i.next();
134             if (descriptor.getDependencyId().equals(md.getModuleRevisionId().getModuleId())) {
135                 if (md.getResolvedModuleRevisionId().getRevision() == null) {
136                     return md;
137                 } else if (matcher.accept(descriptor.getDependencyRevisionId(), md)) {
138                     return md;
139                 }
140             }
141         }
142         return null;
143     }
144 }
Popular Tags