1 11 package org.eclipse.osgi.internal.resolver; 12 13 import java.util.*; 14 import org.eclipse.core.internal.dependencies.*; 15 import org.eclipse.osgi.service.resolver.*; 16 import org.osgi.framework.Bundle; 17 18 public class ResolverImpl implements Resolver { 19 private State state; 20 private DependencySystem dependencies; 21 22 public void resolve(BundleDescription[] reRefresh) { 23 for (int i = 0; i < reRefresh.length; i++) 25 unresolveBundle(reRefresh[i]); 26 resolve(); 27 } 28 29 32 public synchronized void resolve() { 33 if (state == null) 34 throw new IllegalStateException ("RESOLVER_NO_STATE"); if (dependencies == null) 36 dependencies = ResolverHelper.buildDependencySystem(state, new Eclipse30SelectionPolicy()); 37 ResolutionDelta delta = null; 38 boolean success; 40 do { 41 success = true; 42 try { 43 delta = dependencies.resolve(); 44 } catch (DependencySystem.CyclicSystemException e) { 45 success = false; 46 Object [][] cycles = e.getCycles(); 47 for (int i = 0; i < cycles.length; i++) 49 for (int j = 0; j < cycles[i].length; j++) 50 ((ElementSet) cycles[i][j]).removeFromCycle(); 51 } 52 } while (!success); 53 processInnerDelta(delta); 54 resolvePackages(); 55 } 56 57 public void setState(State newState) { 58 if (state == newState) 60 return; 61 if (state != null) { 63 State oldState = state; 64 state = null; 65 oldState.setResolver(null); 66 } 67 state = newState; 68 if (newState != null) 69 state.setResolver(this); 70 flush(); 72 } 73 74 77 private void processInnerDelta(ResolutionDelta delta) { 78 ElementChange[] changes = delta.getAllChanges(); 80 for (int i = 0; i < changes.length; i++) { 81 Element element = changes[i].getElement(); 82 BundleDescription bundle = (BundleDescription) element.getUserObject(); 83 int kind = changes[i].getKind(); 84 if ((kind & ElementChange.RESOLVED) != 0) { 85 state.resolveBundle(bundle, Bundle.RESOLVED); 86 resolveConstraints(element); 87 } else if ((kind & ElementChange.UNRESOLVED) != 0) 88 state.resolveBundle(bundle, Bundle.INSTALLED); 89 else if (kind == ElementChange.LINKAGE_CHANGED) 90 resolveConstraints(element); 91 } 92 } 93 94 private void resolveConstraints(Element element) { 95 Dependency[] dependencies = element.getDependencies(); 98 for (int j = 0; j < dependencies.length; j++) { 99 if (dependencies[j].getResolvedVersionId() == null) 100 continue; 102 VersionConstraint constraint = (VersionConstraint) dependencies[j].getUserObject(); 103 Version actualVersion = (Version) dependencies[j].getResolvedVersionId(); 104 BundleDescription supplier = state.getBundle(constraint.getName(), actualVersion); 105 state.resolveConstraint(constraint, actualVersion, supplier); 106 } 107 } 108 109 public void bundleAdded(BundleDescription bundle) { 110 if (dependencies == null) 111 return; 112 ResolverHelper.add(bundle, dependencies); 113 } 114 115 public void bundleRemoved(BundleDescription bundle) { 116 if (dependencies == null) 117 return; 118 ResolverHelper.remove(bundle, dependencies); 119 } 120 121 public void bundleUpdated(BundleDescription newDescription, BundleDescription existingDescription) { 122 if (dependencies == null) 123 return; 124 ResolverHelper.update(newDescription, existingDescription, dependencies); 125 } 126 127 public State getState() { 128 return state; 129 } 130 131 public void flush() { 132 dependencies = null; 133 } 134 135 139 private boolean resolvePackages() { 140 141 Map availablePackages; 142 boolean success; 143 int tries = 0; 144 do { 145 tries++; 146 success = true; 147 BundleDescription[] initialBundles = state.getResolvedBundles(); 148 availablePackages = new HashMap(11); 149 150 for (int i = 0; i < initialBundles.length; i++) { 151 PackageSpecification[] required = initialBundles[i].getPackages(); 152 for (int j = 0; j < required.length; j++) 153 if (required[j].isExported()) { 156 Version toExport = required[j].getVersionRange().getMinimum(); 157 PackageSpecification existing = (PackageSpecification) availablePackages.get(required[j].getName()); 158 Version existingVersion = existing == null ? null : existing.getVersionRange().getMinimum(); 159 if (existingVersion == null || (toExport != null && toExport.isGreaterThan(existingVersion))) 160 availablePackages.put(required[j].getName(), required[j]); 161 } 162 } 163 164 for (int i = 0; i < initialBundles.length; i++) { 165 PackageSpecification[] required = initialBundles[i].getPackages(); 166 for (int j = 0; j < required.length; j++) { 167 PackageSpecification exported = (PackageSpecification) availablePackages.get(required[j].getName()); 168 Version exportedVersion = exported == null ? null : exported.getVersionRange().getMinimum(); 169 if (exported == null || !required[j].isSatisfiedBy(exportedVersion)) { 170 unresolveRequirementChain(initialBundles[i]); 171 success = false; 172 break; 174 } 175 } 176 } 177 } while (!success); 178 179 BundleDescription[] resolvedBundles = state.getResolvedBundles(); 180 for (int i = 0; i < resolvedBundles.length; i++) { 181 PackageSpecification[] required = resolvedBundles[i].getPackages(); 182 for (int j = 0; j < required.length; j++) { 183 PackageSpecification exported = (PackageSpecification) availablePackages.get(required[j].getName()); 184 state.resolveConstraint(required[j], exported.getVersionRange().getMinimum(), exported.getBundle()); 185 } 186 } 187 188 return tries > 1; 189 } 190 191 194 private void unresolveRequirementChain(BundleDescription bundle) { 195 if (!bundle.isResolved()) 196 return; 197 state.resolveBundle(bundle, Bundle.INSTALLED); 198 if (bundle.getSymbolicName() == null) 199 return; 200 ElementSet bundleElementSet = dependencies.getElementSet(bundle.getSymbolicName()); 201 Collection requiring = bundleElementSet.getRequiringElements(bundle.getVersion()); 202 for (Iterator requiringIter = requiring.iterator(); requiringIter.hasNext();) { 203 Element requiringElement = (Element) requiringIter.next(); 204 BundleDescription requiringBundle = state.getBundle((String ) requiringElement.getId(), (Version) requiringElement.getVersionId()); 205 if (requiringBundle != null) 206 unresolveRequirementChain(requiringBundle); 207 } 208 } 209 210 private void unresolveBundle(BundleDescription bundle) { 211 if (!bundle.isResolved()) 212 return; 213 if (dependencies != null) 214 ResolverHelper.unresolve(bundle, dependencies); 215 } 216 } | Popular Tags |