1 26 27 package com.opensugar.cube; 28 29 import com.opensugar.cube.java2.PackageHelper; 30 import com.opensugar.cube.packageAdmin.PackageAdminImpl; 31 import com.opensugar.cube.packageAdmin.PackageImport; 32 import com.opensugar.cube.serviceRegistry.ServiceRegistry; 33 import com.opensugar.cube.serviceRegistry.ServiceRegistryException; 34 import com.opensugar.cube.ldap.LDAPFilter; 35 36 import org.osgi.framework.Bundle; 37 import org.osgi.framework.BundleException; 38 import org.osgi.framework.FrameworkEvent; 39 import org.osgi.framework.ServiceEvent; 40 import org.osgi.framework.BundleEvent; 41 import org.osgi.framework.FrameworkListener; 42 import org.osgi.framework.ServiceListener; 43 import org.osgi.framework.BundleListener; 44 import org.osgi.framework.SynchronousBundleListener; 45 import org.osgi.framework.ServiceReference; 46 import org.osgi.framework.InvalidSyntaxException; 47 import org.osgi.framework.Constants; 48 import org.osgi.framework.ServicePermission; 49 import org.osgi.service.permissionadmin.PermissionAdmin; 50 51 import java.io.File; 52 import java.io.InputStream; 53 import java.io.FileOutputStream; 54 import java.io.FileInputStream; 55 import java.io.IOException; 56 import java.net.URL; 57 import java.util.Hashtable; 58 import java.util.Enumeration; 59 import java.util.Vector; 60 import java.util.Locale; 61 import java.util.Observer; 62 63 public abstract class AbstractCube { 68 69 public static final String VERSION = "2.1.3"; 70 public static final String VENDOR = "Opensugar S.A."; 71 public static final String OSGI_RELEASE = "2"; 72 73 private static final String SYSTEM_PROPERTY_CUBE_VERSION = "com.opensugar.cube.version"; 74 private static final String SYSTEM_PROPERTY_CUBE_DIR = "com.opensugar.cube.dir"; 75 private static final String SYSTEM_PROPERTY_SYSTEM_BUNDLE_JAR_FILE = "com.opensugar.cube.systemBundleJarFile"; 77 private static final String SYSTEM_PROPERTY_CUBE_STARTED_FLAG_FILE = "com.opensugar.cube.startedFlagFile"; 78 79 private static final String FLASH_URL_FILE = "flash.url"; 80 81 private static final String defaultCubeDir = "osc/bs"; 82 private static final String defaultPermanentStorageDir = "osc/.opensugar"; 83 private static final String defaultSystemBundleJarFile = "systemBundle.jar"; 84 85 86 protected static final String bundleDirNameBase = "b"; 87 protected static final String bundleJarNameBase = "bundle"; 88 protected static final String bundleJarNameExtension = ".jar"; 89 protected static final String bundleLocationFileName = "location"; 90 protected static final String bundleUninstalledFlagFileName = "uninstalled.flag"; 91 protected static final String bundleStartedFlagFileName = "started.flag"; 92 protected static final String bundleInnerFilesDirName = "inner"; 93 protected static final String bundleDataDirName = "data"; 94 protected static final String bundleIdFileName = ".bid"; 95 96 private int reasonableTimeToWait = 5000; 100 101 private Hashtable id_bundle; 103 private PackageAdminImpl packageAdmin; 105 private ServiceRegistry serviceRegistry; 107 108 private ServiceListeners serviceListeners; 110 private BundleListeners bundleListeners; 112 private FrameworkListeners frameworkListeners; 114 private boolean handlingEvents = false; 116 117 private long largestBundleId = -1; 119 120 private Hashtable bundleInnerFileDirectories; 122 123 private int state = Bundle.RESOLVED; 129 130 private File baseDirectory; 132 133 137 protected AbstractCube() { 138 this( null ); 139 } 140 141 protected AbstractCube( File baseDirectory ) { 142 this.baseDirectory = baseDirectory; 144 145 System.out.println( "Opensugar cube " + VERSION ); 146 System.out.println( "Implements OSGi Service Platform, Specification Release " + OSGI_RELEASE ); 147 148 System.out.println( "Copyright (c) 2001, Opensugar S.A. All Rights Reserved." ); 149 System.out.println( "Opensugar is a Registered Trademark." ); 150 System.out.println( "" ); 151 152 System.getProperties().put( Constants.FRAMEWORK_VENDOR, getProperty( Constants.FRAMEWORK_VENDOR ) ); 154 System.getProperties().put( Constants.FRAMEWORK_VERSION, getProperty( Constants.FRAMEWORK_VERSION ) ); 155 156 System.getProperties().put( SYSTEM_PROPERTY_CUBE_VERSION, VERSION ); 158 159 165 initLog(); 166 } 167 168 public void flash( String flashURL ) throws IOException { 169 writeFile( new File( FLASH_URL_FILE ), flashURL ); 170 shutdown( false ); 171 } 172 173 public synchronized void startup( Observer progressListener ) { 174 176 deleteUninstalledBundleDirectories(); 178 deleteObsoleteBundleFiles(); 179 180 serviceListeners = new ServiceListeners(); 182 bundleListeners = new BundleListeners(); 183 frameworkListeners = new FrameworkListeners(); 184 handlingEvents = true; 185 186 state = Bundle.STARTING; 188 189 id_bundle = new Hashtable(); 191 192 bundleInnerFileDirectories = new Hashtable(); 194 195 packageAdmin = new PackageAdminImpl( this ); 197 198 serviceRegistry = new ServiceRegistry( this ); 200 201 getBaseDirectory().mkdirs(); 203 installSystemBundle( new File( System.getProperty( SYSTEM_PROPERTY_SYSTEM_BUNDLE_JAR_FILE, defaultSystemBundleJarFile ) ) ); 205 206 reinstallBundles(); 211 Bundle[] bs = getBundles(); 215 Vector v = new Vector(); 216 for ( int i = 0; i < bs.length; i++ ) { 217 v.addElement( bs[ i ] ); 218 } 219 v.removeElement( getBundle( (long)0 ) ); 220 bs = new Bundle[ v.size() ]; 221 v.copyInto( bs ); 222 packageAdmin.doRefreshPackages( bs ); 224 restartBundles( progressListener ); 229 230 state = Bundle.ACTIVE; 232 233 fireFrameworkStartedEvent(); 234 235 System.out.println( "Cube started" ); 236 237 String startedFlagFile = System.getProperty( SYSTEM_PROPERTY_CUBE_STARTED_FLAG_FILE ); 238 if ( startedFlagFile != null ) { 239 File file = new File( startedFlagFile ); 240 try { 241 writeFile( file, "" ); 242 } 243 catch ( IOException e ) { 244 log( LOG_ERROR, "Unable to create started flag file: " + file.getAbsolutePath(), e ); 245 } 246 } 247 } 248 249 public synchronized void shutdown( boolean exitJVM ) { 250 state = Bundle.STOPPING; 252 253 BundleImpl[] bundles = getBundles(); 258 for ( int i = bundles.length - 1; i >= 0; i-- ) { 259 if ( bundles[ i ].getBundleId() != 0 && bundles[ i ].getState() == bundles[ i ].ACTIVE ) { 260 try { 261 bundles[ i ].stop( true ); 262 } 263 catch( BundleException e ) { 264 fireFrameworkEvent( FrameworkEvent.ERROR, bundles[ i ], e ); 265 } 266 } 267 } 268 269 handlingEvents = false; 271 272 state = Bundle.RESOLVED; 273 274 System.out.println( "Cube stopped" ); 275 276 281 if ( exitJVM ) { 282 System.exit( 0 ); 283 } 284 } 285 286 protected abstract boolean enforcesPermissions(); 287 288 292 protected Bundle reinstallBundle( long id ) throws BundleException, IOException { 293 File jarFile = getCurrentBundleJarFile( id ); 294 String location = readStoredBundleLocation( id ); 295 return installBundle( id, location, jarFile ); 296 } 297 298 public Bundle installBundle( String location ) throws BundleException { 299 Util.checkNullParameter( location, getClass().getName(), "installBundle", "location" ); 300 return installBundle( location, null ); 301 } 302 303 protected Bundle installBundle( String location, InputStream in ) throws BundleException { 304 Util.checkNullParameter( location, getClass().getName(), "installBundle", "location" ); 305 306 try { 309 Bundle bundle = getBundle( location ); 310 if ( bundle != null && bundle.getState() != bundle.UNINSTALLED ) { 311 return getBundle( location ); 312 } 313 } 314 catch( IllegalArgumentException ignore ) { 315 } 317 318 long id = generateNewBundleId(); 320 321 File bundleDirectory = null; 334 while ( bundleDirectory == null ) { 335 bundleDirectory = createFreshBundleDirectory( id ); 337 if ( bundleDirectory.list() == null ) { 338 bundleDirectory = null; 339 id++; 340 } 341 } 342 343 try { 344 if ( in == null ) { 346 URL url = new URL( location ); 347 in = url.openStream(); 348 } 349 File bundleJar = getNewBundleJarFile( id ); 350 Util.transferData( in, new FileOutputStream( bundleJar ) ); 351 352 if ( id != 0 ) { 354 recordBundleLocation( id, location ); 355 } 356 357 return installBundle( id, location, bundleJar ); 358 } 359 catch( Exception e ) { 360 if ( !Util.recursiveFileDelete( bundleDirectory ) ) { 362 log( LOG_WARNING, "Unable to delete bundle directory after bundle installation failure" ); 363 } 364 365 if ( e instanceof BundleException ) { 366 throw (BundleException)e; 367 } 368 else { 369 throw new BundleException( "Unable to install bundle: " + location, e ); 370 } 371 } 372 } 373 374 private Bundle installSystemBundle( File bundleJar ) { 375 try { 376 if ( !bundleJar.exists() ) { 377 throw new BundleException( "System bundle jar file not found: " + bundleJar.getAbsolutePath() ); 378 } 379 return installBundle( (long)0, Constants.SYSTEM_BUNDLE_LOCATION, bundleJar ); 380 } 381 catch( BundleException e ) { 382 Throwable rootCause = e; 384 if ( e.getNestedException() != null ) { 385 rootCause = e.getNestedException(); 386 } 387 log( LOG_ERROR, "FATAL ERROR: System bundle could not be installed", rootCause ); 388 389 System.exit( 1 ); 390 return null; 391 } 392 } 393 394 private Bundle installBundle( long id, String location, File bundleJar ) throws BundleException { 399 if ( id > largestBundleId ) { 400 largestBundleId = id; 401 } 402 403 try { 404 BundleImpl bundle; 409 if ( id == 0 ) { 410 bundle = new SystemBundle( this, bundleJar ); 411 } 412 else { 413 bundle = new BundleImpl( this, id, location, bundleJar ); 414 } 415 416 fireBundleEvent( BundleEvent.INSTALLED, bundle ); 418 419 id_bundle.put( new Long( bundle.getBundleId() ), bundle ); 420 packageAdmin.resolveBundles(); 421 422 log( LOG_INFO, bundle.getLocation() + " installed (bundle id: " + bundle.getBundleId() + ")" ); 423 424 return bundle; 426 } 427 catch( Exception e ) { 428 e.printStackTrace(); 429 throw new BundleException( "Unable to install bundle: " + location, e ); 430 } 431 } 432 433 protected void bundleUninstalled( long id ) throws BundleException { 434 440 443 log( LOG_INFO, "Bundle " + id + " uninstalled" ); 444 } 445 446 public void wipeUninstalledBundles( Bundle[] bundlesToCheck ) { 447 if ( bundlesToCheck == null ) { 448 bundlesToCheck = getBundles(); 449 } 450 451 long bundleId; 452 for ( int i = 0; i < bundlesToCheck.length; i++ ) { 453 if ( bundlesToCheck[ i ].getState() == bundlesToCheck[ i ].UNINSTALLED ) { 454 bundleId = bundlesToCheck[ i ].getBundleId(); 455 id_bundle.remove( new Long( bundleId ) ); 456 deleteBundleDirectory( bundleId ); 457 } 458 } 459 } 460 461 463 protected String getProperty( String key ) { 464 Util.checkNullParameter( key, getClass().getName(), "getProperty", "key" ); 465 466 if ( key.equals( Constants.FRAMEWORK_LANGUAGE ) ) { 467 return Locale.getDefault().getLanguage(); 468 } 469 else if ( key.equals( Constants.FRAMEWORK_OS_NAME ) ) { 470 String osName = System.getProperty( "os.name" ); 471 if ( osName.equals( "OS/2" ) ) { 472 return "OS2"; 473 } 474 else if ( osName.equals( "procnto" ) ) { 475 return "QNX"; 476 } 477 else if ( osName.equals( "Win95" ) 478 || osName.equals( "Windows 95" ) ) { 479 return "Windows95"; 480 } 481 else if ( osName.equals( "Win98" ) 482 || osName.equals( "Windows 98" ) ) { 483 return "Windows98"; 484 } 485 else if ( osName.equals( "WinNT" ) 486 || osName.equals( "Windows NT" ) ) { 487 return "WindowsNT"; 488 } 489 else if ( osName.equals( "WinCE" ) 490 || osName.equals( "Windows CE" ) ) { 491 return "WindowsCE"; 492 } 493 else if ( osName.equals( "Win2000" ) 494 || osName.equals( "Windows 2000" ) ) { 495 return "Windows2000"; 496 } 497 else if ( osName.equals( "Mac OS X" ) ) { 498 return "MacOS"; 499 } 500 else { 501 return osName; 502 } 503 } 504 else if ( key.equals( Constants.FRAMEWORK_OS_VERSION ) ) { 505 return System.getProperty( "os.version" ); 506 } 507 else if ( key.equals( Constants.FRAMEWORK_PROCESSOR ) ) { 508 String processorName = System.getProperty( "os.arch" ); 509 if ( processorName.equals( "psc1k" ) ) { 510 return "Ignite"; 511 } 512 else if ( processorName.equals( "power" ) 513 || processorName.equals( "ppc" ) ) { 514 return "PowerPC"; 515 } 516 else if ( processorName.equals( "pentium" ) 517 || processorName.equals( "i386" ) 518 || processorName.equals( "i486" ) 519 || processorName.equals( "i586" ) 520 || processorName.equals( "i686" ) ) { 521 return "x86"; 522 } 523 else { 524 return processorName; 525 } 526 } 527 else if ( key.equals( Constants.FRAMEWORK_VENDOR ) ) { 528 return VENDOR; 529 } 530 else if ( key.equals( Constants.FRAMEWORK_VERSION ) ) { 531 return VERSION; 532 } 533 else { 534 return null; 535 } 536 } 537 538 protected long generateNewBundleId() { 539 541 long newBundleId = 0; 543 try { 544 newBundleId = Long.valueOf( readFile( getLastBundleIdFile() ) ).longValue() + 1; 545 } 546 catch ( Exception ignore ) { 547 551 long thousands = largestBundleId / 1000 + 1; 556 newBundleId = thousands * 1000 + 1; 557 } 558 559 while ( id_bundle.get( new Long( newBundleId ) ) != null ) { 560 newBundleId++; 561 } 562 563 largestBundleId = newBundleId; 564 try { 565 writeFile( getLastBundleIdFile(), "" + largestBundleId ); 566 } 567 catch ( IOException ignore ) {} 568 569 return newBundleId; 570 581 } 582 583 public BundleImpl getBundle( String location ) { 584 Enumeration bundles = id_bundle.elements(); 585 BundleImpl bundle; 586 while ( bundles.hasMoreElements() ) { 587 bundle = (BundleImpl)bundles.nextElement(); 588 if ( bundle.getLocation().equals( location ) ) { 589 return bundle; 590 } 591 } 592 throw new IllegalArgumentException( "Bundle with requested location does not exist: " + location ); 593 } 594 595 public BundleImpl getBundle( long id ) { 596 BundleImpl bundle = (BundleImpl)id_bundle.get( new Long( id ) ); 597 if ( bundle == null ) { 598 throw new IllegalArgumentException( "Bundle with requested id does not exist: " + id ); 599 } 600 return bundle; 601 } 602 603 public BundleImpl[] getBundles() { 604 Number[] ids = new Number[ id_bundle.size() ]; 605 Enumeration enum = id_bundle.keys(); 606 int i = 0; 607 while ( enum.hasMoreElements() ) { 608 ids[ i++ ] = (Long)enum.nextElement(); 609 } 610 ids = Util.sortNumbers( ids ); 611 612 BundleImpl[] bundles = new BundleImpl[ ids.length ]; 613 for ( i = 0; i < ids.length; i++ ) { 614 bundles[ i ] = (BundleImpl)id_bundle.get( ids[ i ] ); 615 } 616 return bundles; 617 } 618 619 public PackageAdminImpl getPackageAdmin() { 620 return packageAdmin; 621 } 622 623 public PermissionAdmin getPermissionAdmin() { 624 return null; 625 } 626 627 protected ServiceRegistry getServiceRegistry() { 628 return serviceRegistry; 629 } 630 631 protected File createFreshBundleDirectory( long id ) { 632 File bundleDirectory = generateBundleDirectory( id ); 633 634 if ( bundleDirectory.exists() ) { 636 if ( !Util.recursiveFileDelete( bundleDirectory ) ) { 637 log( LOG_WARNING, "Could not delete directory: " + bundleDirectory.getAbsolutePath() ); 638 } 639 } 640 641 bundleDirectory.mkdirs(); 643 return bundleDirectory; 644 } 645 646 public File getBundleInnerFilesDirectory( long id ) { 647 File bundleInnerFilesDirectory = (File)bundleInnerFileDirectories.get( new Long( id ) ); 648 if ( bundleInnerFilesDirectory == null ) { 649 bundleInnerFilesDirectory = new File( generateBundleDirectory( id ), bundleInnerFilesDirName + getLargestBundleJarIndex( id ) ); 651 bundleInnerFileDirectories.put( new Long( id ), bundleInnerFilesDirectory ); 652 if ( bundleInnerFilesDirectory.exists() ) { 653 Util.recursiveFileDelete( bundleInnerFilesDirectory ); 655 } 656 bundleInnerFilesDirectory.mkdirs(); 657 } 658 return bundleInnerFilesDirectory; 659 } 660 661 public File getBundleDataDirectory( long id ) { 662 File dataDirectory = new File( generateBundleDirectory( id ), bundleDataDirName ); 663 if ( !dataDirectory.exists() ) { 664 dataDirectory.mkdirs(); 665 } 666 return dataDirectory; 667 } 668 669 protected int getLargestBundleJarIndex( long id ) { 670 File bundleDir = generateBundleDirectory( id ); 671 String[] listing = bundleDir.list(); 672 String indexString; 673 int index; 674 int largestBundleJarIndex = -1; 675 for ( int i = 0; i < listing.length; i++ ) { 676 if ( listing[ i ].startsWith( bundleJarNameBase ) && listing[ i ].endsWith( bundleJarNameExtension ) ) { 677 indexString = listing[ i ].substring( bundleJarNameBase.length(), listing[ i ].length() - bundleJarNameExtension.length() ); 678 try { 679 index = Integer.valueOf( indexString ).intValue(); 680 if ( largestBundleJarIndex < index ) { 681 largestBundleJarIndex = index; 682 } 683 } 684 catch( NumberFormatException ignore ) {} 685 } 686 } 687 if ( largestBundleJarIndex > -1 ) { 688 return largestBundleJarIndex; 689 } 690 throw new IllegalArgumentException( "No bundle jar file found for requested bundle id: " + id ); 691 } 692 693 protected File getCurrentBundleJarFile( long id ) { 694 int jarIndex = getLargestBundleJarIndex( id ); 695 return new File( generateBundleDirectory( id ), bundleJarNameBase + jarIndex + bundleJarNameExtension ); 696 } 697 698 protected File getNewBundleJarFile( long id ) { 699 int index; 700 try { 701 int jarIndex = getLargestBundleJarIndex( id ); 702 index = jarIndex + 1; 703 } 704 catch( IllegalArgumentException e ) { 705 index = 0; 706 } 707 708 return new File( generateBundleDirectory( id ), bundleJarNameBase + index + bundleJarNameExtension ); 709 } 710 711 protected boolean deleteBundleJarFile( File file ) { 713 if ( file.exists() ) { 714 return file.delete(); 715 } 716 return true; 717 } 718 719 protected boolean deleteBundleDirectory( long id ) { 720 File bundleDir = generateBundleDirectory( id ); 721 return bundleDir.delete(); 722 } 723 724 protected void setBundleUninstalled( long id ) throws IOException { 725 File uninstalledFlagFile = generateBundleUninstalledFlagFile( id ); 726 writeFile( uninstalledFlagFile, "" ); 727 } 728 729 protected void registerBundleAsStarted( long bundleId ) throws IOException { 730 File startedFlagFile = generateBundleStartedFlagFile( bundleId ); 731 writeFile( startedFlagFile, "" ); 732 } 733 734 protected void recordBundleLocation( long bundleId, String location ) throws IOException { 735 File file = generateBundleLocationFile( bundleId ); 736 writeFile( file, location ); 737 } 738 739 protected String readStoredBundleLocation( long id ) throws IOException { 740 File file = generateBundleLocationFile( id ); 741 if ( !file.exists() ) { 742 throw new IllegalArgumentException( "No location file found for bundle: " + id ); 743 } 744 745 return readFile( file ); 746 } 747 748 protected boolean unregisterBundleAsStarted( Bundle bundle ) { 749 File startedFlagFile = generateBundleStartedFlagFile( bundle.getBundleId() ); 750 if ( !startedFlagFile.exists() ) { 751 return true; 752 } 753 else { 754 return startedFlagFile.delete(); 755 } 756 } 757 758 protected int getReasonableTimeToWait() { 759 return reasonableTimeToWait; 760 } 761 762 766 public abstract void checkAdminPermission() throws SecurityException; 767 public abstract void checkFilePermission( String file, String permissionToCheck ) throws SecurityException; 768 public abstract void checkPackagePermission( NamedPropertySet[] packages, String permissionToCheck, Object codeSource ) throws SecurityException; 769 public abstract void checkPropertyPermission( String property, String permissionToCheck ) throws SecurityException; 770 public abstract void checkServicePermission( String className, String permissionToCheck ) throws SecurityException; 771 public abstract void checkServicePermissionForAll( String[] classNames, String permissionToCheck ) throws SecurityException; 773 public abstract void checkServicePermissionForAtLeastOne( String[] classNames, String permissionToCheck ) throws SecurityException; 775 protected abstract boolean hasPermission( BundleImpl bundle, Object permission ); 776 protected abstract BundleClassLoader createClassLoaderForBundle( BundleImpl bundle, File bundleJarFile, NamedPropertySet[] nativeLibraries, NamedPropertySet[] classPath ) throws IOException; 777 778 779 783 protected void addServiceListener( BundleImpl bundle, ServiceListener serviceListener, String filterString ) throws InvalidSyntaxException { 784 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " adding a service listener" ); 785 if ( filterString == null ) { 786 addServiceListener( bundle, serviceListener ); 787 } 788 else { 789 serviceListeners.addListener( bundle, serviceListener, new LDAPFilter( filterString, false ) ); 791 } 792 } 793 794 protected void addServiceListener( BundleImpl bundle, ServiceListener serviceListener ) { 795 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " adding a service listener" ); 796 serviceListeners.addListener( bundle, serviceListener ); 797 } 798 799 protected void removeServiceListener( BundleImpl bundle, ServiceListener serviceListener ) { 800 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " removing a service listener" ); 801 serviceListeners.removeListener( bundle, serviceListener ); 802 } 803 804 protected void removeServiceListenersRegisteredBy( BundleImpl bundle ) { 805 int n = serviceListeners.getListenersRegisteredBy( bundle ).length; 806 if ( n > 0 ) { 807 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " removing " + n + " service listener(s)" ); 808 } 809 serviceListeners.removeAllListenersRegisteredBy( bundle ); 810 } 811 812 protected void addBundleListener( BundleImpl bundle, BundleListener bundleListener ) { 813 if ( bundleListener instanceof SynchronousBundleListener ) { 814 checkAdminPermission(); 816 } 817 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " adding a bundle listener" ); 818 bundleListeners.addListener( bundle, bundleListener ); 819 } 820 821 protected void removeBundleListener( BundleImpl bundle, BundleListener bundleListener ) { 822 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " removing a bundle listener" ); 823 bundleListeners.removeListener( bundle, bundleListener ); 824 } 825 826 protected void removeBundleListenersRegisteredBy( BundleImpl bundle ) { 827 int n = bundleListeners.getListenersRegisteredBy( bundle ).length; 828 if ( n > 0 ) { 829 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " removing " + n + " bundle listener(s)" ); 830 } 831 bundleListeners.removeAllListenersRegisteredBy( bundle ); 832 } 833 834 protected void addFrameworkListener( BundleImpl bundle, FrameworkListener frameworkListener ) { 835 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " adding a framework listener" ); 836 frameworkListeners.addListener( bundle, frameworkListener ); 837 } 838 839 protected void removeFrameworkListener( BundleImpl bundle, FrameworkListener frameworkListener ) { 840 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " removing a framework listeners" ); 841 frameworkListeners.removeListener( bundle, frameworkListener ); 842 } 843 844 protected void removeFrameworkListenersRegisteredBy( BundleImpl bundle ) { 845 int n = frameworkListeners.getListenersRegisteredBy( bundle ).length; 846 if ( n > 0 ) { 847 log( LOG_DEBUG, bundle.getLocationWithoutAdminPermissionCheck() + " removing " + n + " framework listener(s)" ); 848 } 849 frameworkListeners.removeAllListenersRegisteredBy( bundle ); 850 } 851 852 protected void fireServiceEvent( int type, ServiceReference serviceReference ) { 853 if ( handlingEvents ) { 854 final ServiceEvent event = new ServiceEvent( type, serviceReference ); 855 String[] serviceObjectClasses = (String[])serviceReference.getProperty( Constants.OBJECTCLASS ); 856 ServicePermission[] permissions = new ServicePermission[ serviceObjectClasses.length ]; 857 for ( int i = 0; i < serviceObjectClasses.length; i++ ) { 858 permissions[ i ] = new ServicePermission( serviceObjectClasses[ i ], ServicePermission.GET ); 859 } 860 861 Enumeration bundles = serviceListeners.getBundles(); 862 BundleImpl bundle; 863 boolean permissionOk; 864 Object[] bundleListeners; 865 Vector listeners = new Vector(); 866 while ( bundles.hasMoreElements() ) { 867 bundle = (BundleImpl)bundles.nextElement(); 868 permissionOk = false; 871 for ( int i = 0; i < permissions.length; i++ ) { 872 if ( hasPermission( bundle, permissions[ i ] ) ) { 873 permissionOk = true; 874 break; 875 } 876 } 877 if ( permissionOk ) { 878 bundleListeners = serviceListeners.getListenersRegisteredBy( bundle ); 881 for ( int i = 0; i < bundleListeners.length; i++ ) { 882 LDAPFilter filter = serviceListeners.getFilter( bundleListeners[ i ] ); 883 if ( filter == null || filter.match( serviceReference ) ) { 884 listeners.addElement( bundleListeners[ i ] ); 886 } 887 } 888 } 889 } 890 891 for ( int i = 0; i < listeners.size(); i++ ) { 895 try { 896 doServiceEventCallback( (ServiceListener)listeners.elementAt( i ), event ); 897 } 898 catch ( Throwable e ) { 899 log( LOG_WARNING, "A service listener threw an exception while being notified of an event" ); 900 } 901 } 902 } 903 } 904 905 protected void fireBundleEvent( int type, Bundle bundle ) { 906 if ( handlingEvents ) { 907 SynchronousBundleListener[] synchronousTargets = bundleListeners.getSynchronousBundleListeners(); 908 final BundleListener[] nonSynchronousTargets = bundleListeners.getNonSynchronousBundleListeners(); 909 final BundleEvent event = new BundleEvent( type, bundle ); 910 for ( int i = 0; i < synchronousTargets.length; i++ ) { 912 try { 913 doBundleEventCallback( synchronousTargets[ i ], event ); 914 } 915 catch ( Throwable e ) { 916 log( LOG_WARNING, "A bundle listener threw an exception while being notified of an event" ); 917 } 918 } 919 new Thread( ( new Runnable() { 921 public void run() { 922 for ( int i = 0; i < nonSynchronousTargets.length; i++ ) { 923 try { 924 doBundleEventCallback( nonSynchronousTargets[ i ], event ); 925 } 926 catch ( Throwable e ) { 927 log( LOG_WARNING, "A bundle listener threw an exception while being notified of an event" ); 928 } 929 } 930 } 931 } ) ).start(); 932 } 933 } 934 935 public void fireFrameworkEvent( int type, Bundle bundle, Throwable throwable ) { 936 if ( type == FrameworkEvent.ERROR ) { 937 log( LOG_ERROR, "Framework error" ); 938 if ( bundle != null ) { 939 log( LOG_ERROR, "Bundle: " + bundle.getLocation() + " (Id: " + bundle.getBundleId() + ")" ); 940 } 941 if ( throwable != null ) { 942 StringBuffer sb = new StringBuffer( "Exception: " + throwable.toString() ); 943 if ( throwable instanceof BundleException ) { 944 Throwable nested = ( (BundleException)throwable ).getNestedException(); 945 if ( nested != null ) { 946 sb.append( "\nNested excpetion: " + nested.toString() ); 947 } 948 } 949 log( LOG_ERROR, sb.toString() ); 950 } 951 } 952 953 if ( handlingEvents ) { 954 final Enumeration targets = frameworkListeners.getAllListeners(); 955 final FrameworkEvent event = new FrameworkEvent( type, bundle, throwable ); 956 new Thread( ( new Runnable() { 958 public void run() { 959 while ( targets.hasMoreElements() ) { 960 try { 961 doFrameworkEventCallback( (FrameworkListener)targets.nextElement(), event ); 962 } 963 catch ( Throwable e ) { 964 log( LOG_WARNING, "A framework listener threw an exception while being notified of an event" ); 965 } 966 } 967 } 968 } ) ).start(); 969 } 970 } 971 972 protected void fireFrameworkErrorEvent( Bundle bundle, Throwable exception ) { 973 log( LOG_ERROR, "Framework error" ); 974 log( LOG_ERROR, "Exception: " + exception.toString() ); 975 976 if ( handlingEvents ) { 977 final Enumeration targets = frameworkListeners.getAllListeners(); 978 final FrameworkEvent event = new FrameworkEvent( FrameworkEvent.ERROR, bundle, exception ); 979 new Thread( ( new Runnable() { 981 public void run() { 982 while ( targets.hasMoreElements() ) { 983 try { 984 doFrameworkEventCallback( (FrameworkListener)targets.nextElement(), event ); 985 } 986 catch ( Throwable e ) { 987 log( LOG_WARNING, "A framework listener threw an exception while being notified of an event" ); 988 } 989 } 990 } 991 } ) ).start(); 992 } 993 } 994 995 private void fireFrameworkStartedEvent() { 996 if ( handlingEvents ) { 997 final Enumeration targets = frameworkListeners.getAllListeners(); 998 final FrameworkEvent event = new FrameworkEvent( FrameworkEvent.STARTED, getBundle( 0 ), null ); 999 new Thread( ( new Runnable() { 1001 public void run() { 1002 while ( targets.hasMoreElements() ) { 1003 try { 1004 doFrameworkEventCallback( (FrameworkListener)targets.nextElement(), event ); 1005 } 1006 catch ( Throwable e ) { 1007 log( LOG_WARNING, "A framework listener threw an exception while being notified of an event" ); 1008 } 1009 } 1010 } 1011 } ) ).start(); 1012 } 1013 } 1014 1015 public void doServiceEventCallback( ServiceListener listener, ServiceEvent event ) { 1016 listener.serviceChanged( event ); 1017 } 1018 1019 public void doBundleEventCallback( BundleListener listener, BundleEvent event ) { 1020 listener.bundleChanged( event ); 1021 } 1022 1023 public void doFrameworkEventCallback( FrameworkListener listener, FrameworkEvent event ) { 1024 listener.frameworkEvent( event ); 1025 } 1026 1027 1031 public static final String LOG_INFO = "INFO: "; 1032 public static final String LOG_DEBUG = "DEBUG: "; 1033 public static final String LOG_WARNING = "WARNING: "; 1034 public static final String LOG_ERROR = "ERROR: "; 1035 1036 private Hashtable logTypes = new Hashtable(); 1037 1038 private void initLog() { 1039 if ( ( "" + false ).equals( System.getProperty( "com.opensugar.cube.lowLevelLog.showErrors" ) ) ) { 1041 setLogging( LOG_ERROR, false ); 1042 } 1043 else { 1044 setLogging( LOG_ERROR, true ); 1045 } 1046 if ( ( "" + false ).equals( System.getProperty( "com.opensugar.cube.lowLevelLog.showWarnings" ) ) ) { 1048 setLogging( LOG_WARNING, false ); 1049 } 1050 else { 1051 setLogging( LOG_WARNING, true ); 1052 } 1053 if ( ( "" + true ).equals( System.getProperty( "com.opensugar.cube.lowLevelLog.showInfos" ) ) ) { 1055 setLogging( LOG_INFO, true ); 1056 } 1057 else { 1058 setLogging( LOG_INFO, false ); 1059 } 1060 } 1061 1062 protected void setLogging( String logType, boolean logging ) { 1063 if ( logging ) { 1064 logTypes.put( logType, "" ); 1065 } 1066 else { 1067 logTypes.remove( logType ); 1068 } 1069 } 1070 1071 public void log( String logType, String message ) { 1072 log( logType, message, null ); 1073 } 1074 1075 public void log( String logType, String message, Throwable exception ) { 1076 if ( logTypes.get( logType ) != null ) { 1077 System.out.println( logType + message ); 1078 if ( logType.equals( LOG_ERROR ) && exception != null ) { 1079 if ( exception instanceof BundleException && ( (BundleException)exception ).getNestedException() != null ) { 1080 ( (BundleException) exception ).getNestedException().printStackTrace(); 1081 } 1082 else { 1083 exception.printStackTrace(); 1084 } 1085 } 1086 } 1087 } 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1104 protected File getBaseDirectory() { 1105 if ( baseDirectory == null ) { 1106 baseDirectory = new File( System.getProperty( SYSTEM_PROPERTY_CUBE_DIR, defaultCubeDir ) ); 1107 } 1108 return baseDirectory; 1109 } 1110 1111 private File getLastBundleIdFile() { 1112 return new File( getBaseDirectory(), bundleIdFileName ); 1113 } 1114 1115 private File generateBundleDirectory( long id ) { 1116 return new File( getBaseDirectory(), bundleDirNameBase + id ); 1117 } 1118 1119 private File generateBundleStartedFlagFile( long id ) { 1120 return new File( generateBundleDirectory( id ), bundleStartedFlagFileName ); 1121 } 1122 1123 private File generateBundleUninstalledFlagFile( long id ) { 1124 return new File( generateBundleDirectory( id ), bundleUninstalledFlagFileName ); 1125 } 1126 1127 private File generateBundleLocationFile( long id ) { 1128 return new File( generateBundleDirectory( id ), bundleLocationFileName ); 1129 } 1130 1131 private String readFile( File file ) throws IOException { 1132 FileInputStream fis = null; 1133 try { 1134 fis = new FileInputStream( file ); 1135 int n = fis.available(); 1136 byte[] data = new byte[ n ]; 1137 fis.read( data ); 1138 return new String( data ); 1139 } 1140 catch( IOException e ) { 1141 throw e; 1142 } 1143 finally { 1144 try { 1145 fis.close(); 1146 } 1147 catch( Exception ignore ) {} 1148 } 1149 } 1150 1151 private void writeFile( File file, String contents ) throws IOException { 1152 FileOutputStream fos = null; 1153 try { 1154 fos = new FileOutputStream( file ); 1155 fos.write( contents.getBytes() ); 1156 } 1157 catch( IOException e ) { 1158 throw e; 1159 } 1160 finally { 1161 try { 1162 fos.close(); 1163 } 1164 catch( Exception ignore ) {} 1165 } 1166 } 1167 1168 1175 private void deleteUninstalledBundleDirectories() { 1186 File[] bundleDirs = getBundleDirectories(); 1187 if ( bundleDirs == null ) { 1188 return; 1189 } 1190 1191 for ( int i = 0; i < bundleDirs.length; i++ ) { 1192 if ( !isInstalled( bundleDirs[ i ] ) ) { 1193 if ( !Util.recursiveFileDelete( bundleDirs[ i ] ) ) { 1194 log( LOG_WARNING, "Unable to delete bundle directory: " + bundleDirs[ i ] ); 1195 } 1196 } 1197 } 1198 } 1199 1200 private boolean isInstalled( File bundleDir ) { 1202 File uninstalledFlagFile = new File( bundleDir, AbstractCube.bundleUninstalledFlagFileName ); 1203 if ( uninstalledFlagFile.exists() ) { 1204 return false; 1205 } 1206 return true; 1207 } 1208 1209 private boolean isStarted( File bundleDir ) { 1211 File startedFlagFile = new File( bundleDir, AbstractCube.bundleStartedFlagFileName ); 1212 if ( startedFlagFile.exists() ) { 1213 return true; 1214 } 1215 return false; 1216 } 1217 1218 private void deleteObsoleteBundleFiles() { 1247 File[] invalidBundleDirs = getInvalidBundleDirectories(); 1248 for ( int i = 0; i < invalidBundleDirs.length; i++ ) { 1249 if ( !invalidBundleDirs[ i ].delete() ) { 1250 log( LOG_ERROR, "Unable to delete invalid bundle directory: " + invalidBundleDirs[ i ] ); 1251 System.exit( 1 ); 1252 } 1253 } 1254 1255 1256 File[] bundleDirs = getBundleDirectories(); 1257 if ( bundleDirs == null ) { 1258 return; 1259 } 1260 1261 File[] obsoleteBundleFiles; 1262 for ( int i = 0; i < bundleDirs.length; i++ ) { 1263 obsoleteBundleFiles = getObsoleteBundleFiles( bundleDirs[ i ] ); 1264 if ( obsoleteBundleFiles == null ) { 1265 continue; 1266 } 1267 for ( int j = 0; j < obsoleteBundleFiles.length; j++ ) { 1268 if ( !Util.recursiveFileDelete( obsoleteBundleFiles[ j ] ) ) { 1269 log( LOG_WARNING, "Unable to delete obsolete bundle file: " + obsoleteBundleFiles[ j ].getPath() ); 1270 } 1271 } 1272 } 1273 } 1274 1275 private File[] getInvalidBundleDirectories() { 1281 File[] bundleDirs = getBundleDirectories(); 1282 if ( bundleDirs == null ) { 1283 return new File[ 0 ]; 1284 } 1285 String[] listing; 1286 Vector v = new Vector(); 1287 for ( int i = 0; i < bundleDirs.length; i++ ) { 1288 listing = bundleDirs[ i ].list(); 1289 boolean bundleJarFileFound = false; 1290 boolean locationFileFound = false; 1291 for ( int j = 0; j < listing.length; j++ ) { 1292 try { 1293 getBundleJarFileIndex( listing[ j ] ); 1294 bundleJarFileFound = true; 1295 } 1296 catch( Exception e ) { 1297 } 1299 1300 if ( listing[ j ].equals( AbstractCube.bundleLocationFileName ) ) { 1301 locationFileFound = true; 1302 } 1303 } 1304 if ( !bundleJarFileFound || !locationFileFound ) { 1305 v.addElement( bundleDirs[ i ] ); 1306 } 1307 } 1308 1309 File[] invalidBundleDirs = new File[ v.size() ]; 1310 v.copyInto( invalidBundleDirs ); 1311 return invalidBundleDirs; 1312 } 1313 1314 private File[] getBundleDirectories() { 1320 File baseDir = getBaseDirectory(); 1321 if ( !baseDir.exists() ) { 1322 return null; 1323 } 1324 1325 String[] listing = baseDir.list(); 1326 Vector vec = new Vector(); 1327 String bundleId; 1328 for ( int i = 0; i < listing.length; i++ ) { 1329 try { 1330 getBundleId( listing[ i ] ); 1332 vec.addElement( new File( baseDir, listing[ i ] ) ); 1334 } 1335 catch( IllegalArgumentException ignore ) { 1336 } 1338 } 1339 1340 File[] bundleDirs = new File[ vec.size() ]; 1341 vec.copyInto( bundleDirs ); 1342 return bundleDirs; 1343 } 1344 1345 1346 private long getBundleId( String bundleDirName ) throws IllegalArgumentException { 1351 if ( !bundleDirName.startsWith( AbstractCube.bundleDirNameBase ) ) { 1352 throw new IllegalArgumentException( "Directory name is not a valid bundle directory name" ); 1353 } 1354 String idString = bundleDirName.substring( AbstractCube.bundleDirNameBase.length(), bundleDirName.length() ); 1355 try { 1356 Long id = Long.valueOf( idString ); 1357 return id.longValue(); 1358 } 1359 catch( NumberFormatException e ) { 1360 throw new IllegalArgumentException( "Directory name is not a valid bundle directory name" ); 1361 } 1362 } 1363 1364 private File[] getObsoleteBundleFiles( File bundleDir ) { 1374 if ( bundleDir == null ) { 1375 return null; 1376 } 1377 1378 String[] listing = bundleDir.list(); 1380 if ( listing == null ) { 1381 return null; 1383 } 1384 1385 Vector indices = new Vector(); 1386 for ( int i = 0; i < listing.length; i++ ) { 1387 try { 1388 indices.addElement( new Integer( getBundleJarFileIndex( listing[ i ] ) ) ); 1389 } 1390 catch( Exception e ) { 1391 } 1393 } 1394 1395 if ( indices.size() == 0 ) { 1397 log( LOG_WARNING, "No bundle jar file in directory: " + bundleDir ); 1398 return null; 1399 } 1400 1401 if ( indices.size() == 1 ) { 1403 return null; 1404 } 1405 1406 int maxIndex = -1; 1408 int index; 1409 for ( int i = 0; i < indices.size(); i++ ) { 1410 index = ( (Integer)indices.elementAt( i ) ).intValue(); 1411 if ( maxIndex < index ) { 1412 maxIndex = index; 1413 } 1414 } 1415 1416 indices.removeElement( new Integer( maxIndex ) ); 1418 1419 Vector tmp = new Vector(); 1424 File innerFilesDirectory; 1425 for ( int i = 0; i < indices.size(); i++ ) { 1426 index = ( (Integer)indices.elementAt( i ) ).intValue(); 1427 tmp.addElement( new File( bundleDir, AbstractCube.bundleJarNameBase + index + AbstractCube.bundleJarNameExtension ) ); 1428 innerFilesDirectory = new File( bundleDir, AbstractCube.bundleInnerFilesDirName + index ); 1429 if ( innerFilesDirectory.exists() ) { 1430 tmp.addElement( innerFilesDirectory ); 1431 } 1432 } 1433 1434 File[] obsoleteBundleFiles = new File[ tmp.size() ]; 1435 tmp.copyInto( obsoleteBundleFiles ); 1436 return obsoleteBundleFiles; 1437 } 1438 1439 private int getBundleJarFileIndex( String bundleJarFileName ) throws NumberFormatException, IllegalArgumentException { 1440 if ( bundleJarFileName.startsWith( AbstractCube.bundleJarNameBase ) && bundleJarFileName.endsWith( AbstractCube.bundleJarNameExtension ) ) { 1441 String indexString = bundleJarFileName.substring( AbstractCube.bundleJarNameBase.length(), bundleJarFileName.length() - AbstractCube.bundleJarNameExtension.length() ); 1442 return Integer.valueOf( indexString ).intValue(); 1443 } 1444 else { 1445 throw new IllegalArgumentException( "Invalid bundle jar file name" ); 1446 } 1447 } 1448 1449 private void reinstallBundles() { 1454 File[] bundleDirs = getBundleDirectories(); 1455 if ( bundleDirs == null ) { 1456 return; 1457 } 1458 1459 long bundleId; 1460 for ( int i = 0; i < bundleDirs.length; i++ ) { 1461 if ( isInstalled( bundleDirs[ i ] ) ) { 1462 bundleId = getBundleId( bundleDirs[ i ].getName() ); 1463 try { 1464 reinstallBundle( bundleId ); 1465 } 1466 catch( BundleException e ) { 1467 log( LOG_ERROR, "Could not reinstall bundle " + bundleId, e ); 1468 } 1469 catch( IOException e ) { 1470 log( LOG_ERROR, "Could not reinstall bundle " + bundleId, e ); 1471 } 1472 } 1473 } 1474 } 1475 1476 private void restartBundles( Observer progressListener ) { 1481 File[] bundleDirs = getBundleDirectories(); 1482 if ( bundleDirs == null ) { 1483 return; 1484 } 1485 1486 long bundleId, id; 1488 Vector vec = new Vector(); 1489 for ( int i = 0; i < bundleDirs.length; i++ ) { 1490 if ( isStarted( bundleDirs[ i ] ) ) { 1491 bundleId = getBundleId( bundleDirs[ i ].getName() ); 1492 int index = vec.size(); 1493 for ( int j = 0; j < vec.size(); j++ ) { 1494 id = ( (Long)vec.elementAt( j ) ).longValue(); 1495 if ( bundleId < id ) { 1496 index = j; 1497 break; 1498 } 1499 } 1500 vec.insertElementAt( new Long( bundleId ), index ); 1501 } 1502 } 1503 1504 int fudgeSleepTime = 0; 1505 try { 1506 fudgeSleepTime = Integer.valueOf( System.getProperty( "com.opensugar.cube.fudgeSleep" ) ).intValue(); 1507 } 1508 catch ( Exception ignore ) {} 1509 1510 int percent = 0; 1511 String percentString = percent + " %"; 1512 System.out.print( percentString ); 1513 if ( progressListener != null ) { 1514 progressListener.update( null, new Integer( percent ) ); 1515 } 1516 for ( int i = 0; i < vec.size(); i++ ) { 1517 bundleId = ( (Long)vec.elementAt( i ) ).longValue(); 1518 BundleImpl bundle = getBundle( bundleId ); 1519 try { 1520 for ( int j = 0; j < percentString.length(); j++ ) { 1521 System.out.print( "\b" ); 1522 } 1523 percent = (int)( ( i + 0.5 ) / vec.size() * 100 ); 1524 percentString = percent + " %"; 1525 System.out.print( percentString ); 1526 if ( progressListener != null ) { 1527 progressListener.update( null, new Integer( percent ) ); 1528 } 1529 if ( bundle.getState() == bundle.RESOLVED ) { 1536 bundle.start(); 1537 } 1538 else { 1539 log( LOG_WARNING, "\nCould not restart bundle " + bundleId + " because it is not resolved" ); 1540 PackageImport[] unsatisfiedImports = packageAdmin.getUnsatisfiedImports( bundle ); 1541 System.out.println( "Missing packages:" ); 1542 for ( int j = 0; j < unsatisfiedImports.length; j++ ) { 1543 System.out.print( "\t" + unsatisfiedImports[ j ].getName() ); 1544 if ( unsatisfiedImports[ j ].getSpecificationVersion() != null ) { 1545 System.out.print( " - v" + unsatisfiedImports[ j ].getSpecificationVersion() ); 1546 } 1547 System.out.print( "\n" ); 1548 } 1549 } 1550 if ( fudgeSleepTime > 0 ) { 1551 try { 1552 Thread.sleep( fudgeSleepTime ); 1553 } 1554 catch ( InterruptedException ignore ) {} 1555 } 1556 for ( int j = 0; j < percentString.length(); j++ ) { 1557 System.out.print( "\b" ); 1558 } 1559 percent = (int)( ( i + 1.0 ) / vec.size() * 100 ); 1560 percentString = percent + " %"; 1561 System.out.print( percentString ); 1562 if ( progressListener != null ) { 1563 progressListener.update( null, new Integer( percent ) ); 1564 } 1565 } 1566 catch( Throwable e ) { 1567 fireFrameworkEvent( FrameworkEvent.ERROR, bundle, e ); 1568 log( LOG_ERROR, "\nCould not restart bundle " + bundleId, e ); 1569e.printStackTrace(); 1570 } 1571 } 1572 for ( int j = 0; j < percentString.length(); j++ ) { 1573 System.out.print( "\b" ); 1574 } 1575 if ( progressListener != null ) { 1576 progressListener.update( null, new Integer( percent ) ); 1577 } 1578 } 1579 1580} 1581 | Popular Tags |