blob: ba93e5d4c7639959020df4bc59ef58632e33af84 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 Sonatype, 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:
* Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.launch;
import java.util.Collections;
import java.util.Map;
import org.eclipse.sisu.inject.DefaultBeanLocator;
import org.eclipse.sisu.inject.MutableBeanLocator;
import org.eclipse.sisu.inject.Weak;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
* OSGi extender that uses Sisu and Guice to wire up applications from one or more component bundles.<br>
* To enable it install {@code org.eclipse.sisu.inject.extender}, or adapt the class for your own extender.
*/
public class SisuExtender
implements BundleActivator
{
// ----------------------------------------------------------------------
// Implementation fields
// ----------------------------------------------------------------------
// track locators (per-extender-bundle) so they can be re-used when possible
private static final Map<Long, MutableBeanLocator> locators =
Collections.synchronizedMap( Weak.<Long, MutableBeanLocator> values() );
/**
* Tracker of component bundles.
*/
protected SisuTracker tracker;
// ----------------------------------------------------------------------
// Public methods
// ----------------------------------------------------------------------
public void start( final BundleContext context )
{
tracker = createTracker( context );
tracker.open();
}
public void stop( final BundleContext context )
{
tracker.close();
tracker = null;
}
// ----------------------------------------------------------------------
// Customizable methods
// ----------------------------------------------------------------------
/**
* Returns the mask of bundle states this extender is interested in.
*
* @return State mask
*/
protected int bundleStateMask()
{
return Bundle.STARTING | Bundle.ACTIVE;
}
/**
* Creates a new tracker of component bundles for this extender.
*
* @param context The extender context
* @return New bundle tracker
*/
protected SisuTracker createTracker( final BundleContext context )
{
return new SisuTracker( context, bundleStateMask(), findLocator( context ) );
}
/**
* Returns a new locator of bound components for this extender.
*
* @param context The extender context
* @return New bean locator
*/
protected MutableBeanLocator createLocator( final BundleContext context )
{
final MutableBeanLocator locator = new DefaultBeanLocator();
locator.add( new ServiceBindings( context ) );
return locator;
}
// ----------------------------------------------------------------------
// Implementation methods
// ----------------------------------------------------------------------
/**
* Finds the locator associated with this extender; creates one if none exist.
*
* @param context The extender context
* @return Associated bean locator
*/
protected final MutableBeanLocator findLocator( final BundleContext context )
{
@SuppressWarnings( "boxing" )
final Long extenderId = context.getBundle().getBundleId();
MutableBeanLocator locator = locators.get( extenderId );
if ( null == locator )
{
locators.put( extenderId, locator = createLocator( context ) );
}
return locator;
}
}