1 11 package org.eclipse.core.internal.dependencies; 12 13 import java.util.*; 14 15 public class ElementSet { 16 private DependencySystem system; 17 private Object id; 18 transient private int visitedMark; 20 transient private int changedMark; 22 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 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 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 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 (toRemove.isSingleton()) 82 this.singletonsCount--; 83 int change = ElementChange.REMOVED; 84 system.recordElementStatusChanged(toRemove, change); 87 } 88 89 92 public Object getId() { 93 return id; 94 } 95 96 99 public boolean isRoot() { 100 return getRequired().isEmpty(); 101 } 102 103 106 public Set getAvailable() { 107 return new HashSet(available.values()); 108 } 109 110 113 114 public Collection getRequired() { 115 return required; 116 } 117 118 121 122 public Collection getRequiring() { 123 return requiring; 124 } 125 126 129 130 public Set getResolved() { 131 return resolved; 132 } 133 134 public void resolveDependency(Dependency dependency, Object resolvedVersionId) { 135 dependency.resolve(resolvedVersionId, this.visitedMark); 136 } 137 138 public void setResolved(Set newResolved) { 139 this.setNeedingUpdate(DependencySystem.UP_TO_DATE); 140 141 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 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 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 toString() { 193 return this.id + ": " + available; } 195 196 public boolean equals(Object 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 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 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 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); return; 229 } 230 counter.value--; 231 if (counter.value == 0) { 232 this.dependencyCounters.remove(requiredId); 233 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 versionId) { 282 return (Element) this.available.get(versionId); 283 } 284 285 289 290 public Collection getRequiringElements(Object 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 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 |