blob: cf6cf676502babeef9366308455954d6672fc36d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.container;
import java.io.DataInputStream;
import java.util.EnumSet;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.osgi.container.Module.Settings;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
import org.osgi.framework.startlevel.FrameworkStartLevel;
/**
* Adapts the behavior of a container.
* @since 3.10
*/
public abstract class ModuleContainerAdaptor {
private static Executor defaultExecutor = command -> command.run();
/**
* Event types that may be {@link #publishContainerEvent(ContainerEvent, Module, Throwable, FrameworkListener...) published}
* for a container.
*
*/
public enum ContainerEvent {
/**
* A container {@link ModuleContainer#refresh(java.util.Collection) refresh} operation has completed
*/
REFRESH,
/**
* A container {@link ModuleContainer#getFrameworkStartLevel() start level} change has completed.
*/
START_LEVEL,
/**
* The container has been started.
*/
STARTED,
/**
* This event is returned by {@link SystemModule#waitForStop(long)}
* to indicate that the container has stopped.
*/
STOPPED,
/**
* This event is returned by {@link SystemModule#waitForStop(long)}
* to indicate that the container has stopped because of an update
* operation.
*/
STOPPED_UPDATE,
/**
* This event is returned by {@link SystemModule#waitForStop(long)}
* to indicate that the container has stopped because of an refresh
* operation.
*/
STOPPED_REFRESH,
/**
* This event is returned by {@link SystemModule#waitForStop(long)}
* to indicate that the wait operation has timed out..
*/
STOPPED_TIMEOUT,
/**
* An event fired for an error condition.
*/
ERROR,
/**
* An event fired for a warning condition.
*/
WARNING,
/**
* An event fired for informational purposes only.
*/
INFO
}
/**
* Event types that may be {@link #publishModuleEvent(ModuleEvent, Module, Module) published} for a module
* indicating a {@link Module#getState() state} change has occurred for a module.
*/
public static enum ModuleEvent {
/**
* The module has been installed
*/
INSTALLED,
/**
* The module has been activated with the lazy activation policy and
* is waiting a {@link Module.StartOptions#LAZY_TRIGGER trigger} class load.
*/
LAZY_ACTIVATION,
/**
* The module has been resolved.
*/
RESOLVED,
/**
* The module has beens started.
*/
STARTED,
/**
* The module is about to be activated.
*/
STARTING,
/**
* The module has been stopped.
*/
STOPPED,
/**
* The module is about to be deactivated.
*/
STOPPING,
/**
* The module has been uninstalled.
*/
UNINSTALLED,
/**
* The module has been unresolved.
*/
UNRESOLVED,
/**
* The module has been updated.
*/
UPDATED
}
/**
* Returns the collision hook the container will use.
* @return the collision hook the container will use.
*/
public abstract ModuleCollisionHook getModuleCollisionHook();
/**
* Returns the resolver hook factory the container will use.
* @return the resolver hook factory the container will use.
*/
public abstract ResolverHookFactory getResolverHookFactory();
/**
* Publishes the specified container event.
* No locks are held by the container when this method is called
* @param type the type of event
* @param module the module associated with the event
* @param error the error associated with the event, may be {@code null}
* @param listeners additional listeners to publish the event to synchronously
*/
public abstract void publishContainerEvent(ContainerEvent type, Module module, Throwable error, FrameworkListener... listeners);
/**
* Publishes the specified module event type for the specified module.
* No locks are held by the container when this method is called
* @param type the event type to publish
* @param module the module the event is associated with
* @param origin the module which is the origin of the event. For the event
* type {@link ModuleEvent#INSTALLED}, this is the module whose context was used
* to install the module. Otherwise it is the module itself. May be null only
* when the event is not of type {@link ModuleEvent#INSTALLED}.
*/
public abstract void publishModuleEvent(ModuleEvent type, Module module, Module origin);
/**
* Returns the specified configuration property value
* @param key the key of the configuration property
* @return the configuration property value
*/
public String getProperty(String key) {
return null;
}
/**
* Creates a new {@link ModuleLoader} for the specified wiring.
* @param wiring the module wiring to create a module loader for
* @return a new {@link ModuleLoader} for the specified wiring.
*/
public ModuleLoader createModuleLoader(ModuleWiring wiring) {
throw new UnsupportedOperationException("Container adaptor does not support module class loaders."); //$NON-NLS-1$
}
/**
* Creates a new module. This gets called when a new module is installed
* or when {@link ModuleDatabase#load(DataInputStream) loading} persistent data into this
* database.
* @param location the location for the module
* @param id the id for the module
* @param settings the settings for the module. May be {@code null} if there are no settings.
* @param startlevel the start level for the module
* @return the Module
*/
public abstract Module createModule(String location, long id, EnumSet<Settings> settings, int startlevel);
/**
* Creates the system module. This gets called when the system module is installed
* or when {@link ModuleDatabase#load(DataInputStream) loading} persistent data into this
* database.
* <p>
* The returned system module must have an {@link Module#getId() id} of zero and a location
* of {@link Constants#SYSTEM_BUNDLE_LOCATION System Bundle}.
* @return the system module
*/
public abstract SystemModule createSystemModule();
/**
* Returns the current revision info for a module with the specified location and id
* @param location the location of the module
* @param id the id of the module
* @return the revision info, may be {@code null}
*/
public Object getRevisionInfo(String location, long id) {
return null;
}
/**
* After a revision is created this method is called with the specified revision info.
* @param revision the newly created revision
* @param revisionInfo the revision info that got associated with the revision
*/
public void associateRevision(ModuleRevision revision, Object revisionInfo) {
// do nothing by default
}
/**
* This is called when a wiring is made invalid and allows the adaptor to react
* to this. This method is called while holding state change lock for the
* module as well as for the module database. Care must be taken not to introduce
* deadlock.
* @param moduleWiring the module wiring being invalidated
* @param current the current module loader associated with the wiring, may be <code>null</code>.
*/
public void invalidateWiring(ModuleWiring moduleWiring, ModuleLoader current) {
// do nothing by default
}
/**
* This is called if a request to refresh modules causes the system module
* to be refreshed. This causes the system module to be stopped in a back
* ground thread. This method is called before the background thread is
* started to stop the system module.
*/
public void refreshedSystemModule() {
// do nothing by default
}
/**
* This is called whenever the module database has been updated.
*/
public void updatedDatabase() {
// do nothing by default
}
/**
* This is called when the {@link SystemModule#init()} is running.
*/
public void initBegin() {
// do nothing by default
}
/**
* This is called just before the {@link SystemModule#init()} returns.
*/
public void initEnd() {
// do nothing by default
}
/**
* Returns the debug options for the module container.
* @return the debug options for the module container, or null if there are no debug options.
*/
public DebugOptions getDebugOptions() {
// be default there are no debug options
return null;
}
/**
* Returns the executor used to perform resolve operations
* @return the executor used to perform resolve operations
* @since 3.11
*/
public Executor getResolverExecutor() {
return defaultExecutor;
}
/**
* Returns the executor used to by the
* {@link ModuleContainer#getFrameworkStartLevel() FrameworkStartLevel} implementation to
* start bundles that have the same start level. This allows bundles to be
* started in parallel.
* @return the executor used by the {@link FrameworkStartLevel} implementation.
* @since 3.14
*/
public Executor getStartLevelExecutor() {
return defaultExecutor;
}
/**
* Allows a builder to be modified before it is used by the container. This gets
* call when a new module is {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) installed}
* into the container or when an existing module is {@link ModuleContainer#update(Module, ModuleRevisionBuilder, Object) updated}
* with a new revision. The container does not call any methods on the builder before calling this method.
* @param operation The lifecycle operation event that is in progress using the supplied builder.
* This will be either {@link ModuleEvent#INSTALLED installed} or {@link ModuleEvent#UPDATED updated}.
* @param origin The module which originated the lifecycle operation. The origin may be {@code null} for
* {@link ModuleEvent#INSTALLED installed} operations. This is the module
* passed to the {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) install} or
* {@link ModuleContainer#update(Module, ModuleRevisionBuilder, Object) update} method.
* @param builder the builder that will be used to create a new {@link ModuleRevision}.
* @param revisionInfo the revision info that will be used for the new revision, may be {@code null}.
* @return The modified builder or a completely new builder to be used by the bundle. A {@code null} value
* indicates the original builder should be used, which may have been modified by adding requirements or
* capabilities.
* @since 3.12
*/
public ModuleRevisionBuilder adaptModuleRevisionBuilder(ModuleEvent operation, Module origin, ModuleRevisionBuilder builder, Object revisionInfo) {
// do nothing by default
return null;
}
/**
* Returns the scheduled executor that may be used by the
* container to schedule background tasks.
* @return the scheduled executor, or null if background tasks are not supported
* @since 3.13
*/
public ScheduledExecutorService getScheduledExecutor() {
return null;
}
}