blob: 7a9e91740a112857bd138d0096fd9a74287ca940 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2006, 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
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
* is available at http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* VMware Inc.
*****************************************************************************/
package org.eclipse.gemini.blueprint.context.support;
import org.eclipse.gemini.blueprint.context.DelegatedExecutionOsgiBundleApplicationContext;
import org.eclipse.gemini.blueprint.context.DependencyAwareBeanFactoryPostProcessor;
import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor;
import org.eclipse.gemini.blueprint.context.OsgiBundleApplicationContextExecutor;
import org.eclipse.gemini.blueprint.context.event.*;
import org.eclipse.gemini.blueprint.util.OsgiBundleUtils;
import org.eclipse.gemini.blueprint.util.OsgiStringUtils;
import org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import java.io.IOException;
import java.util.*;
/**
* OSGi-specific application context that delegates the execution of its life cycle methods to a different class. The
* main reason behind this is to <em>break</em> the startup of the application context in steps that can be executed
* asynchronously. <p/> <p/> <p/> The {@link #refresh()} and {@link #close()} methods delegate their execution to an
* {@link OsgiBundleApplicationContextExecutor} class that chooses how to call the lifecycle methods. <p/> <p/> <p/> One
* can still call the 'traditional' lifecycle methods through {@link #normalRefresh()} and {@link #normalClose()}.
*
* @author Costin Leau
* @author Olaf Otto
*
* @see DelegatedExecutionOsgiBundleApplicationContext
*/
public abstract class AbstractDelegatedExecutionApplicationContext extends AbstractOsgiBundleApplicationContext
implements DelegatedExecutionOsgiBundleApplicationContext {
/**
* Executor that offers the traditional way of <code>refreshing</code>/ <code>closing</code> of an
* ApplicationContext (no conditions have to be met and the refresh happens in only one step).
*
* @author Costin Leau
*/
private static class NoDependenciesWaitRefreshExecutor implements OsgiBundleApplicationContextExecutor {
private final DelegatedExecutionOsgiBundleApplicationContext context;
private NoDependenciesWaitRefreshExecutor(DelegatedExecutionOsgiBundleApplicationContext ctx) {
context = ctx;
}
public void refresh() throws BeansException, IllegalStateException {
context.normalRefresh();
}
public void close() {
context.normalClose();
}
}
/**
* BeanPostProcessor that logs an info message when a bean is created during BeanPostProcessor instantiation, i.e.
* when a bean is not eligible for getting processed by all BeanPostProcessors.
*/
private class BeanPostProcessorChecker implements BeanPostProcessor {
private final ConfigurableListableBeanFactory beanFactory;
private final int beanPostProcessorTargetCount;
public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) {
this.beanFactory = beanFactory;
this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (!(bean instanceof BeanPostProcessor)
&& this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
if (logger.isInfoEnabled()) {
logger.info("Bean '" + beanName + "' is not eligible for getting processed by all "
+ "BeanPostProcessors (for example: not eligible for auto-proxying)");
}
}
return bean;
}
}
/**
* Default executor
*/
private OsgiBundleApplicationContextExecutor executor = new NoDependenciesWaitRefreshExecutor(this);
/**
* monitor used during refresh/close
*/
private final Object startupShutdownMonitor = new Object();
/**
* Delegated multicaster
*/
private OsgiBundleApplicationContextEventMulticaster delegatedMulticaster;
private ContextClassLoaderProvider cclProvider;
/**
* Constructs a new <code>AbstractDelegatedExecutionApplicationContext</code> instance.
*/
public AbstractDelegatedExecutionApplicationContext() {
super();
}
/**
* Constructs a new <code>AbstractDelegatedExecutionApplicationContext</code> instance.
*
* @param parent parent application context
*/
public AbstractDelegatedExecutionApplicationContext(ApplicationContext parent) {
super(parent);
}
/**
* Delegate execution of refresh method to a third party. This allows breaking the refresh process into several
* small pieces providing continuation-like behaviour or completion of the refresh method on several threads, in a
* asynch manner. <p/> By default, the refresh method in executed in <em>one go</em> (normal behaviour). <p/>
* {@inheritDoc}
*/
public void refresh() throws BeansException, IllegalStateException {
executor.refresh();
}
public void normalRefresh() {
Assert.notNull(getBundleContext(), "bundle context should be set before refreshing the application context");
try {
PrivilegedUtils.executeWithCustomTCCL(contextClassLoaderProvider().getContextClassLoader(),
new PrivilegedUtils.UnprivilegedExecution() {
public Object run() {
AbstractDelegatedExecutionApplicationContext.super.refresh();
sendRefreshedEvent();
return null;
}
});
} catch (Throwable th) {
if (logger.isDebugEnabled()) {
logger.debug("Refresh error", th);
}
sendFailedEvent(th);
// propagate exception to the caller
// rethrow the problem w/o rewrapping
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
} else {
throw (Error) th;
}
}
}
public void normalClose() {
try {
PrivilegedUtils.executeWithCustomTCCL(contextClassLoaderProvider().getContextClassLoader(),
new PrivilegedUtils.UnprivilegedExecution() {
public Object run() {
AbstractDelegatedExecutionApplicationContext.super.doClose();
sendClosedEvent();
return null;
}
});
} catch (Throwable th) {
// send failure event
sendClosedEvent(th);
// rethrow the problem w/o rewrapping
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
} else {
throw (Error) th;
}
}
}
// Adds behaviour for isAvailable flag.
protected void doClose() {
executor.close();
}
public void startRefresh() {
try {
PrivilegedUtils.executeWithCustomTCCL(contextClassLoaderProvider().getContextClassLoader(),
new PrivilegedUtils.UnprivilegedExecution<Object>() {
public Object run() {
synchronized (startupShutdownMonitor) {
if (ObjectUtils.isEmpty(getConfigLocations())) {
setConfigLocations(getDefaultConfigLocations());
}
if (!OsgiBundleUtils.isBundleActive(getBundle())
&& !OsgiBundleUtils.isBundleLazyActivated(getBundle())) {
throw new ApplicationContextException(
"Unable to refresh application context: bundle is neither active nor lazy-activated but "
+ OsgiStringUtils.bundleStateAsString(getBundle()));
}
ConfigurableListableBeanFactory beanFactory = null;
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean
// factory.
beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in
// context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans
// in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean
// creation.
registerBeanPostProcessors(beanFactory,
DependencyInitializationAwareBeanPostProcessor.class, null, false);
return null;
} catch (BeansException ex) {
// Destroy already created singletons to avoid
// dangling resources.
beanFactory.destroySingletons();
cancelRefresh(ex);
// propagate exception to the caller
throw ex;
}
}
}
});
} catch (Throwable th) {
if (logger.isDebugEnabled()) {
logger.debug("Pre refresh error", th);
}
// send failure event
sendFailedEvent(th);
// rethrow the problem w/o rewrapping
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
} else {
throw (Error) th;
}
}
}
public void completeRefresh() {
try {
PrivilegedUtils.executeWithCustomTCCL(contextClassLoaderProvider().getContextClassLoader(),
new PrivilegedUtils.UnprivilegedExecution<Object>() {
public Object run() {
synchronized (startupShutdownMonitor) {
try {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// Invoke factory processors registered as beans
// in the context.
invokeBeanFactoryPostProcessors(beanFactory,
DependencyAwareBeanFactoryPostProcessor.class, null);
// Register bean processors that intercept bean
// creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this
// context.
initApplicationEventMulticaster();
// Initialize other special beans in specific
// context
// subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init)
// singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
// everything went okay, post notification
sendRefreshedEvent();
return null;
} catch (BeansException ex) {
// Destroy already created singletons to avoid
// dangling
// resources.
getBeanFactory().destroySingletons();
cancelRefresh(ex);
// propagate exception to the caller
throw ex;
}
}
}
});
} catch (Throwable th) {
if (logger.isDebugEnabled()) {
logger.debug("Post refresh error", th);
}
// post notification
sendFailedEvent(th);
// rethrow the problem w/o rewrapping
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
} else {
throw (Error) th;
}
}
}
// customized to handle DependencyAwareBeanFactoryPostProcessor classes
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
invokeBeanFactoryPostProcessors(beanFactory, BeanFactoryPostProcessor.class,
DependencyAwareBeanFactoryPostProcessor.class);
}
/**
* This version of the original
* {@link org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List) post processor invocation}
* implementation adds including and excluding processor types to allow for a multi-staged
* context initialization, see for instance {{@link #completeRefresh()}}.
*
* @param beanFactory must not be <code>null</code>
* @param include only invoke post processors that are assignment-compatible with this type. Must not be <code>null</code>
* @param exclude exclude all post processors that are assignment-compatible with this type. Can be <code>null</code>
*/
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,
Class<? extends BeanFactoryPostProcessor> include,
Class<? extends BeanFactoryPostProcessor> exclude) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (isExcluded(include, exclude, postProcessor)) {
continue;
}
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
if (include.isAssignableFrom(BeanDefinitionRegistryPostProcessor.class)) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registryPostProcessors.addAll(priorityOrderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
}
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(include, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName) || exclude != null && isTypeMatch(ppName, exclude)) {
continue;
}
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, include));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, include));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, include));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
private boolean isExcluded(Class<? extends BeanFactoryPostProcessor> include, Class<? extends BeanFactoryPostProcessor> exclude, BeanFactoryPostProcessor postProcessor) {
return !include.isInstance(postProcessor) || exclude != null && exclude.isInstance(postProcessor);
}
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
private static void sortPostProcessors(ConfigurableListableBeanFactory beanFactory, List<?> postProcessors) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
comparatorToUse = OrderComparator.INSTANCE;
}
Collections.sort(postProcessors, comparatorToUse);
}
// customized to handle DependencyInitializationAwareBeanPostProcessor
// classes
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
registerBeanPostProcessors(beanFactory, BeanPostProcessor.class,
DependencyInitializationAwareBeanPostProcessor.class, true);
}
/**
* Instantiate and invoke all registered BeanPostProcessor beans, respecting explicit order if given. <p/> Must be
* called before any instantiation of application beans. Very similar to
* {@link AbstractApplicationContext#invokeBeanFactoryPostProcessors} but allowing exclusion of a certain type.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, Class<?> type,
Class<?> exclude, boolean check) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(type, true, false);
if (check) {
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e.
// when
// a bean is not eligible for getting processed by all
// BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
}
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (int i = 0; i < postProcessorNames.length; i++) {
// check exclude type first
if (exclude == null || !isTypeMatch(postProcessorNames[i], exclude)) {
if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i],
BeanPostProcessor.class));
} else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
orderedPostProcessorNames.add(postProcessorNames[i]);
} else {
nonOrderedPostProcessorNames.add(postProcessorNames[i]);
}
}
}
// First, register the BeanPostProcessors that implement
// PriorityOrdered.
Collections.sort(priorityOrderedPostProcessors, new OrderComparator());
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(getBean(postProcessorName, BeanPostProcessor.class));
}
Collections.sort(orderedPostProcessors, new OrderComparator());
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Finally, register all other BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(getBean(postProcessorName, BeanPostProcessor.class));
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
}
/**
* Register the given BeanPostProcessor beans.
*/
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory,
List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
public void setExecutor(OsgiBundleApplicationContextExecutor executor) {
this.executor = executor;
}
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException, BeansException {
}
public void setDelegatedEventMulticaster(OsgiBundleApplicationContextEventMulticaster multicaster) {
this.delegatedMulticaster = multicaster;
}
/**
* Sets the OSGi multicaster by using a Spring {@link ApplicationEventMulticaster}. This method is added as a
* covenience.
*
* @param multicaster Spring multi-caster used for propagating OSGi specific events
* @see OsgiBundleApplicationContextEventMulticasterAdapter
*/
public void setDelegatedEventMulticaster(ApplicationEventMulticaster multicaster) {
this.delegatedMulticaster = new OsgiBundleApplicationContextEventMulticasterAdapter(multicaster);
}
public OsgiBundleApplicationContextEventMulticaster getDelegatedEventMulticaster() {
return this.delegatedMulticaster;
}
private void sendFailedEvent(Throwable cause) {
if (delegatedMulticaster != null)
delegatedMulticaster.multicastEvent(new OsgiBundleContextFailedEvent(this, this.getBundle(), cause));
}
private void sendRefreshedEvent() {
if (delegatedMulticaster != null)
delegatedMulticaster.multicastEvent(new OsgiBundleContextRefreshedEvent(this, this.getBundle()));
}
private void sendClosedEvent() {
if (delegatedMulticaster != null)
delegatedMulticaster.multicastEvent(new OsgiBundleContextClosedEvent(this, this.getBundle()));
}
private void sendClosedEvent(Throwable cause) {
if (delegatedMulticaster != null)
delegatedMulticaster.multicastEvent(new OsgiBundleContextClosedEvent(this, this.getBundle(), cause));
}
/**
* private method used for doing lazy-init-if-not-set for cclProvider
*/
private ContextClassLoaderProvider contextClassLoaderProvider() {
if (cclProvider == null) {
DefaultContextClassLoaderProvider defaultProvider = new DefaultContextClassLoaderProvider();
defaultProvider.setBeanClassLoader(getClassLoader());
cclProvider = defaultProvider;
}
return cclProvider;
}
/**
* Sets the {@link ContextClassLoaderProvider} used by this OSGi application context instance. By default,
* {@link DefaultContextClassLoaderProvider} is used.
*
* @param contextClassLoaderProvider context class loader provider to use
* @see ContextClassLoaderProvider
* @see DefaultContextClassLoaderProvider
*/
public void setContextClassLoaderProvider(ContextClassLoaderProvider contextClassLoaderProvider) {
this.cclProvider = contextClassLoaderProvider;
}
}