/*******************************************************************************
* Copyright (c) 2008, 2010 VMware Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware Inc. - initial contribution
*******************************************************************************/
package org.eclipse.virgo.kernel.install.artifact.internal.bundle;
import java.util.Set;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.SynchronousBundleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
import org.eclipse.virgo.kernel.install.artifact.internal.ArtifactStateMonitor;
import org.eclipse.virgo.kernel.install.artifact.internal.StandardArtifactStateMonitor;
import org.eclipse.virgo.nano.serviceability.NonNull;
import org.eclipse.virgo.util.math.ConcurrentHashSet;
/**
* {@link BundleDriverBundleListener} listens for bundle events and notifies the bundle's {@link StandardArtifactStateMonitor}.
* <p />
*
* <strong>Concurrent Semantics</strong><br />
*
* This class is thread safe.
*
*/
final class BundleDriverBundleListener implements SynchronousBundleListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final StandardBundleInstallArtifact installArtifact;
private final Bundle bundle;
private final ArtifactStateMonitor artifactStateMonitor;
private final Set<Bundle> solicitedStartBundleSet = new ConcurrentHashSet<Bundle>();
public BundleDriverBundleListener(@NonNull StandardBundleInstallArtifact installArtifact, @NonNull Bundle bundle,
@NonNull ArtifactStateMonitor artifactStateMonitor) {
this.installArtifact = installArtifact;
this.bundle = bundle;
this.artifactStateMonitor = artifactStateMonitor;
}
void addSolicitedStart(Bundle bundle) {
this.solicitedStartBundleSet.add(bundle);
}
void removeSolicitedStart(Bundle bundle) {
this.solicitedStartBundleSet.remove(bundle);
}
/**
* {@inheritDoc}
*/
public void bundleChanged(BundleEvent event) {
if (event.getBundle() == this.bundle) {
try {
switch (event.getType()) {
case BundleEvent.RESOLVED:
artifactStateMonitor.onResolved(this.installArtifact);
break;
case BundleEvent.LAZY_ACTIVATION:
break;
case BundleEvent.STARTING:
artifactStateMonitor.onStarting(this.installArtifact);
break;
case BundleEvent.STARTED:
if (!this.solicitedStartBundleSet.contains(this.bundle)) {
/*
* Track an unsolicited start of the install artifact so that its state transitions are performed
* correctly. Solicited starts are tracked by the solicitor.
*/
this.installArtifact.trackStart();
}
break;
case BundleEvent.STOPPING:
artifactStateMonitor.onStopping(this.installArtifact);
break;
case BundleEvent.STOPPED:
artifactStateMonitor.onStopped(this.installArtifact);
break;
case BundleEvent.UNRESOLVED:
artifactStateMonitor.onUnresolved(this.installArtifact);
break;
case BundleEvent.UNINSTALLED:
artifactStateMonitor.onUninstalled(this.installArtifact);
break;
default:
break;
}
} catch (DeploymentException e) {
logger.error(String.format("listener for bundle %s threw DeploymentException", this.bundle), e);
throw new RuntimeException("percolated listener exception", e);
}
}
}
}