private class InstanceSupport implements ServiceTrackerCustomizer {
public Object addingService(final ServiceReference reference) {
Object service = m_bundleContext.getService(reference);
if (service instanceof InstanceDeclaration) {
final InstanceDeclaration instanceDeclaration = (InstanceDeclaration) service;
// Check that instance is not already bound
if (instanceDeclaration.getStatus().isBound()) {
return null;
}
// Handle visibility (private/public factories)
if (!m_declaration.isPublic()) {
if (!reference.getBundle().equals(m_bundleContext.getBundle())) {
Bundle origin = m_bundleContext.getBundle();
instanceDeclaration.unbind(
format("Component '%s/%s' is private. It only accept instances " +
"from bundle %s/%s [%d] (instance bundle origin: %d)",
m_declaration.getComponentName(),
m_declaration.getComponentVersion(),
origin.getSymbolicName(),
origin.getVersion(),
origin.getBundleId(),
reference.getBundle().getBundleId())
);
return null;
}
}
return m_queueService.submit(new DefaultJob<ComponentInstance>(reference.getBundle(), INSTANCE_STARTUP_JOB_TYPE) {
public ComponentInstance call() throws Exception {
try {
// Create the component's instance
// It is automatically started
// Future.get should never be null since this tracker is started when the factory has been created
ComponentInstance instance = m_future.get().createComponentInstance(instanceDeclaration.getConfiguration());
if (instance instanceof InstanceBundleContextAware) {
((InstanceBundleContextAware) instance).setInstanceBundleContext(instanceDeclaration
.getBundle().getBundleContext());
}
// Notify the declaration that everything is fine
instanceDeclaration.bind();
return instance;
} catch (UnacceptableConfiguration c) {
instanceDeclaration.unbind(format("Instance configuration is invalid (component:%s/%s, bundle:%d)",
m_declaration.getComponentName(),
m_declaration.getComponentVersion(),
reference.getBundle().getBundleId()),
c);
} catch (MissingHandlerException e) {
instanceDeclaration.unbind(
format(
"Component '%s/%s' (required for instance creation) is missing some handlers",
m_declaration.getComponentName(),
m_declaration.getComponentVersion()
),
e);
} catch (ConfigurationException e) {
instanceDeclaration.unbind(
format(
"Instance configuration is incorrect for component '%s/%s'",
m_declaration.getComponentName(),
m_declaration.getComponentVersion()),
e);