⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bundleimpl.java

📁 OSGI这是一个中间件,与UPNP齐名,是用于移植到嵌入式平台之上
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2003-2004, KNOPFLERFISH project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright *   notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above *   copyright notice, this list of conditions and the following *   disclaimer in the documentation and/or other materials *   provided with the distribution. * * - Neither the name of the KNOPFLERFISH project nor the names of its *   contributors may be used to endorse or promote products derived *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */package org.knopflerfish.framework;import java.io.*;import java.net.*;import java.security.*;import java.util.Set;import java.util.Dictionary;import java.util.List;import java.util.ArrayList;import java.util.Map;import java.util.HashSet;import java.util.HashMap;import java.util.Iterator;import org.osgi.framework.*;/** * Implementation of the Bundle object. * * @see org.osgi.framework.Bundle * @author Jan Stein */class BundleImpl implements Bundle {  /**   * Framework for bundle.   */  final Framework framework;  /**   * Bundle identifier.   */  final long id;  /**   * Bundle location identifier.   */  final String location;  /**   * Bundle protect domain.   */  final ProtectionDomain protectionDomain;  /**   * State of bundle.   */  int state;  /**   * Packages that the bundle wants to export and import.   */  BundlePackages bpkgs;  /**   * Bundle JAR data.   */  BundleArchive archive;  /**   * Classloader for bundle.   */  private BundleClassLoader classLoader = null;  /**   * Zombie classloaders for bundle.   */  private Map /* String -> BundleClassLoader */ oldClassLoaders = null;      /**   * Directory for bundle data.   */  protected FileTree bundleDir = null;  /**   * BundleContext for bundle.   */  protected BundleContextImpl bundleContext = null;  /**   * BundleActivator for bundle.   */  protected BundleActivator bactivator = null;  /**   * List of all nativeLibs that can be used in this bundle.   *    * pl: unused   */  //protected List nativeLibs = null;  /**   * Set to true of bundle.start() has been called but   * current start levels was too low to actually start the bundle.   */  boolean bDelayedStart = false;  /**   * Construct a new Bundle empty.   *   * @param fw Framework for this bundle.   */  BundleImpl(Framework fw, long id, String loc, ProtectionDomain pd) {    this.framework = fw;    this.id = id;    this.location = loc;    this.protectionDomain = pd;  }  /**   * Construct a new Bundle based on a BundleArchive.   *   * @param bundlesDir Directory where to store the bundles all persistent data.   * @param fw Framework for this bundle.   * @param loc Location for new bundle.   * @param in Bundle JAR as an inputstream.   * @exception IOException If we fail to read and store our JAR bundle or if   *            the input data is corrupted.   * @exception SecurityException If we don't have permission to import and export   *            bundle packages.   */  BundleImpl(Framework fw, BundleArchive ba) {    framework = fw;    id = ba.getBundleId();    location = ba.getBundleLocation();    archive = ba;    state = INSTALLED;    doExportImport();    FileTree dataRoot = fw.getDataStorage();    if (dataRoot != null) {      bundleDir = new FileTree(dataRoot, Long.toString(id));    }    ProtectionDomain pd = null;    if (fw.bPermissions) {      try {        URLStreamHandler handler           = bpkgs.bundle.framework.bundleURLStreamhandler;        	URL bundleUrl = new URL(BundleURLStreamHandler.PROTOCOL,                                 Long.toString(id),                                 -1,                                "",                                handler);	PermissionCollection pc = fw.permissions.getPermissionCollection(this);	pd = new ProtectionDomain(new CodeSource(bundleUrl, 						 (java.security.cert.Certificate[])null), 				  pc);      } catch (MalformedURLException e) { 	e.printStackTrace();      }    }    protectionDomain = pd;    int oldStartLevel = archive.getStartLevel();    try {      if(framework.startLevelService == null) {	archive.setStartLevel(0);      } else {	if(oldStartLevel == -1) {	  archive.setStartLevel(framework.startLevelService.getInitialBundleStartLevel());	} else {	}       }    } catch (Exception e) {      Debug.println("Failed to set start level on #" + getBundleId() + ": " + e);    }  }  //  // Bundle interface  //  /**   * Get bundle state.   *   * @see org.osgi.framework.Bundle#getState   */  public int getState() {    return state;  }  /**   * Start this bundle.   *   * @see org.osgi.framework.Bundle#start   */  synchronized public void start() throws BundleException {    framework.checkAdminPermission();    int updState = getUpdatedState();    setPersistent(true);        if(framework.startLevelService != null) {      if(getStartLevel() > framework.startLevelService.getStartLevel()) {	bDelayedStart = true;	return;      }    }    switch (updState) {    case INSTALLED:      throw new BundleException("Bundle.start: Failed, " + bpkgs.getResolveFailReason());    case RESOLVED:      if (framework.active) {	state = STARTING;	bundleContext = new BundleContextImpl(this);	try {	  AccessController.doPrivileged(new PrivilegedExceptionAction() {	      public Object run() throws BundleException {		final String ba = archive.getAttribute(Constants.BUNDLE_ACTIVATOR);		boolean bStarted = false;		ClassLoader oldLoader = null;		if(Framework.SETCONTEXTCLASSLOADER) {		  oldLoader = Thread.currentThread().getContextClassLoader();		}		try {		  // If SETCONTEXTCLASSLOADER, set the thread's context		  // class loader to the bundle class loader. This		  // is useful for debugging external libs using		  // the context class loader.		  if(Framework.SETCONTEXTCLASSLOADER) {		    Thread.currentThread().setContextClassLoader(getClassLoader());		  }		  if (ba != null) {		    		    Class c = getClassLoader().loadClass(ba.trim());		    bactivator = (BundleActivator)c.newInstance();		    bactivator.start(bundleContext);		    bStarted = true;		  } else {		    // Check if we have a standard Main-class attribute as		    // in normal executable jar files. This is a slight 		    // extension to the OSGi spec.		    final String mc = archive.getAttribute("Main-class");		    		    if (mc != null) {		      if(Debug.packages) {			Debug.println("starting main class " + mc);		      }		      Class mainClass = getClassLoader().loadClass(mc.trim());		      		      bactivator = MainClassBundleActivator.create(getClassLoader(), mainClass);		      bactivator.start(bundleContext);		      bStarted = true;		    }		  } 		  		  if(!bStarted) {		    // Even bundles without an activator is marked as 		    // ACTIVE.		    		    // Should we possible log an information message to 		    // make sure users are aware of the missing activator?		  }		  		  state = ACTIVE;		  startOnLaunch(true);		} catch (Throwable t) {		  throw new BundleException("Bundle.start: BundleActivator start failed", t);		} finally {		  if(Framework.SETCONTEXTCLASSLOADER) {		    Thread.currentThread().setContextClassLoader(oldLoader);		  }		}		return null;	      }	    });	} catch (PrivilegedActionException e) {	  removeBundleResources();	  bundleContext.invalidate();	  bundleContext = null;	  state = RESOLVED;	  throw (BundleException) e.getException();	}	framework.listeners.bundleChanged(new BundleEvent(BundleEvent.STARTED, this));	break;      } else {	startOnLaunch(true);      }    case ACTIVE:      return;    case STARTING:      // This happens if we call start from inside the BundleActivator.start method.      // We don't allow it.      throw new BundleException("Bundle.start called from BundleActivator.start");    case STOPPING:      // This happens if we call start from inside the BundleActivator.stop method.      // We don't allow it.      throw new BundleException("Bundle.start called from BundleActivator.stop");    case UNINSTALLED:      throw new IllegalStateException("Bundle.start: Bundle is in UNINSTALLED state");    }  }  /**   * Check if setStartOnLaunch(false) is allowed.   */  boolean allowSetStartOnLaunchFalse() {    boolean bCompat =       framework.startLevelService == null ||      framework.startLevelService.bCompat;        return       // never never touch on FW shutdown      !framework.shuttingdown && !archive.isPersistent();      /*	&&             // allow touch if in startlevel compatibility mode      (bCompat ||        // ...also allow touch if not marked as persistant startlevel active       !isPersistent());      */  }  /**   * Stop this bundle.   *   * @see org.osgi.framework.Bundle#stop   */  synchronized public void stop() throws BundleException {    framework.checkAdminPermission();    bDelayedStart = false;        setPersistent(false);    if(framework.startLevelService != null) {      if(getStartLevel() <= framework.startLevelService.getStartLevel()) {	if(state == ACTIVE) {	  bDelayedStart = true;	}      }    }    switch (state) {    case INSTALLED:    case RESOLVED:      // We don't want this bundle to start on launch after it has been      // stopped. (Don't apply during shutdown      if (allowSetStartOnLaunchFalse()) {	AccessController.doPrivileged(new PrivilegedAction() {	    public Object run() {	      startOnLaunch(false);	      return null;	    }	  });      }      break;    case ACTIVE:      state = STOPPING;      Throwable savedException =	(Throwable) AccessController.doPrivileged(new PrivilegedAction() {	  public Object run() {	    Throwable res = null;	    if (allowSetStartOnLaunchFalse()) {	      startOnLaunch(false);	    }	    if (bactivator != null) {	      try {		bactivator.stop(bundleContext);	      } catch (Throwable e) {		res = e;	      }	      bactivator = null;	    }	    bundleContext.invalidate();	    bundleContext = null;	    removeBundleResources();	    state = RESOLVED;	    return res;	  }	});      framework.listeners.bundleChanged(new BundleEvent(BundleEvent.STOPPED, this));      if (savedException != null) {	throw new BundleException("Bundle.stop: BundleActivator stop failed",				  savedException);      }      break;    case STARTING:      // This happens if we call stop from inside the BundleActivator.start method.      // We don't allow it.      throw new BundleException("Bundle.start called from BundleActivator.stop");    case STOPPING:      // This happens if we call stop from inside the BundleActivator.stop method.      // We don't allow it.      throw new BundleException("Bundle.stop called from BundleActivator.stop");    case UNINSTALLED:      throw new IllegalStateException("Bundle.stop: Bundle is in UNINSTALLED state");    }  }  /**   * Update this bundle.   *   * @see org.osgi.framework.Bundle#update   */  public void update() throws BundleException {    update(null);  }  /**   * Update this bundle.   *   * @see org.osgi.framework.Bundle#update   */  synchronized public void update(final InputStream in) throws BundleException {    try {      framework.checkAdminPermission();      final boolean wasActive = state == ACTIVE;      switch (getUpdatedState()) {      case ACTIVE:	stop();	// Fall through      case INSTALLED:      case RESOLVED:	// Load new bundle	try {	  final BundleImpl thisBundle = this;	  final int oldStartLevel = getStartLevel();	  AccessController.doPrivileged(new PrivilegedExceptionAction() {	      public Object run() throws BundleException {		BundleArchive newArchive = null;		HeaderDictionary newHeaders;		try {		  // New bundle as stream supplied?		  InputStream bin;		  if (in == null) {		    // Try Bundle-UpdateLocation		    String update = archive.getAttribute(Constants.BUNDLE_UPDATELOCATION);		    if (update == null) {		      // Take original location		      update = location;		    }		    bin = (new URL(update)).openStream();		  } else {		    bin = in;		  }		  newArchive = framework.storage.replaceBundleJar(archive, bin);		  newArchive.setStartLevel(oldStartLevel);		} catch (Exception e) {		  if (newArchive != null) {		    newArchive.purge();		  }				  if (wasActive) {		    try {		      start();		    } catch (BundleException be) {		      framework.listeners.frameworkError(thisBundle, be);		    }		  }		  throw new BundleException("Failed to get update bundle", e);		}		// Remove this bundles packages		boolean allRemoved = bpkgs.unregisterPackages(false);		// Loose old bundle if no exporting packages left		if (classLoader != null) {		  if (allRemoved) {		    classLoader.purge();		  } else {		    saveZombiePackages();		  }		  classLoader = null;		}		// Activate new bundle		state = INSTALLED;		BundleArchive oldArchive = archive;		archive = newArchive;		doExportImport();		// Purge old archive		if (allRemoved) {		  oldArchive.purge();		}		checkEE(newArchive);      		// Broadcast updated event		framework.listeners.bundleChanged(new BundleEvent(BundleEvent.UPDATED, thisBundle));		// Restart bundles previously stopped in the operation		if (wasActive) {		  try {		    thisBundle.start();		  } catch (BundleException be) {		    framework.listeners.frameworkError(thisBundle, be);		  }		}		return null;	      }	    });	} catch (PrivilegedActionException e) {	  throw (BundleException) e.getException();	}	break;      case STARTING:	// Wait for RUNNING state, this doesn't happen now	// since we are synchronized.	throw new IllegalStateException("Bundle.update: Bundle is in STARTING state");      case STOPPING:	// Wait for RESOLVED state, this doesn't happen now	// since we are synchronized.	throw new IllegalStateException("Bundle.update: Bundle is in STOPPING state");      case UNINSTALLED:	throw new IllegalStateException("Bundle.update: Bundle is in UNINSTALLED state");      }    } finally {      if (in != null) {	try {	  in.close();	} catch (IOException ignore) {}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -