| /* |
| * Copyright (c) OSGi Alliance (2012). All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.osgi.service.subsystem; |
| |
| import java.io.InputStream; |
| import java.util.Collection; |
| import java.util.Locale; |
| import java.util.Map; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Version; |
| import org.osgi.framework.namespace.IdentityNamespace; |
| import org.osgi.resource.Resource; |
| |
| /** |
| * A subsystem is a collection of resources constituting a logical, possibly |
| * isolated, unit of functionality. |
| * |
| * <p> |
| * A subsystem may be <i>scoped</i> or <i>unscoped</i>. Scoped subsystems are |
| * isolated by implicit or explicit sharing policies. Unscoped subsystems are |
| * not isolated and, therefore, have no sharing policy. There are three standard |
| * {@link SubsystemConstants#SUBSYSTEM_TYPE types} of subsystems. |
| * <ul> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_APPLICATION Application} - An |
| * implicitly scoped subsystem. Nothing is exported, and imports are computed |
| * based on any unsatisfied content requirements.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_COMPOSITE Composite} - An |
| * explicitly scoped subsystem. The sharing policy is defined by metadata within |
| * the subsystem archive.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_FEATURE Feature} - An unscoped |
| * subsystem.</li> |
| * </ul> |
| * Conceptually, a subsystem may be thought of as existing in an isolated region |
| * along with zero or more other subsystems. Each region has one and only one |
| * scoped subsystem, which dictates the sharing policy. The region may, however, |
| * have many unscoped subsystems. It is, therefore, possible to have shared |
| * constituents across multiple subsystems within a region. Associated with each |
| * region is a bundle whose context may be {@link #getBundleContext() retrieved} |
| * from any subsystem within that region. This context may be used to monitor |
| * activity occurring within the region. |
| * |
| * <p> |
| * A subsystem may have {@link #getChildren() children} and, unless it's the |
| * root subsystem, must have at least one {@link #getParents() parent}. |
| * Subsystems become children of the subsystem in which they are installed. |
| * Unscoped subsystems have more than one parent if they are installed in more |
| * than one subsystem within the same region. The subsystem graph may be thought |
| * of as an <a |
| * href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">acyclic |
| * digraph</a> with one and only one source vertex, which is the root subsystem. |
| * The edges have the child as the head and parent as the tail. |
| * |
| * <p> |
| * A subsystem has several identifiers. |
| * <ul> |
| * <li>{@link #getLocation() Location} - An identifier specified by the client |
| * as part of installation. It is guaranteed to be unique within the same |
| * framework.</li> |
| * <li>{@link #getSubsystemId() ID} - An identifier generated by the |
| * implementation as part of installation. It is guaranteed to be unique within |
| * the same framework. |
| * <li>{@link #getSymbolicName() Symbolic Name}/{@link #getVersion() Version} - |
| * The combination of symbolic name and version is guaranteed to be unique |
| * within the same region. Although {@link #getType() type} is not formally part |
| * of the identity, two subsystems with the same symbolic names and versions but |
| * different types are not considered to be equal.</li> |
| * </ul> |
| * A subsystem has a well-defined {@link State life cycle}. Which stage a |
| * subsystem is in may be obtained from the subsystem's {@link #getState() |
| * state} and is dependent on which life cycle operation is currently active or |
| * was last invoked. |
| * |
| * <p> |
| * A subsystem archive is a ZIP file having an {@code .esa} extension and |
| * containing metadata describing the subsystem. The form of the metadata may be |
| * a subsystem or deployment manifest, as well as any content resource files. |
| * The manifests are optional and will be computed if not present. The subsystem |
| * manifest headers may be {@link #getSubsystemHeaders(Locale) retrieved} in raw |
| * or localized forms. There are five standard |
| * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE types} of resources that |
| * may be included in a subsystem. |
| * <ul> |
| * <li>{@link IdentityNamespace#TYPE_BUNDLE Bundle} - A bundle that is not a |
| * fragment.</li> |
| * <li>{@link IdentityNamespace#TYPE_FRAGMENT Fragment} - A fragment bundle.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_APPLICATION Application |
| * Subsystem} - An application subsystem.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_COMPOSITE Composite Subsystem} - |
| * A composite subsystem.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_FEATURE Feature Subsystem} - A |
| * feature subsystem.</li> |
| * </ul> |
| * Resources contained by a subsystem are called {@link #getConstituents() |
| * constituents}. There are several ways a resource may become a constituent of |
| * a subsystem: |
| * <ul> |
| * <li>A resource is listed as part of the subsystem's content.</li> |
| * <li>A subsystem resource is a child of the subsystem.</li> |
| * <li>The subsystem has a provision policy of accept dependencies.</li> |
| * <li>A bundle resource is installed using the region bundle context.</li> |
| * <li>A bundle resource is installed using the bundle context of another |
| * resource contained by the subsystem.</li> |
| * </ul> |
| * |
| * <p> |
| * In addition to invoking one of the install methods, a subsystem instance may |
| * be obtained through the service registry. Each installed subsystem has a |
| * corresponding service registration. A subsystem service has the following |
| * properties. |
| * |
| * <ul> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_ID_PROPERTY ID} - The ID of the |
| * subsystem.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_SYMBOLICNAME_PROPERTY Symbolic Name} |
| * - The symbolic name of the subsystem.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_VERSION_PROPERTY Version} - The |
| * version of the subsystem.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_TYPE_PROPERTY Type} - The type of the |
| * subsystem.</li> |
| * <li>{@link SubsystemConstants#SUBSYSTEM_STATE_PROPERTY State} - The state of |
| * the subsystem.</li> |
| * </ul> |
| * |
| * <p> |
| * Because a subsystem must be used to install other subsystems, a root |
| * subsystem is provided as a starting point. The root subsystem may only be |
| * obtained as a service and has the following characteristics. |
| * |
| * <ul> |
| * <li>The ID is {@code 0}.</li> |
| * <li>The symbolic name is |
| * {@link SubsystemConstants#ROOT_SUBSYSTEM_SYMBOLICNAME |
| * org.osgi.service.subsystem.root}.</li> |
| * <li>The version matches this specification's version.</li> |
| * <li>It has no parents.</li> |
| * <li>All existing bundles, including the system and subsystem implementation |
| * bundles, are constituents.</li> |
| * <li>The type is {@link SubsystemConstants#SUBSYSTEM_TYPE_APPLICATION |
| * osgi.subsystem.application} with no imports.</li> |
| * <li>The provision policy is |
| * {@link SubsystemConstants#PROVISION_POLICY_ACCEPT_DEPENDENCIES |
| * acceptDependencies}.</li> |
| * </ul> |
| * |
| * @ThreadSafe |
| * @noimplement |
| * @version $Id: 73028a6997272cbac7e90ae00eb0f28afd14c8ee $ |
| */ |
| public interface Subsystem { |
| /** |
| * An enumeration of the possible states of a subsystem. |
| * |
| * <p> |
| * These states are a reflection of what constituent resources are permitted |
| * to do and not an aggregation of constituent resource states. |
| */ |
| public static enum State { |
| /** |
| * The subsystem is in the process of installing. |
| * <p> |
| * A subsystem is in the {@code INSTALLING} state when the |
| * {@link Subsystem#install(String, InputStream) install} method of its |
| * parent is active, and attempts are being made to install its content |
| * resources. If the install method completes without exception, then |
| * the subsystem has successfully installed and must move to the |
| * {@link #INSTALLED} state. Otherwise, the subsystem has failed to |
| * install and must move to the {@link #INSTALL_FAILED} state. |
| */ |
| INSTALLING, |
| /** |
| * The subsystem is installed but not yet resolved. |
| * <p> |
| * A subsystem is in the {@code INSTALLED} state when it has been |
| * installed in a parent subsystem but is not or cannot be resolved. |
| * This state is visible if the dependencies of the subsystem's content |
| * resources cannot be resolved. |
| */ |
| INSTALLED, |
| /** |
| * The subsystem failed to install. |
| * <p> |
| * A subsystem is in the {@code INSTALL_FAILED} state when an |
| * unrecoverable error occurred during installation. The subsystem is in |
| * an unusable state but references to the subsystem object may still be |
| * available and used for introspection. |
| */ |
| INSTALL_FAILED, |
| /** |
| * The subsystem is in the process of resolving. |
| * <p> |
| * A subsystem is in the {@code RESOLVING} state when the |
| * {@link Subsystem#start() start} method is active, and attempts are |
| * being made to resolve its content resources. If the resolve method |
| * completes without exception, then the subsystem has successfully |
| * resolved and must move to the {@link #RESOLVED} state. Otherwise, the |
| * subsystem has failed to resolve and must move to the INSTALLED state. |
| */ |
| RESOLVING, |
| /** |
| * The subsystem is resolved and able to be started. |
| * <p> |
| * A subsystem is in the {@code RESOLVED} state when all of its content |
| * resources are resolved. Note that the subsystem is not active yet. |
| */ |
| RESOLVED, |
| /** |
| * The subsystem is in the process of starting. |
| * <p> |
| * A subsystem is in the {@code STARTING} state when its |
| * {@link Subsystem#start() start} method is active, and attempts are |
| * being made to start its content and dependencies. If the start method |
| * completes without exception, then the subsystem has successfully |
| * started and must move to the {@link #ACTIVE} state. Otherwise, the |
| * subsystem has failed to start and must move to the {@link #RESOLVED} |
| * state. |
| */ |
| STARTING, |
| /** |
| * The subsystem is now running. |
| * <p> |
| * A subsystem is in the {@code ACTIVE} state when its content and |
| * dependencies have been successfully started. |
| */ |
| ACTIVE, |
| /** |
| * The subsystem is in the process of stopping. |
| * <p> |
| * A subsystem is in the {@code STOPPING} state when its |
| * {@link Subsystem#stop() stop} method is active, and attempts are |
| * being made to stop its content and dependencies. When the stop method |
| * completes, the subsystem is stopped and must move to the |
| * {@link #RESOLVED} state. |
| */ |
| STOPPING, |
| /** |
| * The subsystem is in the process of uninstalling. |
| * <p> |
| * A subsystem is in the {@code UNINSTALLING} state when its |
| * {@link Subsystem#uninstall() uninstall} method is active, and |
| * attempts are being made to uninstall its constituent and |
| * dependencies. When the uninstall method completes, the subsystem is |
| * uninstalled and must move to the {@link #UNINSTALLED} state. |
| */ |
| UNINSTALLING, |
| /** |
| * The subsystem is uninstalled and may not be used. |
| * <p> |
| * The {@code UNINSTALLED} state is only visible after a subsystem's |
| * constituent and dependencies are uninstalled. The subsystem is in an |
| * unusable state but references to the subsystem object may still be |
| * available and used for introspection. |
| */ |
| UNINSTALLED |
| } |
| |
| /** |
| * Returns the bundle context of the region within which this subsystem |
| * resides. |
| * <p> |
| * The bundle context offers the same perspective of any resource contained |
| * by a subsystem within the region. It may be used, for example, to monitor |
| * events internal to the region as well as external events visible to the |
| * region. All subsystems within the same region have the same bundle |
| * context. If this subsystem is in a state where the bundle context would |
| * be invalid, {@code null} is returned. |
| * |
| * @return The bundle context of the region within which this subsystem |
| * resides or {@code null} if this subsystem's state is in |
| * {@link State#INSTALL_FAILED INSTALL_FAILED}, |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[this,CONTEXT], and the runtime |
| * supports permissions. |
| */ |
| public BundleContext getBundleContext(); |
| |
| /** |
| * Returns the child subsystems of this subsystem. |
| * |
| * @return The child subsystems of this subsystem. The returned collection |
| * is an unmodifiable snapshot of all subsystems that are installed |
| * in this subsystem. The collection will be empty if no subsystems |
| * are installed in this subsystem. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALL_FAILED INSTALL_FAILED}, |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| */ |
| public Collection<Subsystem> getChildren(); |
| |
| /** |
| * Returns the headers for this subsystem's subsystem manifest. |
| * <p> |
| * Each key in the map is a header name and the value of the key is the |
| * corresponding header value. Because header names are case-insensitive, |
| * the methods of the map must treat the keys in a case-insensitive manner. |
| * If the header name is not found, {@code null} is returned. Both original |
| * and derived headers will be included in the map. |
| * <p> |
| * This method must continue to return the headers while this subsystem is |
| * in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @param locale The locale for which translations are desired. The header |
| * values are translated according to the specified locale. If the |
| * specified locale is {@code null} or not supported, the raw values |
| * are returned. If the translation for a particular header is not |
| * found, the raw value is returned. |
| * @return The headers for this subsystem's subsystem manifest. The returned |
| * map is unmodifiable. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[this,METADATA], and the runtime |
| * supports permissions. |
| */ |
| public Map<String, String> getSubsystemHeaders(Locale locale); |
| |
| /** |
| * Returns the location identifier of this subsystem. |
| * <p> |
| * The location identifier is the {@code location} that was passed to the |
| * {@link #install(String, InputStream) install} method of the |
| * {@link #getParents() parent} subsystem. It is unique within the |
| * framework. |
| * <p> |
| * This method must continue to return this subsystem's headers while this |
| * subsystem is in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @return The location identifier of this subsystem. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[this,METADATA], and the runtime |
| * supports permissions. |
| */ |
| public String getLocation(); |
| |
| /** |
| * Returns the parent subsystems of this subsystem. |
| * |
| * @return The parent subsystems of this subsystem. The returned collection |
| * is an unmodifiable snapshot of all subsystems in which this |
| * subsystem is installed. The collection will be empty for the root |
| * subsystem; otherwise, it must contain at least one parent. Scoped |
| * subsystems always have only one parent. Unscoped subsystems may |
| * have multiple parents. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALL_FAILED INSTALL_FAILED}, |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| */ |
| public Collection<Subsystem> getParents(); |
| |
| /** |
| * Returns the constituent resources of this subsystem. |
| * |
| * @return The constituent resources of this subsystem. The returned |
| * collection is an unmodifiable snapshot of the constituent |
| * resources of this subsystem. If this subsystem has no |
| * constituents, the collection will be empty. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALL_FAILED INSTALL_FAILED}, |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| */ |
| public Collection<Resource> getConstituents(); |
| |
| /** |
| * Returns the current state of this subsystem. |
| * <p> |
| * This method must continue to return this subsystem's state while this |
| * subsystem is in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @return The current state of this subsystem. |
| */ |
| public State getState(); |
| |
| /** |
| * Returns the identifier of this subsystem. |
| * <p> |
| * The identifier is a monotonically increasing, non-negative integer |
| * automatically generated at installation time and guaranteed to be unique |
| * within the framework. The identifier of the root subsystem is zero. |
| * <p> |
| * This method must continue to return this subsystem's identifier while |
| * this subsystem is in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @return The identifier of this subsystem. |
| */ |
| public long getSubsystemId(); |
| |
| /** |
| * Returns the symbolic name of this subsystem. |
| * <p> |
| * The subsystem symbolic name conforms to the same grammar rules as the |
| * bundle symbolic name and is derived from one of the following, in order. |
| * <ul> |
| * <li>The value of the {@link SubsystemConstants#SUBSYSTEM_SYMBOLICNAME |
| * Subsystem-SymbolicName} header, if specified.</li> |
| * <li>The subsystem URI if passed as the {@code location} along with the |
| * {@code content} to the {@link #install(String, InputStream) install} |
| * method.</li> |
| * <li>Optionally generated in an implementation specific way.</li> |
| * </ul> |
| * The combination of subsystem symbolic name and {@link #getVersion() |
| * version} is unique within a region. The symbolic name of the root |
| * subsystem is {@link SubsystemConstants#ROOT_SUBSYSTEM_SYMBOLICNAME |
| * org.osgi.service.subsystem.root}. |
| * <p> |
| * This method must continue to return this subsystem's symbolic name while |
| * this subsystem is in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @return The symbolic name of this subsystem. |
| */ |
| public String getSymbolicName(); |
| |
| /** |
| * Returns the {@link SubsystemConstants#SUBSYSTEM_TYPE type} of this |
| * subsystem. |
| * <p> |
| * This method must continue to return this subsystem's type while this |
| * subsystem is in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @return The type of this subsystem. |
| */ |
| public String getType(); |
| |
| /** |
| * Returns the {@link SubsystemConstants#SUBSYSTEM_VERSION version} of this |
| * subsystem. |
| * <p> |
| * The subsystem version conforms to the same grammar rules as the bundle |
| * version and is derived from one of the following, in order. |
| * <ul> |
| * <li>The value of the {@link SubsystemConstants#SUBSYSTEM_VERSION |
| * Subsystem-Version} header, if specified.</li> |
| * <li>The subsystem URI if passed as the {@code location} along with the |
| * {@code content} to the {@link #install(String, InputStream) install} |
| * method.</li> |
| * <li>Defaults to {@code 0.0.0}.</li> |
| * </ul> |
| * The combination of subsystem {@link #getSymbolicName() symbolic name} and |
| * version is unique within a region. The version of the root subsystem |
| * matches this specification's version. |
| * <p> |
| * This method must continue to return this subsystem's version while this |
| * subsystem is in the {@link State#INSTALL_FAILED INSTALL_FAILED} or |
| * {@link State#UNINSTALLED UNINSTALLED} states. |
| * |
| * @return The version of this subsystem. |
| */ |
| public Version getVersion(); |
| |
| /** |
| * Installs a subsystem from the specified location identifier. |
| * <p> |
| * This method performs the same function as calling |
| * {@link #install(String, InputStream)} with the specified location |
| * identifier and {@code null} as the content. |
| * |
| * @param location The location identifier of the subsystem to install. |
| * @return The installed subsystem. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALLING INSTALLING}, {@link State#INSTALL_FAILED |
| * INSTALL_FAILED}, {@link State#UNINSTALLING UNINSTALLING}, |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| * @throws SubsystemException If the installation failed. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[installed subsystem,LIFECYCLE], and |
| * the runtime supports permissions. |
| * @see #install(String, InputStream) |
| */ |
| public Subsystem install(String location); |
| |
| /** |
| * Installs a subsystem from the specified content. |
| * <p> |
| * The specified location will be used as an identifier of the subsystem. |
| * Every installed subsystem is uniquely identified by its location, which |
| * is typically in the form of a URI. If the specified location conforms to |
| * the {@code subsystem-uri} grammar, the required symbolic name and |
| * optional version information will be used as default values. |
| * <p> |
| * If the specified content is {@code null}, a new input stream must be |
| * created from which to read the subsystem by interpreting, in an |
| * implementation dependent manner, the specified location. |
| * <p> |
| * A subsystem installation must be persistent. That is, an installed |
| * subsystem must remain installed across Framework and VM restarts. |
| * <p> |
| * All references to changing the state of this subsystem include both |
| * changing the state of the subsystem object as well as the state property |
| * of the subsystem service registration. |
| * <p> |
| * The following steps are required to install a subsystem. |
| * <ol> |
| * <li>If an installed subsystem with the specified location identifier |
| * already exists, return the installed subsystem.</li> |
| * <li>Read the specified content in order to determine the symbolic name, |
| * version, and type of the installing subsystem. If an error occurs while |
| * reading the content, an installation failure results.</li> |
| * <li>If an installed subsystem with the same symbolic name and version |
| * already exists within this subsystem's region, complete the installation |
| * with one of the following.<br/> |
| * - If the installing and installed subsystems' types are not equal, an |
| * installation failure results.<br/> |
| * - If the installing and installed subsystems' types are equal, and the |
| * installed subsystem is already a child of this subsystem, return the |
| * installed subsystem.<br/> |
| * - If the installing and installed subsystems' types are equal, and the |
| * installed subsystem is not already a child of this subsystem, add the |
| * installed subsystem as a child of this subsystem, increment the installed |
| * subsystem's reference count by one, and return the installed subsystem. |
| * <li>Create a new subsystem based on the specified location and content.</li> |
| * <li>If the subsystem is scoped, install and start a new region context |
| * bundle.</li> |
| * <li>Change the state to {@link State#INSTALLING INSTALLING} and register |
| * a new subsystem service.</li> |
| * <li>Discover the subsystem's content resources. If any mandatory resource |
| * is missing, an installation failure results.</li> |
| * <li>Discover the dependencies required by the content resources. If any |
| * mandatory dependency is missing, an installation failure results.</li> |
| * <li>Using a framework {@code ResolverHook}, disable runtime resolution |
| * for the resources.</li> |
| * <li>For each resource, increment the reference count by one. If the |
| * reference count is one, install the resource. If an error occurs while |
| * installing a resource, an install failure results with that error as the |
| * cause.</li> |
| * <li>If the subsystem is scoped, enable the import sharing policy.</li> |
| * <li>Enable runtime resolution for the resources.</li> |
| * <li>Change the state of the subsystem to {@link State#INSTALLED |
| * INSTALLED}.</li> |
| * <li>Return the new subsystem.</li> |
| * </ol> |
| * <p> |
| * Implementations should be sensitive to the potential for long running |
| * operations and periodically check the current thread for interruption. An |
| * interrupted thread should result in a {@link SubsystemException} with an |
| * InterruptedException as the cause and be treated as an installation |
| * failure. |
| * <p> |
| * All installation failure flows include the following, in order. |
| * <ol> |
| * <li>Change the state to {@link State#INSTALL_FAILED INSTALL_FAILED}.</li> |
| * <li>Change the state to {@link State#UNINSTALLING UNINSTALLING}.</li> |
| * <li>All content and dependencies which may have been installed by the |
| * installing process must be uninstalled. |
| * <li>Change the state to {@link State#UNINSTALLED UNINSTALLED}.</li> |
| * <li>Unregister the subsystem service.</li> |
| * <li>If the subsystem is a scoped subsystem then, uninstall the region |
| * context bundle.</li> |
| * <li>Throw a {@link SubsystemException} with the cause of the installation |
| * failure.</li> |
| * </ol> |
| * |
| * @param location The location identifier of the subsystem to be installed. |
| * @param content The input stream from which this subsystem will be read or |
| * {@code null} to indicate the input stream must be created from the |
| * specified location identifier. The input stream will always be |
| * closed when this method completes, even if an exception is thrown. |
| * @return The installed subsystem. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALLING INSTALLING}, {@link State#INSTALL_FAILED |
| * INSTALL_FAILED}, {@link State#UNINSTALLING UNINSTALLING}, |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| * @throws SubsystemException If the installation failed. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[installed subsystem,LIFECYCLE], and |
| * the runtime supports permissions. |
| */ |
| public Subsystem install(String location, InputStream content); |
| |
| /** |
| * Starts this subsystem. |
| * <p> |
| * The following table shows which actions are associated with each state. |
| * An action of {@code Wait} means this method will block until a state |
| * transition occurs, upon which the new state will be evaluated in order to |
| * determine how to proceed. If a state transition does not occur in a |
| * reasonable time while waiting then no action is taken and a |
| * SubsystemException is thrown to indicate the subsystem was unable to be |
| * started. An action of {@code Return} means this method returns |
| * immediately without taking any other action. |
| * </p> |
| * <table> |
| * <tr> |
| * <th>State</th> |
| * <th width="4">Action</th> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALLING INSTALLING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALLED INSTALLED}</td> |
| * <td>{@code Resolve}<br/> |
| * {@code Start}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALL_FAILED INSTALL_FAILED}</td> |
| * <td>{@code IllegalStateException}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#RESOLVING RESOLVING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#RESOLVED RESOLVED}</td> |
| * <td>{@code Start}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#STARTING STARTING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#ACTIVE ACTIVE}</td> |
| * <td>{@code Return}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#STOPPING STOPPING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#UNINSTALLING UNINSTALLING}</td> |
| * <td>{@code IllegalStateException}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#UNINSTALLED UNINSTALLED}</td> |
| * <td>{@code IllegalStateException}</td> |
| * </tr> |
| * </table> |
| * <p> |
| * All references to changing the state of this subsystem include both |
| * changing the state of the subsystem object as well as the state property |
| * of the subsystem service registration. |
| * <p> |
| * A subsystem must be persistently started. That is, a started subsystem |
| * must be restarted across Framework and VM restarts, even if a start |
| * failure occurs. |
| * <p> |
| * The following steps are required to start this subsystem. |
| * <ol> |
| * <li>Set the subsystem <i>autostart setting</i> to <i>started</i>.</li> |
| * <li>If this subsystem is in the {@link State#RESOLVED RESOLVED} state, |
| * proceed to step 7.</li> |
| * <li>Change the state to {@link State#RESOLVING RESOLVING}.</li> |
| * <li>Resolve the content resources. A resolution failure results in a |
| * start failure with a state of {@link State#INSTALLED INSTALLED}.</li> |
| * <li>Change the state to {@link State#RESOLVED RESOLVED}.</li> |
| * <li>If this subsystem is scoped, enable the export sharing policy.</li> |
| * <li>Change the state to {@link State#STARTING STARTING}.</li> |
| * <li>For each eligible resource, increment the active use count by one. If |
| * the active use count is one, start the resource. All dependencies must be |
| * started before any content resource, and content resources must be |
| * started according to the specified |
| * {@link SubsystemConstants#START_ORDER_DIRECTIVE start order}. If an error |
| * occurs while starting a resource, a start failure results with that error |
| * as the cause.</li> |
| * <li>Change the state to {@link State#ACTIVE ACTIVE}.</li> |
| * </ol> |
| * <p> |
| * Implementations should be sensitive to the potential for long running |
| * operations and periodically check the current thread for interruption. An |
| * interrupted thread should be treated as a start failure with an |
| * {@code InterruptedException} as the cause. |
| * <p> |
| * All start failure flows include the following, in order. |
| * <ol> |
| * <li>If the subsystem state is {@link State#STARTING STARTING} then change |
| * the state to {@link State#STOPPING STOPPING} and stop all resources that |
| * were started as part of this operation.</li> |
| * <li>Change the state to either {@link State#INSTALLED INSTALLED} or |
| * {@link State#RESOLVED RESOLVED}.</li> |
| * <li>Throw a SubsystemException with the specified cause.</li> |
| * </ol> |
| * |
| * @throws SubsystemException If this subsystem fails to start. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALL_FAILED INSTALL_FAILED}, |
| * {@link State#UNINSTALLING UNINSTALLING}, or |
| * {@link State#UNINSTALLED UNINSTALLED}, or if the state of at |
| * least one of this subsystem's parents is not in |
| * {@link State#STARTING STARTING}, {@link State#ACTIVE ACTIVE}. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[this,EXECUTE], and the runtime |
| * supports permissions. |
| */ |
| public void start(); |
| |
| /** |
| * Stops this subsystem. |
| * <p> |
| * The following table shows which actions are associated with each state. |
| * An action of {@code Wait} means this method will block until a state |
| * transition occurs, upon which the new state will be evaluated in order to |
| * determine how to proceed. If a state transition does not occur in a |
| * reasonable time while waiting then no action is taken and a |
| * SubsystemException is thrown to indicate the subsystem was unable to be |
| * stopped. An action of {@code Return} means this method returns |
| * immediately without taking any other action. |
| * </p> |
| * <table> |
| * <tr> |
| * <th>State</th> |
| * <th width="4">Action</th> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALLING INSTALLING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALLED INSTALLED}</td> |
| * <td>{@code Return}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#INSTALL_FAILED INSTALL_FAILED}</td> |
| * <td>{@code IllegalStateException}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#RESOLVING RESOLVING}</td> |
| * <td>{@code Wait}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#RESOLVED RESOLVED}</td> |
| * <td>{@code Return}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#STARTING STARTING}</td> |
| * <td>{@code Wait}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#ACTIVE ACTIVE}</td> |
| * <td>{@code Stop}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#STOPPING STOPPING}</td> |
| * <td>{@code Wait}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#UNINSTALLING UNINSTALLING}</td> |
| * <td>{@code IllegalStateException}</td> |
| * <td> |
| * <tr> |
| * <td>{@link State#UNINSTALLED UNINSTALLED}</td> |
| * <td>{@code IllegalStateException}</td> |
| * <td> |
| * </table> |
| * <p> |
| * A subsystem must be persistently stopped. That is, a stopped subsystem |
| * must remain stopped across Framework and VM restarts. |
| * <p> |
| * All references to changing the state of this subsystem include both |
| * changing the state of the subsystem object as well as the state property |
| * of the subsystem service registration. |
| * <p> |
| * The following steps are required to stop this subsystem. |
| * <ol> |
| * <li>Set the subsystem <i>autostart setting</i> to <i>stopped</i>.</li> |
| * <li>Change the state to {@link State#STOPPING STOPPING}.</li> |
| * <li>For each eligible resource, decrement the active use count by one. If |
| * the active use count is zero, stop the resource. All content resources |
| * must be stopped before any dependencies, and content resources must be |
| * stopped in reverse {@link SubsystemConstants#START_ORDER_DIRECTIVE start |
| * order}.</li> |
| * <li>Change the state to {@link State#RESOLVED RESOLVED}.</li> |
| * </ol> |
| * With regard to error handling, once this subsystem has transitioned to |
| * the {@link State#STOPPING STOPPING} state, every part of each step above |
| * must be attempted. Errors subsequent to the first should be logged. Once |
| * the stop process has completed, a SubsystemException must be thrown with |
| * the initial error as the specified cause. |
| * <p> |
| * Implementations should be sensitive to the potential for long running |
| * operations and periodically check the current thread for interruption, in |
| * which case a SubsystemException with an InterruptedException as the cause |
| * should be thrown. If an interruption occurs while waiting, this method |
| * should terminate immediately. Once the transition to the |
| * {@link State#STOPPING STOPPING} state has occurred, however, this method |
| * must not terminate due to an interruption until the stop process has |
| * completed. |
| * |
| * @throws SubsystemException If this subsystem fails to stop cleanly. |
| * @throws IllegalStateException If this subsystem's state is in |
| * {@link State#INSTALL_FAILED INSTALL_FAILED}, |
| * {@link State#UNINSTALLING UNINSTALLING}, or |
| * {@link State#UNINSTALLED UNINSTALLED}. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[this,EXECUTE], and the runtime |
| * supports permissions. |
| */ |
| public void stop(); |
| |
| /** |
| * Uninstalls this subsystem. |
| * <p> |
| * The following table shows which actions are associated with each state. |
| * An action of {@code Wait} means this method will block until a state |
| * transition occurs, upon which the new state will be evaluated in order to |
| * determine how to proceed. If a state transition does not occur in a |
| * reasonable time while waiting then no action is taken and a |
| * SubsystemException is thrown to indicate the subsystem was unable to be |
| * uninstalled. An action of {@code Return} means this method returns |
| * immediately without taking any other action. |
| * <table> |
| * <tr> |
| * <th>State</th> |
| * <th width="4">Action</th> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALLING INSTALLING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALLED INSTALLED}</td> |
| * <td>{@code Uninstall}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#INSTALL_FAILED INSTALL_FAILED}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#RESOLVING RESOLVING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#RESOLVED RESOLVED}</td> |
| * <td>{@code Uninstall}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#STARTING STARTING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#ACTIVE ACTIVE}</td> |
| * <td>{@code Stop}<br/> |
| * {@code Uninstall}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#STOPPING STOPPING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#UNINSTALLING UNINSTALLING}</td> |
| * <td>{@code Wait}</td> |
| * </tr> |
| * <tr> |
| * <td>{@link State#UNINSTALLED UNINSTALLED}</td> |
| * <td>{@code Return}</td> |
| * </tr> |
| * </table> |
| * <p> |
| * All references to changing the state of this subsystem include both |
| * changing the state of the subsystem object as well as the state property |
| * of the subsystem service registration. |
| * <p> |
| * The following steps are required to uninstall this subsystem after being |
| * stopped if necessary. |
| * <ol> |
| * <li>Change the state to {@link State#INSTALLED INSTALLED}.</li> |
| * <li>Change the state to {@link State#UNINSTALLING UNINSTALLING}.</li> |
| * <li>For each referenced resource, decrement the reference count by one. |
| * If the reference count is zero, uninstall the resource. All content |
| * resources must be uninstalled before any dependencies.</li> |
| * <li>Change the state to {@link State#UNINSTALLED UNINSTALLED}.</li> |
| * <li>Unregister the subsystem service.</li> |
| * <li>If the subsystem is scoped, uninstall the region context bundle.</li> |
| * </ol> |
| * With regard to error handling, once this subsystem has transitioned to |
| * the {@link State#UNINSTALLING UNINSTALLING} state, every part of each |
| * step above must be attempted. Errors subsequent to the first should be |
| * logged. Once the uninstall process has completed, a |
| * {@code SubsystemException} must be thrown with the specified cause. |
| * <p> |
| * Implementations should be sensitive to the potential for long running |
| * operations and periodically check the current thread for interruption, in |
| * which case a {@code SubsystemException} with an |
| * {@code InterruptedException} as the cause should be thrown. If an |
| * interruption occurs while waiting, this method should terminate |
| * immediately. Once the transition to the {@link State#UNINSTALLING |
| * UNINSTALLING} state has occurred, however, this method must not terminate |
| * due to an interruption until the uninstall process has completed. |
| * |
| * @throws SubsystemException If this subsystem fails to uninstall cleanly. |
| * @throws SecurityException If the caller does not have the appropriate |
| * {@link SubsystemPermission}[this,LIFECYCLE], and the runtime |
| * supports permissions. |
| */ |
| public void uninstall(); |
| } |