1 26 27 package com.opensugar.cube.packageAdmin; 28 29 import com.opensugar.cube.AbstractCube; 30 import com.opensugar.cube.BundleClassLoader; 31 import com.opensugar.cube.BundleImpl; 32 import com.opensugar.cube.NamedPropertySet; 33 34 import org.osgi.framework.Bundle; 35 import org.osgi.framework.FrameworkEvent; 36 import org.osgi.framework.Constants; 37 import org.osgi.service.packageadmin.PackageAdmin; 38 import org.osgi.service.packageadmin.ExportedPackage; 39 40 import java.util.Hashtable; 41 import java.util.Vector; 42 import java.util.Enumeration; 43 import java.net.URL; 44 45 public class PackageAdminImpl implements PackageAdmin { 46 47 private AbstractCube cube; 48 49 private Hashtable exportedPackages; 52 private Hashtable proposedExports; private Hashtable requiredImports; 57 public PackageAdminImpl( AbstractCube cube ) { 58 this.cube = cube; 59 60 exportedPackages = new Hashtable(); 61 proposedExports = new Hashtable(); 62 requiredImports = new Hashtable(); 63 } 64 65 71 public ExportedPackage getExportedPackage( String packageName ) { 72 return (ExportedPackage)exportedPackages.get( packageName ); 73 } 74 75 public ExportedPackage[] getExportedPackages( Bundle bundle ) { 76 Hashtable clone = (Hashtable)exportedPackages.clone(); 77 Enumeration enum = clone.elements(); 78 Vector vec = new Vector(); 79 ExportedPackage exportedPackage; 80 while ( enum.hasMoreElements() ) { 81 exportedPackage = (ExportedPackage)enum.nextElement(); 82 if ( bundle == null || bundle.getBundleId() == exportedPackage.getExportingBundle().getBundleId() ) { 83 vec.addElement( exportedPackage ); 84 } 85 } 86 ExportedPackage[] ret = new ExportedPackage[ vec.size() ]; 87 vec.copyInto( ret ); 88 return ret; 89 } 90 91 public void refreshPackages( Bundle[] bundles ) { 92 final Bundle[] bs = bundles; 93 ( new Thread( new Runnable() { 94 public void run() { 95 doRefreshPackages( bs ); 96 } 97 } ) ).start(); 98 } 99 100 101 107 public synchronized void exportPackage( Bundle exportingBundle, String packageName, String specificationVersion, BundleClassLoader classLoader ) { 114 getProposedExports( exportingBundle ).addElement( new PackageExport( packageName, specificationVersion, exportingBundle, classLoader ) ); 115 116 if ( exportingBundle.getBundleId() == 0 ) { 120 exportedPackages.put( packageName, new ExportedPackageImpl( packageName, specificationVersion, exportingBundle, classLoader ) ); 121 } 122 } 123 124 public synchronized void importPackage( Bundle importingBundle, String packageName, String specificationVersion ) { 130 getRequiredImports( importingBundle ).addElement( new PackageImport( importingBundle, packageName, specificationVersion ) ); 131 } 132 133 public synchronized void bundleUpdatedOrUninstalled( BundleImpl bundle ) { 137 Enumeration enum = exportedPackages.elements(); 140 ExportedPackageImpl exportedPackage; 141 while ( enum.hasMoreElements() ) { 142 exportedPackage = (ExportedPackageImpl)enum.nextElement(); 143 if ( bundle.getBundleId() == exportedPackage.getExportingBundle().getBundleId() ) { 144 exportedPackage.setRemovalPending(); 145 } 148 else { 149 exportedPackage.removeImportingBundle( bundle ); 151 } 152 } 153 154 proposedExports.remove( bundle ); 156 requiredImports.remove( bundle ); 157 } 158 159 160 166 public Class loadClass( Bundle requestingBundle, String fullyQualifiedClassName ) throws ClassNotFoundException { 167 171 int n = fullyQualifiedClassName.lastIndexOf( "." ); 173 if ( n == -1 ) { 174 throw new IllegalArgumentException( "Cannot get a class that does not belong to a package: " + fullyQualifiedClassName ); 175 } 176 String packageName = fullyQualifiedClassName.substring( 0, n ); 177 178 ExportedPackageImpl exportedPackage = (ExportedPackageImpl)exportedPackages.get( packageName ); 180 if ( exportedPackage != null ) { 181 if ( packageName.equals( "java.security" ) ) { 185 exportedPackage.loadClass( fullyQualifiedClassName ); 186 } 187 else if ( exportedPackage.isImportingBundle( requestingBundle ) ) { 188 return exportedPackage.loadClass( fullyQualifiedClassName ); 189 } 190 } 191 192 throw new ClassNotFoundException( fullyQualifiedClassName ); 195 } 196 197 public synchronized URL getResource( Bundle requestingBundle, String name ) { 198 202 int n = name.lastIndexOf( "/" ); 204 if ( n == -1 ) { 205 return null; 206 } 207 String packageName = name.substring( 0, n ); 208 packageName = packageName.replace( '/', '.' ); 209 ExportedPackageImpl exportedPackage = (ExportedPackageImpl)exportedPackages.get( packageName ); 211 if ( exportedPackage != null && exportedPackage.isImportingBundle( requestingBundle ) ) { 212 return exportedPackage.getResource( name ); 213 } 214 215 return null; 218 } 219 220 221 227 public synchronized PackageImport[] getUnsatisfiedImports( Bundle bundle ) { 228 Vector unsatisfied = (Vector)getRequiredImports( bundle ).clone(); 229 Vector satisfied = new Vector(); 230 for ( int i = 0; i < unsatisfied.size(); i++ ) { 231 PackageImport required = (PackageImport)unsatisfied.elementAt( i ); 232 ExportedPackageImpl available = (ExportedPackageImpl)exportedPackages.get( required.getName() ); 233 if ( available != null ) { 234 GoRoCoVersion requiredVersion = new GoRoCoVersion( required.getSpecificationVersion() ); 235 GoRoCoVersion availableVersion = new GoRoCoVersion( available.getSpecificationVersion() ); 236 if ( availableVersion.compareTo( requiredVersion ) >= 0 ) { 240 satisfied.addElement( required ); 241 } 242 } 243 } 244 for ( int i = 0; i < satisfied.size(); i++ ) { 245 unsatisfied.removeElement( satisfied.elementAt( i ) ); 246 } 247 248 Vector implicit = new Vector(); 253 Vector proposed = getProposedExports( bundle ); 254 for ( int i = 0; i < unsatisfied.size(); i++ ) { 255 PackageImport pack1 = (PackageImport)unsatisfied.elementAt( i ); 256 if ( exportedPackages.get( pack1.getName() ) == null ) { 257 for ( int j = 0; j < proposed.size(); j++ ) { 258 PackageExport pack2 = (PackageExport)proposed.elementAt( j ); 259 if ( pack2 != null && pack2.getName().equals( pack1.getName() ) ) { 260 GoRoCoVersion v1 = new GoRoCoVersion( pack2.getSpecificationVersion() ); 261 GoRoCoVersion v2 = new GoRoCoVersion( pack1.getSpecificationVersion() ); 262 if ( v1.compareTo( v2 ) >= 0 ) { 266 implicit.addElement( pack1 ); 267 } 268 } 269 } 270 } 271 } 272 for ( int i = 0; i < implicit.size(); i++ ) { 273 unsatisfied.removeElement( implicit.elementAt( i ) ); 274 } 275 276 PackageImport[] ret = new PackageImport[ unsatisfied.size() ]; 277 unsatisfied.copyInto( ret ); 278 return ret; 279 } 280 281 287 public synchronized void doRefreshPackages( Bundle[] bundles ) { 292 BundleImpl[] graph = buildGraph( bundles ); 300 Vector activeBundles = new Vector(); 307 for ( int i = 0; i < graph.length; i++ ) { 308 if ( graph[ i ].getState() == graph[ i ].ACTIVE || graph[ i ].getState() == graph[ i ].STARTING ) { 311 activeBundles.addElement( graph[ i ] ); 312 } 313 314 if ( graph[ i ].getState() != graph[ i ].UNINSTALLED ) { 319 try { 320 graph[ i ].stop( true ); 321 } 322 catch ( Throwable e ) { 323 cube.fireFrameworkEvent( FrameworkEvent.ERROR, cube.getBundle( 0 ), e ); 326 } 327 } 328 329 unresolveBundle( (BundleImpl)graph[ i ] ); 338 } 339 340 cube.wipeUninstalledBundles( graph ); 343 344 resolveBundles(); 345 346 Bundle bundle; 354 for ( int i = 0; i < activeBundles.size(); i++ ) { 355 bundle = (Bundle)activeBundles.elementAt( i ); 356 if ( bundle.getState() == bundle.RESOLVED ) { 357 try { 358 bundle.start(); 359 } 360 catch ( Throwable e ) { 361 cube.fireFrameworkEvent( FrameworkEvent.ERROR, cube.getBundle( 0 ), e ); 364 } 365 } 366 } 367 } 368 369 private BundleImpl[] buildGraph( Bundle[] bundles ) { 377 Vector graph = new Vector(); 379 if ( bundles != null ) { 380 for ( int i = 0; i < bundles.length; i++ ) { 382 graph.addElement( bundles[ i ] ); 383 } 384 } 385 else { 386 Enumeration enum = exportedPackages.elements(); 393 ExportedPackageImpl exportedPackage; 394 while ( enum.hasMoreElements() ) { 395 exportedPackage = (ExportedPackageImpl)enum.nextElement(); 396 if ( exportedPackage.isRemovalPending() && graph.indexOf( exportedPackage.getExportingBundle() ) == -1 ) { 397 graph.addElement( exportedPackage.getExportingBundle() ); 398 } 399 } 400 Bundle[] all = cube.getBundles(); 404 for ( int i = 0; i < all.length; i++ ) { 405 if ( all[ i ].getState() == all[ i ].UNINSTALLED && graph.indexOf( all[ i ] ) == -1 ) { 406 graph.addElement( all[ i ] ); 407 } 408 } 409 } 415 416 boolean done = false; 418 while ( !done ) { 419 Vector bundlesToAdd = new Vector(); 422 for ( int i = 0; i < graph.size(); i++ ) { 423 Vector exports = getProposedExports( (Bundle)graph.elementAt( i ) ); 424 for ( int j = 0; j < exports.size(); j++ ) { 425 PackageExport export = (PackageExport)exports.elementAt( j ); 426 Enumeration enum = requiredImports.keys(); 427 while ( enum.hasMoreElements() ) { 428 Bundle bundle = (Bundle)enum.nextElement(); 429 Vector imports = getRequiredImports( bundle ); 430 for ( int k = 0; k < imports.size(); k++ ) { 431 PackageImport packageImport = (PackageImport)imports.elementAt( k ); 432 if ( packageImport.getName().equals( export.getName() ) && graph.indexOf( bundle ) == -1 && bundlesToAdd.indexOf( bundle ) == -1 ) { 433 bundlesToAdd.addElement( bundle ); 434 } 435 } 436 } 437 } 438 } 439 440 if ( bundlesToAdd.size() > 0 ) { 441 for ( int i = 0; i < bundlesToAdd.size(); i++ ) { 442 graph.addElement( bundlesToAdd.elementAt( i ) ); 443 } 444 } 445 else { 446 done = true; 447 } 448 } 449 450 BundleImpl[] ret = new BundleImpl[ graph.size() ]; 451 graph.copyInto( ret ); 452 return ret; 453 } 454 455 private synchronized void unresolveBundle( BundleImpl bundle ) { 456 Enumeration enum = exportedPackages.elements(); 459 while ( enum.hasMoreElements() ) { 460 ExportedPackageImpl exportedPackage = (ExportedPackageImpl)enum.nextElement(); 461 if ( exportedPackage.getExportingBundle().getBundleId() == bundle.getBundleId() ) { 462 exportedPackage.setStale(); 466 exportedPackages.remove( exportedPackage.getName() ); 467 } 468 else { 469 exportedPackage.removeImportingBundle( bundle ); 477 } 478 } 479 480 if ( bundle.getState() == bundle.RESOLVED ) { 481 bundle.setInstalled(); 482 } 483 } 484 485 491 private Vector getProposedExports( Bundle bundle ) { 492 if ( proposedExports.get( bundle ) == null ) { 493 proposedExports.put( bundle, new Vector() ); 494 } 495 return (Vector)proposedExports.get( bundle ); 496 } 497 498 private Vector getRequiredImports( Bundle bundle ) { 499 if ( requiredImports.get( bundle ) == null ) { 500 requiredImports.put( bundle, new Vector() ); 501 } 502 return (Vector)requiredImports.get( bundle ); 503 } 504 505 public synchronized void resolveBundles() { 522 Bundle[] bundles = cube.getBundles(); 524 Vector potentiallyResolvedBundles = new Vector(); 525 for ( int i = 0; i < bundles.length; i++ ) { 526 if ( bundles[ i ].getState() == bundles[ i ].INSTALLED ) { 527 potentiallyResolvedBundles.addElement( bundles[ i ] ); 528 } 529 } 530 531 boolean done = false; 532 Vector notResolvable; 533 while ( !done ) { 534 notResolvable = simulatePackageExportsFor( potentiallyResolvedBundles ); 535 if ( notResolvable.size() == 0 ) { 536 done = true; 537 } 538 else { 539 for ( int i = 0; i < notResolvable.size(); i++ ) { 540 potentiallyResolvedBundles.removeElement( notResolvable.elementAt( i ) ); 541 } 542 } 543 } 544 545 556 Hashtable toExport = new Hashtable(); 562 for ( int i = 0; i < potentiallyResolvedBundles.size(); i++ ) { 563 Bundle bundle = (Bundle)potentiallyResolvedBundles.elementAt( i ); 564 Vector proposedExports = getProposedExports( bundle ); 565 for ( int j = 0; j < proposedExports.size(); j++ ) { 566 PackageExport proposedExport = (PackageExport)proposedExports.elementAt( j ); 567 ExportedPackageImpl alreadyExported = (ExportedPackageImpl)exportedPackages.get( proposedExport.getName() ); 568 boolean export = false; 569 if ( alreadyExported != null ) { 570 if ( !alreadyExported.isOpen() ) { 571 GoRoCoVersion proposedVersion = new GoRoCoVersion( proposedExport.getSpecificationVersion() ); 574 GoRoCoVersion alreadyExportedVersion = new GoRoCoVersion( alreadyExported.getSpecificationVersion() ); 575 if ( alreadyExportedVersion.isUndefined() && !proposedVersion.isUndefined() ) { 576 export = true; 577 } 578 else { 579 if ( alreadyExportedVersion.compareTo( proposedVersion ) < 0 ) { 584 export = true; 585 } 586 } 587 } 588 } 589 else { 590 PackageExport alreadyInList = (PackageExport)toExport.get( proposedExport.getName() ); 591 if ( alreadyInList == null ) { 592 export = true; 593 } 594 else { 595 GoRoCoVersion version1 = new GoRoCoVersion( alreadyInList.getSpecificationVersion() ); 598 GoRoCoVersion version2 = new GoRoCoVersion( proposedExport.getSpecificationVersion() ); 599 if ( version1.compareTo( version2 ) < 0 ) { 603 export = true; 604 } 605 } 606 } 607 if ( export ) { 608 toExport.put( proposedExport.getName(), proposedExport ); 609 } 610 } 611 } 612 Enumeration enum = toExport.elements(); 613 while ( enum.hasMoreElements() ) { 614 PackageExport packageExport = (PackageExport)enum.nextElement(); 616 ExportedPackageImpl exportedPackage = new ExportedPackageImpl( packageExport.getName(), packageExport.getSpecificationVersion(), packageExport.getExportingBundle(), packageExport.getClassLoader() ); 617 ExportedPackageImpl unopenedExistingExportBeingUpgraded = (ExportedPackageImpl)exportedPackages.get( packageExport.getName() ); 618 if ( unopenedExistingExportBeingUpgraded != null ) { 619 Bundle[] importingBundles = unopenedExistingExportBeingUpgraded.getImportingBundles(); 620 for ( int i = 0; i < importingBundles.length; i++ ) { 621 exportedPackage.addImportingBundle( importingBundles[ i ] ); 622 } 623 unopenedExistingExportBeingUpgraded.setStale(); 624 } 625 exportedPackages.put( packageExport.getName(), exportedPackage ); 626 } 627 628 for ( int i = 0; i < potentiallyResolvedBundles.size(); i++ ) { 633 BundleImpl bundle = (BundleImpl)potentiallyResolvedBundles.elementAt( i ); 634 Vector requiredImports = getRequiredImports( bundle ); 635 for ( int j = 0; j < requiredImports.size(); j++ ) { 636 PackageImport requiredImport = (PackageImport)requiredImports.elementAt( j ); 637 ( (ExportedPackageImpl)exportedPackages.get( requiredImport.getName() ) ).addImportingBundle( bundle ); 639 } 640 bundle.setResolved(); 641 } 642 } 643 644 private Vector simulatePackageExportsFor( Vector bundles ) { 657 Hashtable potentialExports = new Hashtable(); 659 for ( int i = 0; i < bundles.size(); i++ ) { 660 Bundle bundle = (Bundle)bundles.elementAt( i ); 661 Vector proposedExports = getProposedExports( bundle ); 662 for ( int j = 0; j < proposedExports.size(); j++ ) { 663 PackageExport proposedExport = (PackageExport)proposedExports.elementAt( j ); 664 ExportedPackageImpl alreadyExported = (ExportedPackageImpl)exportedPackages.get( proposedExport.getName() ); 665 boolean addToPotentialExports = false; 666 if ( alreadyExported != null ) { 667 if ( !alreadyExported.isOpen() ) { 668 GoRoCoVersion proposedVersion = new GoRoCoVersion( proposedExport.getSpecificationVersion() ); 671 GoRoCoVersion alreadyExportedVersion = new GoRoCoVersion( alreadyExported.getSpecificationVersion() ); 672 if ( alreadyExportedVersion.isUndefined() && !proposedVersion.isUndefined() ) { 673 addToPotentialExports = true; 674 } 675 else { 676 if ( alreadyExportedVersion.compareTo( proposedVersion ) < 0 ) { 681 addToPotentialExports = true; 682 } 683 } 684 } 685 } 686 else { 687 PackageExport alreadyInList = (PackageExport)potentialExports.get( proposedExport.getName() ); 688 if ( alreadyInList == null ) { 689 addToPotentialExports = true; 690 } 691 else { 692 GoRoCoVersion version1 = new GoRoCoVersion( alreadyInList.getSpecificationVersion() ); 695 GoRoCoVersion version2 = new GoRoCoVersion( proposedExport.getSpecificationVersion() ); 696 if ( version1.compareTo( version2 ) < 0 ) { 700 addToPotentialExports = true; 701 } 702 } 703 } 704 if ( addToPotentialExports ) { 705 potentialExports.put( proposedExport.getName(), proposedExport ); 706 } 707 } 708 } 709 Hashtable simulatedExportedPackages = (Hashtable)exportedPackages.clone(); 722 Enumeration enum = potentialExports.elements(); 723 while ( enum.hasMoreElements() ) { 724 PackageExport potentialExport = (PackageExport)enum.nextElement(); 725 simulatedExportedPackages.put( potentialExport.getName(), potentialExport ); 726 } 727 728 Vector bundlesStillNotResolved = new Vector(); 731 for ( int i = 0; i < bundles.size(); i++ ) { 732 Bundle bundle = (Bundle)bundles.elementAt( i ); 733 Vector requiredImports = getRequiredImports( bundle ); 734 for ( int j = 0; j < requiredImports.size(); j++ ) { 735 PackageImport required = (PackageImport)requiredImports.elementAt( j ); 736 HasVersion available = (HasVersion)simulatedExportedPackages.get( required.getName() ); 737 if ( available == null ) { 738 bundlesStillNotResolved.addElement( bundle ); 740 break; 741 } 742 else { 743 GoRoCoVersion requiredVersion = new GoRoCoVersion( required.getSpecificationVersion() ); 744 GoRoCoVersion availableVersion = new GoRoCoVersion( available.getSpecificationVersion() ); 745 if ( availableVersion.compareTo( requiredVersion ) < 0 ) { 749 bundlesStillNotResolved.addElement( bundle ); 751 break; 752 } 753 } 754 } 755 } 756 757 return bundlesStillNotResolved; 760 } 761 762 } 763 | Popular Tags |