1 11 package org.eclipse.osgi.internal.resolver; 12 13 import java.io.IOException ; 14 import java.util.*; 15 import org.eclipse.osgi.framework.internal.core.Constants; 16 import org.eclipse.osgi.framework.util.KeyedElement; 17 import org.eclipse.osgi.service.resolver.*; 18 19 public class BundleDescriptionImpl extends BaseDescriptionImpl implements BundleDescription, KeyedElement { 20 static final String [] EMPTY_STRING = new String [0]; 21 static final ImportPackageSpecification[] EMPTY_IMPORTS = new ImportPackageSpecification[0]; 22 static final BundleSpecification[] EMPTY_BUNDLESPECS = new BundleSpecification[0]; 23 static final ExportPackageDescription[] EMPTY_EXPORTS = new ExportPackageDescription[0]; 24 static final BundleDescription[] EMPTY_BUNDLEDESCS = new BundleDescription[0]; 25 static final GenericSpecification[] EMPTY_GENERICSPECS = new GenericSpecification[0]; 26 static final GenericDescription[] EMPTY_GENERICDESCS = new GenericDescription[0]; 27 28 static final int RESOLVED = 0x01; 29 static final int SINGLETON = 0x02; 30 static final int REMOVAL_PENDING = 0x04; 31 static final int FULLY_LOADED = 0x08; 32 static final int LAZY_LOADED = 0x10; 33 static final int HAS_DYNAMICIMPORT = 0x20; 34 static final int ATTACH_FRAGMENTS = 0x40; 35 static final int DYNAMIC_FRAGMENTS = 0x80; 36 37 private int stateBits = FULLY_LOADED | ATTACH_FRAGMENTS | DYNAMIC_FRAGMENTS; 39 40 private long bundleId = -1; 41 private HostSpecification host; private StateImpl containingState; 43 44 private Object userObject; 45 private int lazyDataOffset = -1; 46 private int lazyDataSize = -1; 47 48 private ArrayList dependencies; 50 private ArrayList dependents; 51 52 private LazyData lazyData; 53 private int equinox_ee = -1; 54 55 public BundleDescriptionImpl() { 56 } 58 59 public long getBundleId() { 60 return bundleId; 61 } 62 63 public String getSymbolicName() { 64 return getName(); 65 } 66 67 public BundleDescription getSupplier() { 68 return this; 69 } 70 71 public String getLocation() { 72 fullyLoad(); 73 return lazyData.location; 74 } 75 76 public String getPlatformFilter() { 77 fullyLoad(); 78 return lazyData.platformFilter; 79 } 80 81 public String [] getExecutionEnvironments() { 82 fullyLoad(); 83 if (lazyData.executionEnvironments == null) 84 return EMPTY_STRING; 85 return lazyData.executionEnvironments; 86 } 87 88 public ImportPackageSpecification[] getImportPackages() { 89 fullyLoad(); 90 if (lazyData.importPackages == null) 91 return EMPTY_IMPORTS; 92 return lazyData.importPackages; 93 } 94 95 public BundleSpecification[] getRequiredBundles() { 96 fullyLoad(); 97 if (lazyData.requiredBundles == null) 98 return EMPTY_BUNDLESPECS; 99 return lazyData.requiredBundles; 100 } 101 102 public GenericSpecification[] getGenericRequires() { 103 fullyLoad(); 104 if (lazyData.genericRequires == null) 105 return EMPTY_GENERICSPECS; 106 return lazyData.genericRequires; 107 } 108 109 public GenericDescription[] getGenericCapabilities() { 110 fullyLoad(); 111 if (lazyData.genericCapabilities == null) 112 return EMPTY_GENERICDESCS; 113 return lazyData.genericCapabilities; 114 } 115 116 public ExportPackageDescription[] getExportPackages() { 117 fullyLoad(); 118 return lazyData.exportPackages == null ? EMPTY_EXPORTS : lazyData.exportPackages; 119 } 120 121 public boolean isResolved() { 122 return (stateBits & RESOLVED) != 0; 123 } 124 125 public State getContainingState() { 126 return containingState; 127 } 128 129 public BundleDescription[] getFragments() { 130 if (host != null) 131 return EMPTY_BUNDLEDESCS; 132 return containingState.getFragments(this); 133 } 134 135 public HostSpecification getHost() { 136 return host; 137 } 138 139 public boolean isSingleton() { 140 return (stateBits & SINGLETON) != 0; 141 } 142 143 public boolean isRemovalPending() { 144 return (stateBits & REMOVAL_PENDING) != 0; 145 } 146 147 public boolean hasDynamicImports() { 148 return (stateBits & HAS_DYNAMICIMPORT) != 0; 149 } 150 151 public boolean attachFragments() { 152 return (stateBits & ATTACH_FRAGMENTS) != 0; 153 } 154 155 public boolean dynamicFragments() { 156 return (stateBits & DYNAMIC_FRAGMENTS) != 0; 157 } 158 159 public ExportPackageDescription[] getSelectedExports() { 160 fullyLoad(); 161 if (lazyData.selectedExports == null) 162 return EMPTY_EXPORTS; 163 return lazyData.selectedExports; 164 } 165 166 public BundleDescription[] getResolvedRequires() { 167 fullyLoad(); 168 if (lazyData.resolvedRequires == null) 169 return EMPTY_BUNDLEDESCS; 170 return lazyData.resolvedRequires; 171 } 172 173 public ExportPackageDescription[] getResolvedImports() { 174 fullyLoad(); 175 if (lazyData.resolvedImports == null) 176 return EMPTY_EXPORTS; 177 return lazyData.resolvedImports; 178 } 179 180 protected void setBundleId(long bundleId) { 181 this.bundleId = bundleId; 182 } 183 184 protected void setSymbolicName(String symbolicName) { 185 setName(symbolicName); 186 } 187 188 protected void setLocation(String location) { 189 checkLazyData(); 190 lazyData.location = location; 191 } 192 193 protected void setPlatformFilter(String platformFilter) { 194 checkLazyData(); 195 lazyData.platformFilter = platformFilter; 196 } 197 198 protected void setExecutionEnvironments(String [] executionEnvironments) { 199 checkLazyData(); 200 lazyData.executionEnvironments = executionEnvironments; 201 } 202 203 protected void setExportPackages(ExportPackageDescription[] exportPackages) { 204 checkLazyData(); 205 lazyData.exportPackages = exportPackages; 206 if (exportPackages != null) { 207 for (int i = 0; i < exportPackages.length; i++) { 208 ((ExportPackageDescriptionImpl) exportPackages[i]).setExporter(this); 209 } 210 } 211 } 212 213 protected void setImportPackages(ImportPackageSpecification[] importPackages) { 214 checkLazyData(); 215 lazyData.importPackages = importPackages; 216 if (importPackages != null) { 217 for (int i = 0; i < importPackages.length; i++) { 218 if (Constants.OSGI_SYSTEM_BUNDLE.equals(importPackages[i].getBundleSymbolicName())) 219 ((ImportPackageSpecificationImpl) importPackages[i]).setBundleSymbolicName(Constants.getInternalSymbolicName()); 220 ((ImportPackageSpecificationImpl) importPackages[i]).setBundle(this); 221 if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(importPackages[i].getDirective(Constants.RESOLUTION_DIRECTIVE))) 222 stateBits |= HAS_DYNAMICIMPORT; 223 } 224 } 225 } 226 227 protected void setRequiredBundles(BundleSpecification[] requiredBundles) { 228 checkLazyData(); 229 lazyData.requiredBundles = requiredBundles; 230 if (requiredBundles != null) 231 for (int i = 0; i < requiredBundles.length; i++) { 232 if (Constants.OSGI_SYSTEM_BUNDLE.equals(requiredBundles[i].getName())) 233 ((VersionConstraintImpl) requiredBundles[i]).setName(Constants.getInternalSymbolicName()); 234 ((VersionConstraintImpl) requiredBundles[i]).setBundle(this); 235 } 236 } 237 238 protected void setGenericCapabilities(GenericDescription[] genericCapabilities) { 239 checkLazyData(); 240 lazyData.genericCapabilities = genericCapabilities; 241 if (genericCapabilities != null) 242 for (int i = 0; i < genericCapabilities.length; i++) 243 ((GenericDescriptionImpl) genericCapabilities[i]).setSupplier(this); 244 } 245 246 protected void setGenericRequires(GenericSpecification[] genericRequires) { 247 checkLazyData(); 248 lazyData.genericRequires = genericRequires; 249 if (genericRequires != null) 250 for (int i = 0; i < genericRequires.length; i++) 251 ((VersionConstraintImpl) genericRequires[i]).setBundle(this); 252 } 253 254 protected int getStateBits() { 255 return stateBits; 256 } 257 258 protected void setStateBit(int stateBit, boolean on) { 259 if (on) 260 stateBits |= stateBit; 261 else 262 stateBits &= ~stateBit; 263 } 264 265 protected void setContainingState(State value) { 266 containingState = (StateImpl) value; 267 if (containingState != null && containingState.getReader() != null) { 268 if (containingState.getReader().isLazyLoaded()) 269 stateBits |= LAZY_LOADED; 270 else 271 stateBits &= ~LAZY_LOADED; 272 } else { 273 stateBits &= ~LAZY_LOADED; 274 } 275 } 276 277 protected void setHost(HostSpecification host) { 278 this.host = host; 279 if (host != null) { 280 if (Constants.OSGI_SYSTEM_BUNDLE.equals(host.getName())) 281 ((VersionConstraintImpl) host).setName(Constants.getInternalSymbolicName()); 282 ((VersionConstraintImpl) host).setBundle(this); 283 } 284 } 285 286 protected void setLazyLoaded(boolean lazyLoad) { 287 fullyLoad(); 288 if (lazyLoad) 289 stateBits |= LAZY_LOADED; 290 else 291 stateBits &= ~LAZY_LOADED; 292 } 293 294 protected void setSelectedExports(ExportPackageDescription[] selectedExports) { 295 checkLazyData(); 296 lazyData.selectedExports = selectedExports; 297 if (selectedExports != null) { 298 for (int i = 0; i < selectedExports.length; i++) { 299 ((ExportPackageDescriptionImpl) selectedExports[i]).setExporter(this); 300 } 301 } 302 } 303 304 protected void setResolvedImports(ExportPackageDescription[] resolvedImports) { 305 checkLazyData(); 306 lazyData.resolvedImports = resolvedImports; 307 } 308 309 protected void setResolvedRequires(BundleDescription[] resolvedRequires) { 310 checkLazyData(); 311 lazyData.resolvedRequires = resolvedRequires; 312 } 313 314 public String toString() { 315 if (getSymbolicName() == null) 316 return "[" + getBundleId() + "]"; return getSymbolicName() + "_" + getVersion(); } 319 320 public Object getKey() { 321 return new Long (bundleId); 322 } 323 324 public boolean compare(KeyedElement other) { 325 if (!(other instanceof BundleDescriptionImpl)) 326 return false; 327 BundleDescriptionImpl otherBundleDescription = (BundleDescriptionImpl) other; 328 return bundleId == otherBundleDescription.bundleId; 329 } 330 331 public int getKeyHashCode() { 332 return (int) (bundleId % Integer.MAX_VALUE); 333 } 334 335 342 343 protected synchronized void removeDependencies() { 344 if (dependencies == null) 345 return; 346 Iterator iter = dependencies.iterator(); 347 while (iter.hasNext()) { 348 ((BundleDescriptionImpl) iter.next()).removeDependent(this); 349 } 350 dependencies = null; 351 } 352 353 protected void addDependencies(BaseDescription[] newDependencies, boolean checkDups) { 354 if (newDependencies == null) 355 return; 356 if (!checkDups && dependencies == null) 357 dependencies = new ArrayList(newDependencies.length); 358 for (int i = 0; i < newDependencies.length; i++) { 359 addDependency((BaseDescriptionImpl) newDependencies[i], checkDups); 360 } 361 } 362 363 protected synchronized void addDependency(BaseDescriptionImpl dependency, boolean checkDups) { 364 BundleDescriptionImpl bundle = (BundleDescriptionImpl) dependency.getSupplier(); 365 if (bundle == this) 366 return; 367 if (dependencies == null) 368 dependencies = new ArrayList(10); 369 if (!checkDups || !dependencies.contains(bundle)) { 370 bundle.addDependent(this); 371 dependencies.add(bundle); 372 } 373 } 374 375 379 synchronized List getBundleDependencies() { 380 if (dependencies == null) 381 return new ArrayList(0); 382 ArrayList required = new ArrayList(dependencies.size()); 383 for (Iterator iter = dependencies.iterator(); iter.hasNext();) { 384 Object dep = iter.next(); 385 if (dep != this && dep instanceof BundleDescription && ((BundleDescription) dep).getHost() == null) 386 required.add(dep); 387 } 388 return required; 389 } 390 391 public Object getUserObject() { 392 return userObject; 393 } 394 395 public void setUserObject(Object userObject) { 396 this.userObject = userObject; 397 } 398 399 protected synchronized void addDependent(BundleDescription dependent) { 400 if (dependents == null) 401 dependents = new ArrayList(10); 402 dependents.add(dependent); 404 } 405 406 protected synchronized void removeDependent(BundleDescription dependent) { 407 if (dependents == null) 408 return; 409 dependents.remove(dependent); 410 } 411 412 public synchronized BundleDescription[] getDependents() { 413 if (dependents == null) 414 return EMPTY_BUNDLEDESCS; 415 return (BundleDescription[]) dependents.toArray(new BundleDescription[dependents.size()]); 416 } 417 418 void setFullyLoaded(boolean fullyLoaded) { 419 if (fullyLoaded) { 420 stateBits |= FULLY_LOADED; 421 } else { 422 stateBits &= ~FULLY_LOADED; 423 } 424 } 425 426 boolean isFullyLoaded() { 427 return (stateBits & FULLY_LOADED) != 0; 428 } 429 430 void setLazyDataOffset(int lazyDataOffset) { 431 this.lazyDataOffset = lazyDataOffset; 432 } 433 434 int getLazyDataOffset() { 435 return this.lazyDataOffset; 436 } 437 438 void setLazyDataSize(int lazyDataSize) { 439 this.lazyDataSize = lazyDataSize; 440 } 441 442 int getLazyDataSize() { 443 return this.lazyDataSize; 444 } 445 446 private void fullyLoad() { 447 if ((stateBits & LAZY_LOADED) == 0) 448 return; 449 StateReader reader = containingState.getReader(); 450 synchronized (reader) { 451 if (isFullyLoaded()) { 452 reader.setAccessedFlag(true); return; 454 } 455 try { 456 reader.fullyLoad(this); 457 } catch (IOException e) { 458 throw new RuntimeException (e.getMessage()); } 460 } 461 } 462 463 synchronized void addDynamicResolvedImport(ExportPackageDescriptionImpl result) { 464 addDependency(result, true); 466 checkLazyData(); 468 if (lazyData.resolvedImports == null) { 469 lazyData.resolvedImports = new ExportPackageDescription[] {result}; 470 return; 471 } 472 ExportPackageDescription[] newImports = new ExportPackageDescription[lazyData.resolvedImports.length + 1]; 473 System.arraycopy(lazyData.resolvedImports, 0, newImports, 0, lazyData.resolvedImports.length); 474 newImports[newImports.length - 1] = result; 475 lazyData.resolvedImports = newImports; 476 setLazyLoaded(false); 477 } 478 479 482 void unload() { 483 if ((stateBits & LAZY_LOADED) == 0) 484 return; 485 if (!isFullyLoaded()) 486 return; 487 setFullyLoaded(false); 488 LazyData tempData = lazyData; 489 lazyData = null; 490 if (tempData == null || tempData.selectedExports == null) 491 return; 492 for (int i = 0; i < tempData.selectedExports.length; i++) 493 containingState.getReader().objectTable.remove(new Integer (((ExportPackageDescriptionImpl) tempData.selectedExports[i]).getTableIndex())); 494 } 495 496 void setDynamicStamps(HashMap dynamicStamps) { 497 lazyData.dynamicStamps = dynamicStamps; 498 } 499 500 void setDynamicStamp(String requestedPackage, Long timestamp) { 501 checkLazyData(); 502 if (lazyData.dynamicStamps == null) { 503 if (timestamp == null) 504 return; 505 lazyData.dynamicStamps = new HashMap(); 506 } 507 if (timestamp == null) 508 lazyData.dynamicStamps.remove(requestedPackage); 509 else 510 lazyData.dynamicStamps.put(requestedPackage, timestamp); 511 } 512 513 long getDynamicStamp(String requestedPackage) { 514 fullyLoad(); 515 Long stamp = lazyData.dynamicStamps == null ? null : (Long ) lazyData.dynamicStamps.get(requestedPackage); 516 return stamp == null ? 0 : stamp.longValue(); 517 } 518 519 HashMap getDynamicStamps() { 520 fullyLoad(); 521 return lazyData.dynamicStamps; 522 } 523 524 public void setEquinoxEE(int equinox_ee) { 525 this.equinox_ee = equinox_ee; 526 } 527 528 public int getEquinoxEE() { 529 return equinox_ee; 530 } 531 532 private void checkLazyData() { 533 if (lazyData == null) 534 lazyData = new LazyData(); 535 } 536 537 private final class LazyData { 538 String location; 539 String platformFilter; 540 541 BundleSpecification[] requiredBundles; 542 ExportPackageDescription[] exportPackages; 543 ImportPackageSpecification[] importPackages; 544 GenericDescription[] genericCapabilities; 545 GenericSpecification[] genericRequires; 546 547 ExportPackageDescription[] selectedExports; 548 BundleDescription[] resolvedRequires; 549 ExportPackageDescription[] resolvedImports; 550 551 String [] executionEnvironments; 552 553 HashMap dynamicStamps; 554 } 555 } 556 | Popular Tags |