org.osgi.service.blueprint.container.BlueprintEvent Maven / Gradle / Ivy
/*
* Copyright (c) OSGi Alliance (2008, 2010). 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.blueprint.container;
import org.osgi.framework.Bundle;
/**
* A Blueprint Event.
*
*
* {@code BlueprintEvent} objects are delivered to all registered
* {@link BlueprintListener} services. Blueprint Events must be asynchronously
* delivered in chronological order with respect to each listener.
*
*
* In addition, after a Blueprint Listener is registered, the Blueprint extender
* will synchronously send to this Blueprint Listener the last Blueprint Event
* for each ready Blueprint bundle managed by this extender. This
* replay of Blueprint Events is designed so that the new Blueprint
* Listener can be informed of the state of each Blueprint bundle. Blueprint
* Events sent during this replay will have the {@link #isReplay()} flag set.
* The Blueprint extender must ensure that this replay phase does not interfere
* with new Blueprint Events so that the chronological order of all Blueprint
* Events received by the Blueprint Listener is preserved. If the last Blueprint
* Event for a given Blueprint bundle is {@link #DESTROYED}, the extender must
* not send it during this replay phase.
*
*
* A type code is used to identify the type of event. The following event types
* are defined:
*
* - {@link #CREATING}
* - {@link #CREATED}
* - {@link #DESTROYING}
* - {@link #DESTROYED}
* - {@link #FAILURE}
* - {@link #GRACE_PERIOD}
* - {@link #WAITING}
*
*
*
* In addition to calling the registered {@link BlueprintListener} services, the
* Blueprint extender must also send those events to the Event Admin service, if
* it is available.
*
* @see BlueprintListener
* @see EventConstants
* @Immutable
* @version $Id: 29fce52f21d5583af483659f8cb06e664894d938 $
*/
public class BlueprintEvent {
/**
* The Blueprint extender has started creating a Blueprint Container for the
* bundle.
*/
public static final int CREATING = 1;
/**
* The Blueprint extender has created a Blueprint Container for the bundle.
* This event is sent after the Blueprint Container has been registered as a
* service.
*/
public static final int CREATED = 2;
/**
* The Blueprint extender has started destroying the Blueprint Container for
* the bundle.
*/
public static final int DESTROYING = 3;
/**
* The Blueprint Container for the bundle has been completely destroyed.
* This event is sent after the Blueprint Container has been unregistered as
* a service.
*/
public static final int DESTROYED = 4;
/**
* The Blueprint Container creation for the bundle has failed. If this event
* is sent after a timeout in the Grace Period, the
* {@link #getDependencies()} method must return an array of missing
* mandatory dependencies. The event must also contain the cause of the
* failure as a {@code Throwable} through the {@link #getCause()}
* method.
*/
public static final int FAILURE = 5;
/**
* The Blueprint Container has entered the grace period. The list of missing
* dependencies must be made available through the
* {@link #getDependencies()} method. During the grace period, a
* {@link #GRACE_PERIOD} event is sent each time the set of unsatisfied
* dependencies changes.
*/
public static final int GRACE_PERIOD = 6;
/**
* The Blueprint Container is waiting on the availability of a service to
* satisfy an invocation on a referenced service. The missing dependency
* must be made available through the {@link #getDependencies()} method
* which will return an array containing one filter object as a String.
*/
public static final int WAITING = 7;
/**
* Type of this event.
*
* @see #getType()
*/
private final int type;
/**
* The time when the event occurred.
*
* @see #getTimestamp()
*/
private final long timestamp;
/**
* The Blueprint bundle.
*
* @see #getBundle()
*/
private final Bundle bundle;
/**
* The Blueprint extender bundle.
*
* @see #getExtenderBundle()
*/
private final Bundle extenderBundle;
/**
* An array containing filters identifying the missing dependencies. Must
* not be {@code null} when the event type requires it.
*
* @see #getDependencies()
*/
private final String[] dependencies;
/**
* Cause of the failure.
*
* @see #getCause()
*/
private final Throwable cause;
/**
* Indicate if this event is a replay event or not.
*
* @see #isReplay()
*/
private final boolean replay;
/**
* Create a simple {@code BlueprintEvent} object.
*
* @param type The type of this event.
* @param bundle The Blueprint bundle associated with this event. This
* parameter must not be {@code null}.
* @param extenderBundle The Blueprint extender bundle that is generating
* this event. This parameter must not be {@code null}.
*/
public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle) {
this(type, bundle, extenderBundle, null, null);
}
/**
* Create a {@code BlueprintEvent} object associated with a set of
* dependencies.
*
* @param type The type of this event.
* @param bundle The Blueprint bundle associated with this event. This
* parameter must not be {@code null}.
* @param extenderBundle The Blueprint extender bundle that is generating
* this event. This parameter must not be {@code null}.
* @param dependencies An array of {@code String} filters for each
* dependency associated with this event. Must be a non-empty array
* for event types {@link #GRACE_PERIOD} and {@link #WAITING}. It is
* optional for event type {@link #FAILURE}. Must be
* {@code null} for other event types.
*/
public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
String[] dependencies) {
this(type, bundle, extenderBundle, dependencies, null);
}
/**
* Create a {@code BlueprintEvent} object associated with a failure
* cause.
*
* @param type The type of this event.
* @param bundle The Blueprint bundle associated with this event. This
* parameter must not be {@code null}.
* @param extenderBundle The Blueprint extender bundle that is generating
* this event. This parameter must not be {@code null}.
* @param cause A {@code Throwable} object describing the root cause of
* the event. May be {@code null}.
*/
public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
Throwable cause) {
this(type, bundle, extenderBundle, null, cause);
}
/**
* Create a {@code BlueprintEvent} object associated with a failure
* cause and a set of dependencies.
*
* @param type The type of this event.
* @param bundle The Blueprint bundle associated with this event. This
* parameter must not be {@code null}.
* @param extenderBundle The Blueprint extender bundle that is generating
* this event. This parameter must not be {@code null}.
* @param dependencies An array of {@code String} filters for each
* dependency associated with this event. Must be a non-empty array
* for event types {@link #GRACE_PERIOD} and {@link #WAITING}. It is
* optional for event type {@link #FAILURE}. Must be
* {@code null} for other event types.
* @param cause A {@code Throwable} object describing the root cause of
* this event. May be {@code null}.
*/
public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
String[] dependencies, Throwable cause) {
this.type = type;
this.timestamp = System.currentTimeMillis();
this.bundle = bundle;
this.extenderBundle = extenderBundle;
this.dependencies = dependencies == null ? null
: (String[]) dependencies.clone();;
this.cause = cause;
this.replay = false;
if (bundle == null) {
throw new NullPointerException("bundle must not be null");
}
if (extenderBundle == null) {
throw new NullPointerException("extenderBundle must not be null");
}
switch (type) {
case WAITING :
case GRACE_PERIOD :
if (dependencies == null) {
throw new NullPointerException(
"dependencies must not be null");
}
if (dependencies.length == 0) {
throw new IllegalArgumentException(
"dependencies must not be length zero");
}
break;
case FAILURE :
if ((dependencies != null) && (dependencies.length == 0)) {
throw new IllegalArgumentException(
"dependencies must not be length zero");
}
break;
default :
if (dependencies != null) {
throw new IllegalArgumentException(
"dependencies must be null");
}
break;
}
}
/**
* Create a new {@code BlueprintEvent} from the specified
* {@code BlueprintEvent}. The {@code timestamp} property will be
* copied from the original event and only the replay property will be
* overridden with the given value.
*
* @param event The original {@code BlueprintEvent} to copy. Must not
* be {@code null}.
* @param replay {@code true} if this event should be used as a replay
* event.
*/
public BlueprintEvent(BlueprintEvent event, boolean replay) {
this.type = event.type;
this.timestamp = event.timestamp;
this.bundle = event.bundle;
this.extenderBundle = event.extenderBundle;
this.dependencies = event.dependencies;
this.cause = event.cause;
this.replay = replay;
}
/**
* Return the type of this event.
*
* The type values are:
*
* - {@link #CREATING}
* - {@link #CREATED}
* - {@link #DESTROYING}
* - {@link #DESTROYED}
* - {@link #FAILURE}
* - {@link #GRACE_PERIOD}
* - {@link #WAITING}
*
*
* @return The type of this event.
*/
public int getType() {
return type;
}
/**
* Return the time at which this event was created.
*
* @return The time at which this event was created.
*/
public long getTimestamp() {
return timestamp;
}
/**
* Return the Blueprint bundle associated with this event.
*
* @return The Blueprint bundle associated with this event.
*/
public Bundle getBundle() {
return bundle;
}
/**
* Return the Blueprint extender bundle that is generating this event.
*
* @return The Blueprint extender bundle that is generating this event.
*/
public Bundle getExtenderBundle() {
return extenderBundle;
}
/**
* Return the filters identifying the missing dependencies that caused this
* event.
*
* @return The filters identifying the missing dependencies that caused this
* event if the event type is one of {@link #WAITING},
* {@link #GRACE_PERIOD} or {@link #FAILURE} or {@code null}
* for the other event types.
*/
public String[] getDependencies() {
return dependencies == null ? null : (String[]) dependencies.clone();
}
/**
* Return the cause for this {@link #FAILURE} event.
*
* @return The cause of the failure for this event. May be {@code null}
* .
*/
public Throwable getCause() {
return cause;
}
/**
* Return whether this event is a replay event.
*
* @return {@code true} if this event is a replay event and
* {@code false} otherwise.
*/
public boolean isReplay() {
return replay;
}
}