KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > dependencies > ElementSet


1 /*******************************************************************************
2  * Copyright (c) 2003, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.dependencies;
12
13 import java.util.*;
14
15 public class ElementSet {
16     private DependencySystem system;
17     private Object JavaDoc id;
18     // # of iteration this element set was last visited
19
transient private int visitedMark;
20     // # of iteration this element set was last changed
21
transient private int changedMark;
22     // does this element set need to be recomputed? (the value is one of {UP_TO_DATE,SATISFACTION,SELECTION,RESOLUTION})
23
transient private int needingUpdate;
24     private int singletonsCount;
25     private Collection requiring;
26     private Collection required;
27     private Map available;
28     private Set satisfied;
29     private Set selected;
30     private Set resolved;
31     private Map dependencyCounters;
32
33     public ElementSet(Object JavaDoc id, DependencySystem system) {
34         this.id = id;
35         this.system = system;
36         this.setNeedingUpdate(DependencySystem.SATISFACTION);
37         this.available = new HashMap();
38         this.satisfied = Collections.EMPTY_SET;
39         this.selected = Collections.EMPTY_SET;
40         this.resolved = Collections.EMPTY_SET;
41         this.required = new LinkedList();
42         this.requiring = new LinkedList();
43         this.dependencyCounters = new HashMap();
44     }
45
46     public DependencySystem getSystem() {
47         return system;
48     }
49
50     /** @return false if there is at least one version that does not allow concurrency. */
51     public boolean allowsConcurrency() {
52         return singletonsCount == 0;
53     }
54
55     void addElement(Element element) {
56         if (this.available.containsKey(element.getVersionId()))
57             return;
58         this.setNeedingUpdate(DependencySystem.SATISFACTION);
59         this.available.put(element.getVersionId(), element);
60         Dependency[] dependencies = element.getDependencies();
61         for (int i = 0; i < dependencies.length; i++)
62             this.addRequired(dependencies[i].getRequiredObjectId());
63         if (element.isSingleton())
64             this.singletonsCount++;
65         system.recordElementStatusChanged(element, ElementChange.ADDED);
66     }
67
68     void removeElement(Element element) {
69         removeElement(element.getVersionId());
70     }
71
72     void removeElement(Object JavaDoc versionId) {
73         Element toRemove = (Element) this.available.remove(versionId);
74         if (toRemove == null)
75             return;
76         this.markNeedingUpdate(DependencySystem.SATISFACTION);
77         Dependency[] dependencies = toRemove.getDependencies();
78         for (int i = 0; i < dependencies.length; i++)
79             removeRequired(dependencies[i].getRequiredObjectId());
80         // if does not allow concurrency, decrement preventingConcurrencyCount
81
if (toRemove.isSingleton())
82             this.singletonsCount--;
83         int change = ElementChange.REMOVED;
84         // if (resolved.contains(toRemove))
85
// change |= ElementChange.UNRESOLVED;
86
system.recordElementStatusChanged(toRemove, change);
87     }
88
89     /**
90      * Returns the unique id for this element set.
91      */

92     public Object JavaDoc getId() {
93         return id;
94     }
95
96     /**
97      * Is this a root element set?
98      */

99     public boolean isRoot() {
100         return getRequired().isEmpty();
101     }
102
103     /**
104      * Returns all elements available in this element set.
105      */

106     public Set getAvailable() {
107         return new HashSet(available.values());
108     }
109
110     /**
111      * Returns all elements sets required this element set.
112      */

113
114     public Collection getRequired() {
115         return required;
116     }
117
118     /**
119      * Returns all elements sets requiring this element set.
120      */

121
122     public Collection getRequiring() {
123         return requiring;
124     }
125
126     /**
127      * Returns all elements currently resolved in this element set.
128      */

129
130     public Set getResolved() {
131         return resolved;
132     }
133
134     public void resolveDependency(Dependency dependency, Object JavaDoc resolvedVersionId) {
135         dependency.resolve(resolvedVersionId, this.visitedMark);
136     }
137
138     public void setResolved(Set newResolved) {
139         this.setNeedingUpdate(DependencySystem.UP_TO_DATE);
140
141         //TODO: this may well be optimized...
142
// maybe just a pre-requisite changed
143
for (Iterator resolvedIter = this.resolved.iterator(); resolvedIter.hasNext();) {
144             Element resolvedElement = (Element) resolvedIter.next();
145             Dependency[] dependencies = resolvedElement.getDependencies();
146             for (int i = 0; i < dependencies.length; i++)
147                 if (dependencies[i].getChangedMark() == this.getVisitedMark()) {
148                     system.recordElementStatusChanged(resolvedElement, ElementChange.LINKAGE_CHANGED);
149                     break;
150                 }
151         }
152         if (newResolved.equals(this.resolved))
153             return;
154         this.setChangedMark(visitedMark);
155         Collection oldResolved = this.resolved;
156         this.resolved = Collections.unmodifiableSet(newResolved);
157         system.recordDependencyChanged(oldResolved, newResolved);
158     }
159
160     /**
161      * Returns all elements currently selected in this element set.
162      */

163
164     public Set getSelected() {
165         return selected;
166     }
167
168     public void setSelected(Set selected) {
169         this.setNeedingUpdate(DependencySystem.RESOLUTION);
170         if (selected.equals(this.selected))
171             return;
172         this.setChangedMark(visitedMark);
173         this.selected = Collections.unmodifiableSet(selected);
174     }
175
176     /**
177      * Returns all elements currently satisfied in this element set.
178      */

179
180     public Set getSatisfied() {
181         return satisfied;
182     }
183
184     public void setSatisfied(Set satisfied) {
185         this.setNeedingUpdate(DependencySystem.SELECTION);
186         if (satisfied.equals(this.satisfied))
187             return;
188         this.setChangedMark(visitedMark);
189         this.satisfied = Collections.unmodifiableSet(satisfied);
190     }
191
192     public String JavaDoc toString() {
193         return this.id + ": " + available; //$NON-NLS-1$
194
}
195
196     public boolean equals(Object JavaDoc elementSet) {
197         return ((ElementSet) elementSet).getId().equals(this.id);
198     }
199
200     public int hashCode() {
201         return this.id.hashCode();
202     }
203
204     class DependencyCounter {
205         int value;
206     }
207
208     private void addRequired(Object JavaDoc requiredId) {
209         this.setNeedingUpdate(DependencySystem.SATISFACTION);
210         ElementSet requiredNode = system.getElementSet(requiredId);
211         DependencyCounter counter = (DependencyCounter) this.dependencyCounters.get(requiredId);
212         if (counter == null) {
213             this.dependencyCounters.put(requiredId, counter = new DependencyCounter());
214             // links requiring and required element sets in both directions
215
this.required.add(requiredNode);
216             requiredNode.requiring.add(this);
217             requiredNode.setNeedingUpdate(Math.min(requiredNode.getNeedingUpdate(), DependencySystem.SELECTION));
218         }
219         counter.value++;
220     }
221
222     private void removeRequired(Object JavaDoc requiredId) {
223         ElementSet requiredNode = system.getElementSet(requiredId);
224         DependencyCounter counter = (DependencyCounter) this.dependencyCounters.get(requiredId);
225         if (counter == null) {
226             if (system.inDebugMode())
227                 System.err.println("Trying to remove non-existent dependency: " + this.id + " -> " + requiredId); //$NON-NLS-1$ //$NON-NLS-2$
228
return;
229         }
230         counter.value--;
231         if (counter.value == 0) {
232             this.dependencyCounters.remove(requiredId);
233             // removes links between requiring and required element sets
234
this.required.remove(requiredNode);
235             requiredNode.requiring.remove(this);
236             requiredNode.setNeedingUpdate(DependencySystem.SELECTION);
237         }
238     }
239
240     public void removeFromCycle() {
241         Element[] availableElements = (Element[]) this.available.values().toArray(new Element[this.available.size()]);
242         for (int i = 0; i < availableElements.length; i++) {
243             removeElement(availableElements[i]);
244             availableElements[i].removeFromCycle();
245             addElement(availableElements[i]);
246         }
247     }
248
249     int getRequiringCount() {
250         return requiring.size();
251     }
252
253     int getElementCount() {
254         return available.size();
255     }
256
257     int getVisitedMark() {
258         return visitedMark;
259     }
260
261     void setVisitedMark(int mark) {
262         this.visitedMark = mark;
263     }
264
265     int getChangedMark() {
266         return changedMark;
267     }
268
269     private void setChangedMark(int mark) {
270         this.changedMark = mark;
271     }
272
273     void markNeedingUpdate(int order) {
274         setNeedingUpdate(order);
275     }
276
277     boolean isNeedingUpdate(int order) {
278         return getNeedingUpdate() <= order;
279     }
280
281     Element getElement(Object JavaDoc versionId) {
282         return (Element) this.available.get(versionId);
283     }
284
285     /**
286      * Assumes resolved system - returns all elements whose dependencies
287      * were resolved to point to the specified element.
288      */

289
290     public Collection getRequiringElements(Object JavaDoc versionId) {
291         Collection result = new LinkedList();
292         for (Iterator requiringSetsIter = requiring.iterator(); requiringSetsIter.hasNext();) {
293             ElementSet requiringSet = (ElementSet) requiringSetsIter.next();
294             for (Iterator iter = requiringSet.getResolved().iterator(); iter.hasNext();) {
295                 Element element = (Element) iter.next();
296                 Dependency requisite = element.getDependency(this.id);
297                 if (requisite != null && versionId.equals(requisite.getResolvedVersionId()))
298                     result.add(element);
299             }
300         }
301         return result;
302     }
303
304     public void unresolve(Element element, int mark) {
305         setVisitedMark(mark);
306         if (!resolved.contains(element))
307             return;
308         Set newResolved = new HashSet(resolved);
309         newResolved.remove(element);
310         resolved = Collections.unmodifiableSet(newResolved);
311
312         Dependency[] dependencies = element.getDependencies();
313         // unresolved dependencies
314
for (int i = 0; i < dependencies.length; i++)
315             resolveDependency(dependencies[i], null);
316         setChangedMark(mark);
317         setNeedingUpdate(DependencySystem.SATISFACTION);
318     }
319
320     private void setNeedingUpdate(int needingUpdate) {
321         this.needingUpdate = needingUpdate;
322     }
323
324     private int getNeedingUpdate() {
325         return needingUpdate;
326     }
327
328 }
Popular Tags