/*******************************************************************************
* 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.agent.dm.internal;
import java.util.Dictionary;
import java.util.Hashtable;
import org.eclipse.virgo.medic.eventlog.EventLogger;
import org.eclipse.virgo.medic.eventlog.EventLoggerFactory;
import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener;
/**
* ComponentContext activator for the Kernel's Agent bundle
*
* <p />
*
* <strong>Concurrent Semantics</strong><br />
*
* Thread-safe.
*
*/
public final class AgentActivator {
private static final String AGENT_DM_START_TRACKER = "agentDMStartTracker";
private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
public void activate(ComponentContext context) {
registerSpringDmToBlueprintEventAdapter(context.getBundleContext());
context.enableComponent(AGENT_DM_START_TRACKER);
}
private void registerSpringDmToBlueprintEventAdapter(BundleContext context) {
registerBlueprintEventPostingOsgiBundleApplicationContextListener(context);
registerDeployerFailureListener(context);
}
private void registerBlueprintEventPostingOsgiBundleApplicationContextListener(BundleContext context) {
EventAdmin eventAdmin = getRequiredService(context, EventAdmin.class);
BlueprintEventPostingOsgiBundleApplicationContextListener listener = new BlueprintEventPostingOsgiBundleApplicationContextListener(eventAdmin);
this.registrationTracker.track(context.registerService(OsgiBundleApplicationContextListener.class.getName(), listener, null));
}
private void registerDeployerFailureListener(BundleContext context) {
EventLoggerFactory eventLoggerFactory = getRequiredService(context, EventLoggerFactory.class);
EventLogger eventLogger = eventLoggerFactory.createEventLogger(context.getBundle());
DeployerFailureListener failureListener = new DeployerFailureListener(eventLogger);
Dictionary<String, String[]> props = new Hashtable<String, String[]>();
props.put(EventConstants.EVENT_TOPIC, new String[] { "org/osgi/service/blueprint/container/*" });
this.registrationTracker.track(context.registerService(EventHandler.class.getName(), failureListener, props));
}
public void deactivate(ComponentContext context) throws Exception {
this.registrationTracker.unregisterAll();
}
private <T> T getRequiredService(BundleContext context, Class<T> clazz) {
T result = null;
ServiceReference<T> ref = context.getServiceReference(clazz);
if (ref != null) {
result = (T) context.getService(ref);
}
if (result == null) {
// TODO: is consuming service references reasonable if failures are retried many times? May need the
// following code.
// if (ref != null) {
// context.ungetService(ref);
// }
throw new IllegalStateException("Unable to access required service of type '" + clazz.getName() + "' from bundle '" + context.getBundle().getSymbolicName() + "'");
}
return result;
}
}