| /* |
| * Copyright (c) OSGi Alliance (2008, 2009). 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. |
| * |
| * <p> |
| * <code>BlueprintEvent</code> objects are delivered to all registered |
| * {@link BlueprintListener} services. Blueprint Events must be asynchronously |
| * delivered in chronological order with respect to each listener. |
| * |
| * <p> |
| * 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 |
| * <em>replay</em> 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. |
| * |
| * <p> |
| * A type code is used to identify the type of event. The following event types |
| * are defined: |
| * <ul> |
| * <li>{@link #CREATING}</li> |
| * <li>{@link #CREATED}</li> |
| * <li>{@link #DESTROYING}</li> |
| * <li>{@link #DESTROYED}</li> |
| * <li>{@link #FAILURE}</li> |
| * <li>{@link #GRACE_PERIOD}</li> |
| * <li>{@link #WAITING}</li> |
| * </ul> |
| * |
| * <p> |
| * 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 $Revision: 896324 $ |
| */ |
| 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</code> 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</code> 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</code> object. |
| * |
| * @param type The type of this event. |
| * @param bundle The Blueprint bundle associated with this event. This |
| * parameter must not be <code>null</code>. |
| * @param extenderBundle The Blueprint extender bundle that is generating |
| * this event. This parameter must not be <code>null</code>. |
| */ |
| public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle) { |
| this(type, bundle, extenderBundle, null, null); |
| } |
| |
| /** |
| * Create a <code>BlueprintEvent</code> 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</code>. |
| * @param extenderBundle The Blueprint extender bundle that is generating |
| * this event. This parameter must not be <code>null</code>. |
| * @param dependencies An array of <code>String</code> filters for each |
| * dependency associated with this event. Must be a non-empty array |
| * for event types {@link #FAILURE}, {@link #GRACE_PERIOD} and |
| * {@link #WAITING}. Must be <code>null</code> for other event types. |
| */ |
| public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle, |
| String[] dependencies) { |
| this(type, bundle, extenderBundle, dependencies, null); |
| } |
| |
| /** |
| * Create a <code>BlueprintEvent</code> 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</code>. |
| * @param extenderBundle The Blueprint extender bundle that is generating |
| * this event. This parameter must not be <code>null</code>. |
| * @param cause A <code>Throwable</code> object describing the root cause of |
| * the event. May be <code>null</code>. |
| */ |
| public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle, |
| Throwable cause) { |
| this(type, bundle, extenderBundle, null, cause); |
| } |
| |
| /** |
| * Create a <code>BlueprintEvent</code> 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</code>. |
| * @param extenderBundle The Blueprint extender bundle that is generating |
| * this event. This parameter must not be <code>null</code>. |
| * @param dependencies An array of <code>String</code> 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 {@link #FAILURE} event types. |
| * Must be <code>null</code> for other event types. |
| * @param cause A <code>Throwable</code> object describing the root cause of |
| * this event. May be <code>null</code>. |
| */ |
| 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; |
| 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 : |
| // not all FAILURE events have a dependency list, but if there |
| // is one, it must be non-empty. |
| if (dependencies != null) { |
| if (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</code> from the specified |
| * <code>BlueprintEvent</code>. The <code>timestamp</code> 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</code> to copy. Must not |
| * be <code>null</code>. |
| * @param replay <code>true</code> 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. |
| * <p> |
| * The type values are: |
| * <ul> |
| * <li>{@link #CREATING}</li> |
| * <li>{@link #CREATED}</li> |
| * <li>{@link #DESTROYING}</li> |
| * <li>{@link #DESTROYED}</li> |
| * <li>{@link #FAILURE}</li> |
| * <li>{@link #GRACE_PERIOD}</li> |
| * <li>{@link #WAITING}</li> |
| * </ul> |
| * |
| * @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</code> |
| * 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</code> |
| * . |
| */ |
| public Throwable getCause() { |
| return cause; |
| } |
| |
| /** |
| * Return whether this event is a replay event. |
| * |
| * @return <code>true</code> if this event is a replay event and |
| * <code>false</code> otherwise. |
| */ |
| public boolean isReplay() { |
| return replay; |
| } |
| } |