/*
* Copyright 2008-2012 Alin Dreghiciu, Harald Wellmann.
*
* 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.ops4j.pax.swissbox.core;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
/**
* Utilities related to bundles.
*
* @author Alin Dreghiciu
* @author Harald Wellmann
* @since 0.1.0, January 11, 2008
*/
public class BundleUtils
{
/**
* Discovers the bundle context for a bundle. If the bundle is an 4.1.0 or greater bundle it should have a method
* that just returns the bundle context. Otherwise uses reflection to look for an internal bundle context.
*
* @param bundle the bundle from which the bundle context is needed
*
* @return corresponding bundle context or null if bundle context cannot be discovered
*/
public static BundleContext getBundleContext( final Bundle bundle )
{
try
{
// first try to find the getBundleContext method (OSGi spec >= 4.10)
final Method method = Bundle.class.getDeclaredMethod( "getBundleContext" );
if( !method.isAccessible() )
{
method.setAccessible( true );
}
return (BundleContext) method.invoke( bundle );
}
catch( Exception e )
{
// then try to find a field in the bundle that looks like a bundle context
try
{
final Field[] fields = bundle.getClass().getDeclaredFields();
for( Field field : fields )
{
if( BundleContext.class.isAssignableFrom( field.getType() ) )
{
if( !field.isAccessible() )
{
field.setAccessible( true );
}
return (BundleContext) field.get( bundle );
}
}
}
catch( Exception ignore )
{
// ignore
}
}
// well, discovery failed
return null;
}
/**
* Returns any bundle with the given symbolic name, or null if no such bundle exists. If there
* are multiple bundles with the same symbolic name and different version, this method returns
* the first bundle found.
*
* @param bc bundle context
* @param symbolicName bundle symbolic name
* @param version bundle version
* @return matching bundle, or null
*/
public static Bundle getBundle( BundleContext bc, String symbolicName )
{
return getBundle( bc, symbolicName, null );
}
/**
* Returns a list of all bundles with the given symbolic name.
*
* @param bc bundle context
* @param symbolicName bundle symbolic name
* @return matching bundles. The list may be empty, but never null.
*/
public static List<Bundle> getBundles( BundleContext bc, String symbolicName )
{
List<Bundle> bundles = new ArrayList<Bundle>();
for( Bundle bundle : bc.getBundles() )
{
if( bundle.getSymbolicName().equals( symbolicName ) )
{
bundles.add( bundle );
}
}
return bundles;
}
/**
* Returns the bundle with the given symbolic name and the given version, or null if no such
* bundle exists
*
* @param bc bundle context
* @param symbolicName bundle symbolic name
* @param version bundle version
* @return matching bundle, or null
*/
public static Bundle getBundle( BundleContext bc, String symbolicName, String version )
{
for( Bundle bundle : bc.getBundles() )
{
if( bundle.getSymbolicName().equals( symbolicName ) )
{
if( version == null || version.equals( bundle.getVersion() ) )
{
return bundle;
}
}
}
return null;
}
}