package org.osgi.framework; import java.io.File; import java.io.InputStream; import java.util.Dictionary; import java.net.URL; /** * An installed bundle in the Framework. * * <p>A <tt>Bundle</tt> object is the access point to define the life cycle * of an installed bundle. Each bundle installed in the OSGi environment * will have an associated <tt>Bundle</tt> object. * * <p>A bundle will have a unique identity, a <tt>long</tt>, chosen by the * Framework. This identity will not change during the life cycle of a bundle, even when * the bundle is updated. Uninstalling and then reinstalling the bundle will create * a new unique identity. * * <p>A bundle can be in one of six states: * <ul> * <li>{@link #UNINSTALLED} * <li>{@link #INSTALLED} * <li>{@link #RESOLVED} * <li>{@link #STARTING} * <li>{@link #STOPPING} * <li>{@link #ACTIVE} * </ul> * <p>Values assigned to these states have no specified ordering; * they represent bit values that may be ORed together to determine if * a bundle is in one of the valid states. * * <p>A bundle should only execute code when its state is one of * <tt>STARTING</tt>, <tt>ACTIVE</tt>, or <tt>STOPPING</tt>. * An <tt>UNINSTALLED</tt> bundle can not be set to another state; it * is a zombie and can only be reached because invalid references are kept somewhere. * * <p>The Framework is the only entity that is allowed to * create <tt>Bundle</tt> objects, and these objects are only valid * within the Framework that created them. * * @version $Revision: 1.1 $ * @author Open Services Gateway Initiative */ public abstract interface Bundle { /** * This bundle is uninstalled and may not be used. * * <p>The <tt>UNINSTALLED</tt> state is only visible after a bundle * is uninstalled; the bundle is in an unusable state * and all references to the <tt>Bundle</tt> object should be released * immediately. * <p>The value of <tt>UNINSTALLED</tt> is 0x00000001. */ public static final int UNINSTALLED = 0x00000001; /** * This bundle is installed but not yet resolved. * * <p>A bundle is in the <tt>INSTALLED</tt> state when it has been installed * in the Framework but cannot run. * <p>This state is visible if the bundle's code dependencies are not resolved. * The Framework may attempt to resolve an <tt>INSTALLED</tt> bundle's * code dependencies and move the bundle to the <tt>RESOLVED</tt> state. * <p>The value of <tt>INSTALLED</tt> is 0x00000002. */ public static final int INSTALLED = 0x00000002; /** * This bundle is resolved and is able to be started. * * <p>A bundle is in the <tt>RESOLVED</tt> state when the Framework has successfully * resolved the bundle's dependencies. These dependencies include: * <ul> * <li>The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH} Manifest header. * <li>The bundle's package dependencies from * its {@link Constants#EXPORT_PACKAGE}and {@link Constants#IMPORT_PACKAGE} Manifest headers. * </ul> * <p>Note that the bundle is not active yet. A bundle must be put in the * <tt>RESOLVED</tt> state before it can be started. The Framework may attempt to * resolve a bundle at any time. * <p>The value of <tt>RESOLVED</tt> is 0x00000004. */ public static final int RESOLVED = 0x00000004; /** * This bundle is in the process of starting. * * <p>A bundle is in the <tt>STARTING</tt> state when the {@link #start}method * is active. A bundle will be in this state when the bundle's * {@link BundleActivator#start}is called. If this method completes * without exception, then the bundle has successfully started and will move to the * <tt>ACTIVE</tt> state. * <p>The value of <tt>STARTING</tt> is 0x00000008. */ public static final int STARTING = 0x00000008; /** * This bundle is in the process of stopping. * * <p>A bundle is in the <tt>STOPPING</tt> state when the {@link #stop}method * is active. A bundle will be in this state when the bundle's * {@link BundleActivator#stop}method is called. When this method completes * the bundle is stopped and will move to the <tt>RESOLVED</tt> state. * <p>The value of <tt>STOPPING</tt> is 0x00000010. */ public static final int STOPPING = 0x00000010; /** * This bundle is now running. * * <p>A bundle is in the <tt>ACTIVE</tt> state when it has been successfully started. * <p>The value of <tt>ACTIVE</tt> is 0x00000020. */ public static final int ACTIVE = 0x00000020; /** * Returns this bundle's current state. * * <p>A bundle can be in only one state at any time. * * @return An element of <tt>UNINSTALLED</tt>, <tt>INSTALLED</tt>, * <tt>RESOLVED</tt>, <tt>STARTING</tt>, <tt>STOPPING</tt>, * <tt>ACTIVE</tt>. */ public abstract int getState(); /** * Starts this bundle. * * If the Framework implements the optional Start Level service and the * current start level is less than this bundle's start level, then the * Framework must persistently mark this bundle as started and delay the * starting of this bundle until the Framework's current start level becomes * equal or more than the bundle's start level. * <p>Otherwise, the following steps are required to start a bundle: * <ol> * <li>If this bundle's state is <tt>UNINSTALLED</tt> then * an <tt>IllegalStateException</tt> is thrown. * * <li>If this bundle's state is <tt>STARTING</tt> or <tt>STOPPING</tt> * then this method will wait for this bundle to * change state before continuing. If this does not occur * in a reasonable time, a <tt>BundleException</tt> is thrown to indicate * this bundle was unable to be started. * * <li>If this bundle's state is <tt>ACTIVE</tt> then this method returns immediately. * * <li>If this bundle's state is not <tt>RESOLVED</tt>, * an attempt is made to resolve this bundle's package dependencies. * If the Framework cannot resolve this bundle, a <tt>BundleException</tt> is thrown. * * <li>This bundle's state is set to <tt>STARTING</tt>. * * <li>The {@link BundleActivator#start}method of this * bundle's <tt>BundleActivator</tt>, if one is specified, is called. * If the <tt>BundleActivator</tt> is invalid or throws an exception, this bundle's state * is set back to <tt>RESOLVED</tt>. * <br>Any services registered by the bundle will be unregistered. * <br>Any services used by the bundle will be released. * <br>Any listeners registered by the bundle will be removed. * <br>A <tt>BundleException</tt> is then thrown. * * <li> If this bundle's state is <tt>UNINSTALLED</tt>, * because the bundle was uninstalled while the <tt>BundleActivator.start</tt> * method was running, a <tt>BundleException</tt> is thrown. * * <li>Since it is recorded that this bundle has been started, when * the Framework is restarted this bundle will be automatically started. * * <li>This bundle's state is set to <tt>ACTIVE</tt>. * * <li>A bundle event of type {@link BundleEvent#STARTED}is broadcast. * </ol> * * <b>Preconditions</b> * <ul> * <li><tt>getState()</tt> in {<tt>INSTALLED</tt>}, {<tt>RESOLVED</tt>}. * </ul> * <b>Postconditions, no exceptions thrown</b> * <ul> * <li><tt>getState()</tt> in {<tt>ACTIVE</tt>}. * <li><tt>BundleActivator.start()</tt> has been called and did not throw an exception. * </ul> * <b>Postconditions, when an exception is thrown</b> * <ul> * <li><tt>getState()</tt> not in {<tt>STARTING</tt>}, {<tt>ACTIVE</tt>}. * </ul> * * @exception BundleException If this bundle couldn't be started. * This could be because a code dependency could not be resolved or * the specified <tt>BundleActivator</tt> could not be loaded or threw an exception. * @exception java.lang.IllegalStateException If this * bundle has been uninstalled or this bundle tries to change its own state. * @exception java.lang.SecurityException If the caller does not have * the appropriate <tt>AdminPermisson</tt>, and the Java Runtime Environment * supports permissions. */ public abstract void start() throws BundleException; /** * Stops this bundle. * * <p> The following steps are required to stop a bundle: * <ol> * <li>If this bundle's state is <tt>UNINSTALLED</tt> then * an <tt>IllegalStateException</tt> is thrown. * * <li>If this bundle's state is <tt>STARTING</tt> or <tt>STOPPING</tt> * then this method will wait for this bundle to * change state before continuing. If this does not occur * in a reasonable time, a <tt>BundleException</tt> is thrown to indicate * this bundle was unable to be stopped. * * <li>If this bundle's state is not <tt>ACTIVE</tt> then this method returns immediately. * * <li> This bundle's state is set to <tt>STOPPING</tt>. * * <li>Since it is recorded that this bundle has been stopped, * Framework is restarted this bundle will not be automatically started. * * <li>The {@link BundleActivator#stop}method of this * bundle's <tt>BundleActivator</tt>, if one is specified, is called. * If this method throws an exception, it will continue to stop this bundle. * A <tt>BundleException</tt> will be thrown after completion of the * remaining steps. * * <li>Any services registered by this bundle must be unregistered. * <li>Any services used by this bundle must be released. * <li>Any listeners registered by this bundle must be removed. * * <li> If this bundle's state is <tt>UNINSTALLED</tt>, * because the bundle was uninstalled while the <tt>BundleActivator.stop</tt> * method was running, a <tt>BundleException</tt> must be thrown. * * <li>This bundle's state is set to <tt>RESOLVED</tt>. * * <li>A bundle event of type {@link BundleEvent#STOPPED}is broadcast. * </ol> * * <b>Preconditions</b> * <ul> * <li><tt>getState()</tt> in {<tt>ACTIVE</tt>}. * </ul> * <b>Postconditions, no exceptions thrown</b> * <ul> * <li><tt>getState()</tt> not in {<tt>ACTIVE</tt>, <tt>STOPPING</tt>}. * <li><tt>BundleActivator.stop</tt> has been called and did not throw an exception. * </ul> * <b>Postconditions, when an exception is thrown</b> * <ul> * <li>None. * </ul> * * @exception BundleException If this bundle's * <tt>BundleActivator</tt> could not be loaded or threw an exception. * @exception java.lang.IllegalStateException If this * bundle has been uninstalled or this bundle tries to change its own state. * @exception java.lang.SecurityException If the caller does not have * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment * supports permissions. */ public abstract void stop() throws BundleException; /** * Updates this bundle. * * <p>If this bundle's state is <tt>ACTIVE</tt>, it will be stopped * before the update and started after the update successfully completes. * * <p>If the bundle being updated has exported any packages, these * packages will not be updated. Instead, the previous package version will remain * exported until the <tt>PackageAdmin.refreshPackages</tt> method has been * has been called or the Framework is relaunched. * * <p> The following steps are required to update a bundle: * <ol> * <li>If this bundle's state is <tt>UNINSTALLED</tt> then * an <tt>IllegalStateException</tt> is thrown. * * <li>If this bundle's state is <tt>ACTIVE</tt>, <tt>STARTING</tt> or <tt>STOPPING</tt>, * the bundle is stopped as described in the <tt>Bundle.stop</tt> method. * If <tt>Bundle.stop</tt> throws an exception, the exception is rethrown * terminating the update. * * <li>The download location of the new version of this bundle * is determined from either the bundle's {@link Constants#BUNDLE_UPDATELOCATION} Manifest * header (if available) or the bundle's original location. * * <li>The location is interpreted in an implementation dependent manner, * typically as a URL, and the new version of this bundle is obtained from * this location. * * <li>The new version of this bundle is installed. If the Framework is * unable to install the new version of this bundle, the original version * of this bundle will be restored and a <tt>BundleException</tt> will be thrown * after completion of the remaining steps. * * <li>If the bundle has declared an Bundle-RequiredExecutionEnvironment header, then * the listed execution environments must be verified against the installed * execution environments. If they do not all match, the original version * of this bundle will be restored and a <tt>BundleException</tt> will be thrown * after completion of the remaining steps. * * <li>This bundle's state is set to <tt>INSTALLED</tt>. * * * <li> If this bundle has not declared an <tt>Import-Package</tt> header * in its Manifest file (specifically, this bundle does not depend on any packages from * other bundles), this bundle's state may be set to <tt>RESOLVED</tt>. * * <li>If the new version of this bundle was successfully installed, * a bundle event of type {@link BundleEvent#UPDATED}is broadcast. * * <li>If this bundle's state was originally <tt>ACTIVE</tt>, * the updated bundle is started as described in the <tt>Bundle.start</tt> method. * If <tt>Bundle.start</tt> throws an exception, a Framework event of * type {@link FrameworkEvent#ERROR}is broadcast containing the exception. * </ol> * * <b>Preconditions</b> * <ul> * <li><tt>getState()</tt> not in {<tt>UNINSTALLED</tt>}. * </ul> * <b>Postconditions, no exceptions thrown</b> * <ul> * <li><tt>getState()</tt> in * {<tt>INSTALLED</tt>, <tt>RESOLVED</tt>, <tt>ACTIVE</tt>}. * <li>This bundle has been updated. * </ul> * <b>Postconditions, when an exception is thrown</b> * <ul> * <li><tt>getState()</tt> in {<tt>INSTALLED</tt>, <tt>RESOLVED</tt>, <tt>ACTIVE</tt>}. * <li>Original bundle is still used; no update occurred. * </ul> * * @exception BundleException If the update fails. * @exception java.lang.IllegalStateException If this * bundle has been uninstalled or this bundle tries to change its own state. * @exception java.lang.SecurityException If the caller does not have * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment * supports permissions. * @see #stop() * @see #start() */ // public abstract void update() throws BundleException; // /** // * Updates this bundle from an <tt>InputStream</tt>. // * // * <p>This method performs all the steps listed in <tt>Bundle.update()</tt>, except the bundle // * will be read from the supplied <tt>InputStream</tt>, rather than a <tt>URL</tt>. // * <p>This method will always close the <tt>InputStream</tt> // * when it is done, even if an exception is thrown. // * // * @param in The <tt>InputStream</tt> from which to read the new bundle. // * @exception BundleException If the provided stream cannot be read or the update fails. // * @exception java.lang.IllegalStateException If this // * bundle has been uninstalled or this bundle tries to change its own state. // * @exception java.lang.SecurityException If the caller does not have // * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment // * supports permissions. // * @see #update() // */ // public abstract void update(InputStream in) throws BundleException; /** * Updates this bundle from an <tt>File</tt>. * * <p>This method performs all the steps listed in <tt>Bundle.update()</tt>, except the bundle * will be read from the supplied <tt>File</tt>, rather than a <tt>URL</tt>. * <p>This method will try to move <tt>File</tt> * * @param file The <tt>File</tt> from which to read the new bundle. * @param version The <tt>File</tt> from which to read the new bundle. * @exception BundleException If the provided stream cannot be read or the update fails. * @exception java.lang.IllegalStateException If this * bundle has been uninstalled or this bundle tries to change its own state. * @exception java.lang.SecurityException If the caller does not have * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment * supports permissions. * @see #update() */ public abstract void update(File file,String version,long dexPathVersion) throws BundleException; /** * Uninstalls this bundle. * * <p>This method causes the Framework to notify other bundles that this bundle * is being uninstalled, and then puts this bundle into the <tt>UNINSTALLED</tt> * state. The Framework will remove any resources related to this * bundle that it is able to remove. * * <p>If this bundle has exported any packages, the Framework will * continue to make these packages available to their importing bundles * until the <tt>PackageAdmin.refreshPackages</tt> method has been called * or the Framework is relaunched. * * <p>The following steps are required to uninstall a bundle: * <ol> * <li>If this bundle's state is <tt>UNINSTALLED</tt> then * an <tt>IllegalStateException</tt> is thrown. * * <li>If this bundle's state is <tt>ACTIVE</tt>, <tt>STARTING</tt> or <tt>STOPPING</tt>, * this bundle is stopped as described in the <tt>Bundle.stop</tt> method. * If <tt>Bundle.stop</tt> throws an exception, a Framework event of type * {@link FrameworkEvent#ERROR}is broadcast containing the exception. * * <li>This bundle's state is set to <tt>UNINSTALLED</tt>. * * <li>A bundle event of type {@link BundleEvent#UNINSTALLED}is broadcast. * * <li>This bundle and any persistent storage area provided for this bundle * by the Framework are removed. * </ol> * * <b>Preconditions</b> * <ul> * <li><tt>getState()</tt> not in {<tt>UNINSTALLED</tt>}. * </ul> * <b>Postconditions, no exceptions thrown</b> * <ul> * <li><tt>getState()</tt> in {<tt>UNINSTALLED</tt>}. * <li>This bundle has been uninstalled. * </ul> * <b>Postconditions, when an exception is thrown</b> * <ul> * <li><tt>getState()</tt> not in {<tt>UNINSTALLED</tt>}. * <li>This Bundle has not been uninstalled. * </ul> * * @exception BundleException If the uninstall failed. * This can occur if another thread is attempting to change the bundle's state * and does not complete in a timely manner. * @exception java.lang.IllegalStateException If this * bundle has been uninstalled or this bundle tries to change its own state. * @exception java.lang.SecurityException If the caller does not have * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment * supports permissions. * @see #stop() */ public abstract void uninstall() throws BundleException; /** * Returns this bundle's Manifest headers and values. * This method returns all the Manifest headers and values * from the main section of the bundle's Manifest file; that is, all lines prior * to the first blank line. * * <p>Manifest header names are case-insensitive. The methods of the returned * <tt>Dictionary</tt> object will operate on header names in a case-insensitive manner. * * <p>For example, the following Manifest headers and values are included * if they are present in the Manifest file: * <pre> * Bundle-Name * Bundle-Vendor * Bundle-Version * Bundle-Description * Bundle-DocURL * Bundle-ContactAddress * </pre> * <p>This method will continue to return Manifest header information * while this bundle is in the <tt>UNINSTALLED</tt> state. * * @return A <tt>Dictionary</tt> object containing this bundle's Manifest headers and values. * * @exception java.lang.SecurityException If the caller does not have * the <tt>AdminPermission</tt>, and the Java Runtime Environment supports permissions. */ public abstract Dictionary<String,String> getHeaders(); /** * Returns this bundle's identifier. The bundle is assigned a unique identifier by the Framework * when it is installed in the OSGi environment. * * <p>A bundle's unique identifier has the following attributes: * <ul> * <li>Is unique and persistent. * <li>Is a <tt>long</tt>. * <li>Its value is not reused for another bundle, even after the bundle is uninstalled. * <li>Does not change while the bundle remains installed. * <li>Does not change when the bundle is updated. * </ul> * * <p>This method will continue to return this bundle's unique identifier * while this bundle is in the <tt>UNINSTALLED</tt> state. * * @return The unique identifier of this bundle. */ public abstract long getBundleId(); /** * Returns this bundle's location identifier. * * <p>The bundle location identifier is the location passed to * {@link BundleContext#installBundle}when a bundle is installed. * * <p>This method will continue to return this bundle's location * identifier while this bundle is in the <tt>UNINSTALLED</tt> state. * * @return The string representation of this bundle's location identifier. * @exception java.lang.SecurityException If the caller does not have * the appropriate <tt>AdminPermission</tt>, and the Java Runtime Environment * supports permissions. */ public abstract String getLocation(); /** * Determines if this bundle has the specified permissions. * * <p>If the Java Runtime Environment does not support permissions, * this method always returns <tt>true</tt>. * <p><tt>permission</tt> is of type <tt>Object</tt> to * avoid referencing the <tt>java.security.Permission</tt> class * directly. This is to allow the Framework to be implemented in Java * environments which do not support permissions. * * <p>If the Java Runtime Environment does support permissions, this * bundle and all its resources including nested JAR files, belong * to the same <tt>java.security.ProtectionDomain</tt>; that is, they will share * the same set of permissions. * * @param permission The permission to verify. * * @return <tt>true</tt> if this bundle has the specified permission or * the permissions possessed by this bundle imply the specified permission; * <tt>false</tt> if this bundle does not have the specified permission or <tt>permission</tt> * is not an <tt>instanceof</tt> <tt>java.security.Permission</tt>. * * @exception java.lang.IllegalStateException If this bundle has been uninstalled. */ public abstract boolean hasPermission(Object permission); /** * Find the specified resource in this bundle. * * This bundle's class loader is called to search for the named resource. * If this bundle's state is <tt>INSTALLED</tt>, then only this bundle will * be searched for the specified resource. Imported packages cannot be searched * when a bundle has not been resolved. * * @param name The name of the resource. * See <tt>java.lang.ClassLoader.getResource</tt> for a description of * the format of a resource name. * @return a URL to the named resource, or <tt>null</tt> if the resource could * not be found or if the caller does not have * the <tt>AdminPermission</tt>, and the Java Runtime Environment supports permissions. * * @since 1.1 * @exception java.lang.IllegalStateException If this bundle has been uninstalled. */ public abstract URL getResource(String name); }