Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 223234 Details for
Bug 356683
Construct application contexts defined in extender fragments only once and share across extender instances
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Corrected version of the previous patch using GIT against the master
356683-against-master.patch (text/plain), 79.57 KB, created by
Olaf Otto
on 2012-11-06 08:39:00 EST
(
hide
)
Description:
Corrected version of the previous patch using GIT against the master
Filename:
MIME Type:
Creator:
Olaf Otto
Created:
2012-11-06 08:39:00 EST
Size:
79.57 KB
patch
obsolete
>From e538b172586db62936fab2d0ef4ced3da129f874 Mon Sep 17 00:00:00 2001 >From: Olaf Otto <olaf.otto@unic.com> >Date: Tue, 6 Nov 2012 14:25:58 +0100 >Subject: [PATCH] 356683 Separate staged configuration and listeners > (https://bugs.eclipse.org/bugs/show_bug.cgi?id=356683) > >--- > .../classloader/ChainedClassLoaderTest.java | 1 - > .../context/support/ConfigLocationsTest.java | 1 - > .../BlueprintNamespaceHandlerActivator.java | 14 + > .../internal/activator/ContextLoaderListener.java | 376 ++++----------------- > .../activator/JavaBeansCacheActivator.java | 60 ++++ > .../internal/activator/LifecycleManager.java | 18 +- > .../internal/activator/ListListenerAdapter.java | 15 +- > .../activator/ListenerServiceActivator.java | 79 +++++ > .../internal/activator/LoggingActivator.java | 27 ++ > .../activator/NamespaceHandlerActivator.java | 115 +++++++ > .../internal/activator/listeners/BaseListener.java | 85 +++++ > .../activator/listeners/NamespaceBundleLister.java | 59 ++++ > .../activator/BlueprintLoaderListener.java | 63 ++-- > .../support/BlueprintExtenderConfiguration.java | 44 --- > .../extender/internal/boot/ChainActivator.java | 49 ++- > ...efaultOsgiBundleApplicationContextListener.java | 3 +- > .../internal/support/ExtenderConfiguration.java | 62 ++-- > .../internal/ContextLoaderListenerTest.java | 205 +++++------ > .../ExtenderConfigurationCustomSettingsTest.java | 24 +- > .../ExtenderConfigurationDefaultSettingsTest.java | 21 +- > 20 files changed, 738 insertions(+), 583 deletions(-) > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/BlueprintNamespaceHandlerActivator.java > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/JavaBeansCacheActivator.java > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListenerServiceActivator.java > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LoggingActivator.java > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/NamespaceHandlerActivator.java > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/BaseListener.java > create mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/NamespaceBundleLister.java > delete mode 100644 extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/support/BlueprintExtenderConfiguration.java > >diff --git a/core/src/test/java/org/eclipse/gemini/blueprint/context/internal/classloader/ChainedClassLoaderTest.java b/core/src/test/java/org/eclipse/gemini/blueprint/context/internal/classloader/ChainedClassLoaderTest.java >index effc03e..8c75d54 100644 >--- a/core/src/test/java/org/eclipse/gemini/blueprint/context/internal/classloader/ChainedClassLoaderTest.java >+++ b/core/src/test/java/org/eclipse/gemini/blueprint/context/internal/classloader/ChainedClassLoaderTest.java >@@ -96,7 +96,6 @@ public class ChainedClassLoaderTest extends TestCase { > } > > public void testGetResourceString() throws Exception { >- System.out.println(chainedLoader.getResource("java/lang/Object.class")); > assertNull(chainedLoader.getResource("java/lang/Object.class")); > chainedLoader.addClassLoader(Object.class); > assertNotNull(chainedLoader.getResource("java/lang/Object.class")); >diff --git a/core/src/test/java/org/eclipse/gemini/blueprint/context/support/ConfigLocationsTest.java b/core/src/test/java/org/eclipse/gemini/blueprint/context/support/ConfigLocationsTest.java >index 548f297..ebb3287 100644 >--- a/core/src/test/java/org/eclipse/gemini/blueprint/context/support/ConfigLocationsTest.java >+++ b/core/src/test/java/org/eclipse/gemini/blueprint/context/support/ConfigLocationsTest.java >@@ -44,7 +44,6 @@ public class ConfigLocationsTest extends TestCase { > context.setConfigLocations(cfgs); > String[] returned = > (String[]) invokeMethod("expandLocations", new Class[] { String[].class }, new Object[] { cfgs }); >- System.out.println("returned " + Arrays.toString(returned)); > assertTrue(Arrays.equals(new String[] { "cnf/*.xml", "/cnf/*.xml" }, returned)); > } > >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/BlueprintNamespaceHandlerActivator.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/BlueprintNamespaceHandlerActivator.java >new file mode 100644 >index 0000000..30a4e2b >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/BlueprintNamespaceHandlerActivator.java >@@ -0,0 +1,14 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator; >+ >+import org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintConfigUtils; >+ >+/** >+ * @author Olaf Otto >+ */ >+public class BlueprintNamespaceHandlerActivator extends NamespaceHandlerActivator { >+ >+ @Override >+ protected String getManagedBundleExtenderVersionHeader() { >+ return BlueprintConfigUtils.EXTENDER_VERSION; >+ } >+} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ContextLoaderListener.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ContextLoaderListener.java >index 5c7f419..caaf44f 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ContextLoaderListener.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ContextLoaderListener.java >@@ -15,28 +15,16 @@ > > package org.eclipse.gemini.blueprint.extender.internal.activator; > >-import java.util.Map; >-import java.util.WeakHashMap; >- > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; >-import org.osgi.framework.Bundle; >-import org.osgi.framework.BundleActivator; >-import org.osgi.framework.BundleContext; >-import org.osgi.framework.BundleEvent; >-import org.osgi.framework.SynchronousBundleListener; >-import org.osgi.framework.Version; >-import org.springframework.beans.BeanUtils; >-import org.springframework.beans.CachedIntrospectionResults; >-import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticaster; >+import org.eclipse.gemini.blueprint.extender.OsgiApplicationContextCreator; >+import org.eclipse.gemini.blueprint.extender.internal.activator.listeners.BaseListener; > import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; >-import org.eclipse.gemini.blueprint.extender.internal.support.NamespaceManager; >+import org.eclipse.gemini.blueprint.extender.support.DefaultOsgiApplicationContextCreator; > import org.eclipse.gemini.blueprint.extender.support.internal.ConfigUtils; >-import org.eclipse.gemini.blueprint.service.exporter.support.OsgiServiceFactoryBean; >-import org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceCollectionProxyFactoryBean; >-import org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceProxyFactoryBean; > import org.eclipse.gemini.blueprint.util.OsgiBundleUtils; > import org.eclipse.gemini.blueprint.util.OsgiStringUtils; >+import org.osgi.framework.*; > > /** > * Osgi Extender that bootstraps 'Spring powered bundles'. >@@ -80,123 +68,7 @@ import org.eclipse.gemini.blueprint.util.OsgiStringUtils; > */ > public class ContextLoaderListener implements BundleActivator { > >- /** >- * Common base class for {@link ContextLoaderListener} listeners. >- * >- * @author Costin Leau >- */ >- private abstract class BaseListener implements SynchronousBundleListener { >- >- static final int LAZY_ACTIVATION_EVENT_TYPE = 0x00000200; >- >- protected final Log log = LogFactory.getLog(getClass()); >- >- /** >- * common cache used for tracking down bundles started lazily so they don't get processed twice (once when >- * started lazy, once when started fully) >- */ >- protected Map<Bundle, Object> lazyBundleCache = new WeakHashMap<Bundle, Object>(); >- /** dummy value for the bundle cache */ >- private final Object VALUE = new Object(); >- >- // caches the bundle >- protected void push(Bundle bundle) { >- synchronized (lazyBundleCache) { >- lazyBundleCache.put(bundle, VALUE); >- } >- } >- >- // checks the presence of the bundle as well as removing it >- protected boolean pop(Bundle bundle) { >- synchronized (lazyBundleCache) { >- return (lazyBundleCache.remove(bundle) != null); >- } >- } >- >- /** >- * A bundle has been started, stopped, resolved, or unresolved. This method is a synchronous callback, do not do >- * any long-running work in this thread. >- * >- * @see org.osgi.framework.SynchronousBundleListener#bundleChanged >- */ >- public void bundleChanged(BundleEvent event) { >- >- boolean trace = log.isTraceEnabled(); >- >- // check if the listener is still alive >- if (isClosed) { >- if (trace) >- log.trace("Listener is closed; events are being ignored"); >- return; >- } >- if (trace) { >- log.trace("Processing bundle event [" + OsgiStringUtils.nullSafeToString(event) + "] for bundle [" >- + OsgiStringUtils.nullSafeSymbolicName(event.getBundle()) + "]"); >- } >- try { >- handleEvent(event); >- } catch (Exception ex) { >- /* log exceptions before swallowing */ >- log.warn("Got exception while handling event " + event, ex); >- } >- } >- >- protected abstract void handleEvent(BundleEvent event); >- } >- >- /** >- * Bundle listener used for detecting namespace handler/resolvers. Exists as a separate listener so that it can be >- * registered early to avoid race conditions with bundles in INSTALLING state but still to avoid premature context >- * creation before the Spring {@link ContextLoaderListener} is not fully initialized. >- * >- * @author Costin Leau >- */ >- private class NamespaceBundleLister extends BaseListener { >- >- private final boolean resolved; >- >- NamespaceBundleLister(boolean resolvedBundles) { >- this.resolved = resolvedBundles; >- } >- >- protected void handleEvent(BundleEvent event) { >- Bundle bundle = event.getBundle(); >- >- switch (event.getType()) { >- >- case BundleEvent.RESOLVED: >- if (resolved) { >- maybeAddNamespaceHandlerFor(bundle, false); >- } >- break; >- >- case LAZY_ACTIVATION_EVENT_TYPE: { >- if (!resolved) { >- push(bundle); >- maybeAddNamespaceHandlerFor(bundle, true); >- } >- break; >- } >- case BundleEvent.STARTED: { >- if (!resolved) { >- if (!pop(bundle)) { >- maybeAddNamespaceHandlerFor(bundle, false); >- } >- } >- break; >- } >- case BundleEvent.STOPPED: { >- pop(bundle); >- maybeRemoveNameSpaceHandlerFor(bundle); >- break; >- } >- default: >- break; >- } >- } >- } >- >- /** >+ /** > * Bundle listener used for context creation/destruction. > */ > private class ContextBundleListener extends BaseListener { >@@ -205,14 +77,14 @@ public class ContextLoaderListener implements BundleActivator { > > Bundle bundle = event.getBundle(); > >- // ignore current bundle for context creation >+ // ignore current bundle for context creation > if (bundle.getBundleId() == bundleId) { > return; > } > > switch (event.getType()) { > case LAZY_ACTIVATION_EVENT_TYPE: { >- // activate bundle >+ // activate bundle > try { > bundle.loadClass("org.osgi.service.blueprint.container.BlueprintContainer"); > } catch (Exception ex) { >@@ -228,8 +100,8 @@ public class ContextLoaderListener implements BundleActivator { > if (log.isDebugEnabled()) { > log.debug("System bundle stopping"); > } >- // System bundle is shutting down; Special handling for >- // framework shutdown >+ // System bundle is shutting down; Special handling for >+ // framework shutdown > shutdown(); > } else { > lifecycleManager.maybeCloseApplicationContextFor(bundle); >@@ -244,23 +116,18 @@ public class ContextLoaderListener implements BundleActivator { > > protected final Log log = LogFactory.getLog(getClass()); > >- /** extender bundle id */ >- private long bundleId; >- >- /** extender configuration */ >- private ExtenderConfiguration extenderConfiguration; >+ private ExtenderConfiguration extenderConfiguration; >+ private VersionMatcher versionMatcher; >+ private Version extenderVersion; > >- /** Spring namespace/resolver manager */ >- private NamespaceManager nsManager; >+ /** extender bundle id */ >+ private long bundleId; > > /** The bundle's context */ > private BundleContext bundleContext; > > /** Bundle listener interested in context creation */ >- private SynchronousBundleListener contextListener; >- >- /** Bundle listener interested in namespace resolvers/parsers discovery */ >- private SynchronousBundleListener nsListener; >+ private BaseListener contextListener; > > /** > * Monitor used for dealing with the bundle activator and synchronous bundle threads >@@ -272,60 +139,44 @@ public class ContextLoaderListener implements BundleActivator { > */ > private volatile boolean isClosed = false; > >- /** This extender version */ >- private Version extenderVersion; >- >- private volatile OsgiBundleApplicationContextEventMulticaster multicaster; >- > private volatile LifecycleManager lifecycleManager; >- private volatile VersionMatcher versionMatcher; > private volatile OsgiContextProcessor processor; >- private volatile ListListenerAdapter osgiListeners; > >- /** >+ public ContextLoaderListener(ExtenderConfiguration extenderConfiguration) { >+ this.extenderConfiguration = extenderConfiguration; >+ } >+ >+ /** > * <p/> Called by OSGi when this bundle is started. Finds all previously resolved bundles and adds namespace > * handlers for them if necessary. </p> <p/> Creates application contexts for bundles started before the extender > * was started. </p> <p/> Registers a namespace/entity resolving service for use by web app contexts. </p> > * > * @see org.osgi.framework.BundleActivator#start > */ >- public void start(BundleContext context) throws Exception { >- >- this.bundleContext = context; >- this.bundleId = context.getBundle().getBundleId(); >- >- this.extenderVersion = OsgiBundleUtils.getBundleVersion(context.getBundle()); >- log.info("Starting [" + bundleContext.getBundle().getSymbolicName() + "] bundle v.[" + extenderVersion + "]"); >- versionMatcher = new DefaultVersionMatcher(getManagedBundleExtenderVersionHeader(), extenderVersion); >- processor = createContextProcessor(); >- >- // init cache (to prevent ad-hoc Java Bean discovery on lazy bundles) >- initJavaBeansCache(); >- >- // Step 1 : discover existing namespaces (in case there are fragments with custom XML definitions) >- nsManager = new NamespaceManager(context); >- initNamespaceHandlers(bundleContext); >- >- // Step 2: initialize the extender configuration >- extenderConfiguration = initExtenderConfiguration(bundleContext); >- >- // init the OSGi event dispatch/listening system >- initListenerService(); >- >- // initialize the configuration once namespace handlers have been detected >- lifecycleManager = >- new LifecycleManager(extenderConfiguration, versionMatcher, createContextConfigFactory(), >- this.processor, getTypeCompatibilityChecker(), bundleContext); >- >- // Step 3: discover the bundles that are started >- // and require context creation >+ public void start(BundleContext extenderBundleContext) throws Exception { >+ >+ this.bundleContext = extenderBundleContext; >+ this.bundleId = extenderBundleContext.getBundle().getBundleId(); >+ this.extenderVersion = OsgiBundleUtils.getBundleVersion(extenderBundleContext.getBundle()); >+ this.versionMatcher = new DefaultVersionMatcher(getManagedBundleExtenderVersionHeader(), extenderVersion); >+ this.processor = createContextProcessor(); >+ >+ // initialize the configuration once namespace handlers have been detected >+ this.lifecycleManager = >+ new LifecycleManager( >+ this.extenderConfiguration, >+ getVersionMatcher(), >+ createContextConfigFactory(), >+ getOsgiApplicationContextCreator(), >+ this.processor, >+ getTypeCompatibilityChecker(), >+ bundleContext); >+ >+ // Step 3: discover the bundles that are started >+ // and require context creation > initStartedBundles(bundleContext); > } > >- protected ExtenderConfiguration initExtenderConfiguration(BundleContext bundleContext) { >- return new ExtenderConfiguration(bundleContext, log); >- } >- > protected OsgiContextProcessor createContextProcessor() { > return new NoOpOsgiContextProcessor(); > } >@@ -334,46 +185,16 @@ public class ContextLoaderListener implements BundleActivator { > return null; > } > >- protected String getManagedBundleExtenderVersionHeader() { >- return ConfigUtils.EXTENDER_VERSION; >- } >- >- protected void initNamespaceHandlers(BundleContext context) { >- nsManager = new NamespaceManager(context); >- >- // register listener first to make sure any bundles in INSTALLED state >- // are not lost >- >- // if the property is defined and true, consider bundles in STARTED/LAZY-INIT state, otherwise use RESOLVED >- boolean nsResolved = !Boolean.getBoolean("org.eclipse.gemini.blueprint.ns.bundles.started"); >- nsListener = new NamespaceBundleLister(nsResolved); >- context.addBundleListener(nsListener); >- >- Bundle[] previousBundles = context.getBundles(); >- >- for (Bundle bundle : previousBundles) { >- // special handling for uber bundle being restarted >- if ((nsResolved && OsgiBundleUtils.isBundleResolved(bundle)) || (!nsResolved && OsgiBundleUtils.isBundleActive(bundle)) || bundleId == bundle.getBundleId()) { >- maybeAddNamespaceHandlerFor(bundle, false); >- } else if (OsgiBundleUtils.isBundleLazyActivated(bundle)) { >- maybeAddNamespaceHandlerFor(bundle, true); >- } >- } >- >- // discovery finished, publish the resolvers/parsers in the OSGi space >- nsManager.afterPropertiesSet(); >- } >- > protected void initStartedBundles(BundleContext bundleContext) { >- // register the context creation listener >+ // register the context creation listener > contextListener = new ContextBundleListener(); >- // listen to any changes in bundles >+ // listen to any changes in bundles > bundleContext.addBundleListener(contextListener); >- // get the bundles again to get an updated view >+ // get the bundles again to get an updated view > Bundle[] previousBundles = bundleContext.getBundles(); > >- // Instantiate all previously resolved bundles which are Spring >- // powered >+ // Instantiate all previously resolved bundles which are Spring >+ // powered > for (int i = 0; i < previousBundles.length; i++) { > if (OsgiBundleUtils.isBundleActive(previousBundles[i])) { > try { >@@ -403,105 +224,46 @@ public class ContextLoaderListener implements BundleActivator { > */ > protected void shutdown() { > synchronized (monitor) { >- // if already closed, bail out >+ // if already closed, bail out > if (isClosed) > return; > else > isClosed = true; > } >- log.info("Stopping [" + bundleContext.getBundle().getSymbolicName() + "] bundle v.[" + extenderVersion + "]"); > >- destroyJavaBeansCache(); >+ this.contextListener.close(); > >- // remove the bundle listeners (we are closing down) >+ // remove the bundle listeners (we are closing down) > if (contextListener != null) { > bundleContext.removeBundleListener(contextListener); > contextListener = null; > } > >- if (nsListener != null) { >- bundleContext.removeBundleListener(nsListener); >- nsListener = null; >- } >- >- // close managed bundles >+ // close managed bundles > lifecycleManager.destroy(); >- // clear the namespace registry >- nsManager.destroy(); >- >- // release multicaster >- if (multicaster != null) { >- multicaster.removeAllListeners(); >- multicaster = null; >- } >- // release listeners >- osgiListeners.destroy(); >- osgiListeners = null; >- >- extenderConfiguration.destroy(); >- } >- >- private void initJavaBeansCache() { >- Class<?>[] classes = >- new Class<?>[] { OsgiServiceFactoryBean.class, OsgiServiceProxyFactoryBean.class, >- OsgiServiceCollectionProxyFactoryBean.class }; >- >- CachedIntrospectionResults.acceptClassLoader(OsgiStringUtils.class.getClassLoader()); >- >- for (Class<?> clazz : classes) { >- BeanUtils.getPropertyDescriptors(clazz); >- } >- } >- >- private void destroyJavaBeansCache() { >- CachedIntrospectionResults.clearClassLoader(OsgiStringUtils.class.getClassLoader()); >- } >- >- protected void maybeAddNamespaceHandlerFor(Bundle bundle, boolean isLazy) { >- if (handlerBundleMatchesExtenderVersion(bundle)) >- nsManager.maybeAddNamespaceHandlerFor(bundle, isLazy); >- } >- >- protected void maybeRemoveNameSpaceHandlerFor(Bundle bundle) { >- if (handlerBundleMatchesExtenderVersion(bundle)) >- nsManager.maybeRemoveNameSpaceHandlerFor(bundle); >- } >- >- /** >- * Utility method that does extender range versioning and approapriate >- * >- * logging. >- * >- * @param bundle >- */ >- private boolean handlerBundleMatchesExtenderVersion(Bundle bundle) { >- if (!versionMatcher.matchVersion(bundle)) { >- if (log.isDebugEnabled()) >- log.debug("Ignoring handler bundle " + OsgiStringUtils.nullSafeNameAndSymName(bundle) >- + "] due to mismatch in expected extender version"); >- return false; >- } >- return true; > } > > protected ApplicationContextConfigurationFactory createContextConfigFactory() { > return new DefaultApplicationContextConfigurationFactory(); > } > >- protected void initListenerService() { >- multicaster = extenderConfiguration.getEventMulticaster(); >- >- addApplicationListener(multicaster); >- multicaster.addApplicationListener(extenderConfiguration.getContextEventListener()); >- >- if (log.isDebugEnabled()) >- log.debug("Initialization of OSGi listeners service completed..."); >- } >- >- protected void addApplicationListener(OsgiBundleApplicationContextEventMulticaster multicaster) { >- osgiListeners = new ListListenerAdapter(bundleContext); >- osgiListeners.afterPropertiesSet(); >- // register the listener that does the dispatching >- multicaster.addApplicationListener(osgiListeners); >- } >+ public VersionMatcher getVersionMatcher() { >+ return versionMatcher; >+ } >+ >+ protected String getManagedBundleExtenderVersionHeader() { >+ return ConfigUtils.EXTENDER_VERSION; >+ } >+ >+ protected OsgiApplicationContextCreator getOsgiApplicationContextCreator() { >+ OsgiApplicationContextCreator creator = this.extenderConfiguration.getContextCreator(); >+ if (creator == null) { >+ creator = createDefaultOsgiApplicationContextCreator(); >+ } >+ return creator; >+ } >+ >+ protected OsgiApplicationContextCreator createDefaultOsgiApplicationContextCreator() { >+ return new DefaultOsgiApplicationContextCreator(); >+ } > } >\ No newline at end of file >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/JavaBeansCacheActivator.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/JavaBeansCacheActivator.java >new file mode 100644 >index 0000000..173df66 >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/JavaBeansCacheActivator.java >@@ -0,0 +1,60 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator; >+ >+import org.eclipse.gemini.blueprint.service.exporter.support.OsgiServiceFactoryBean; >+import org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceCollectionProxyFactoryBean; >+import org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceProxyFactoryBean; >+import org.eclipse.gemini.blueprint.util.OsgiStringUtils; >+import org.osgi.framework.BundleActivator; >+import org.osgi.framework.BundleContext; >+import org.springframework.beans.BeanUtils; >+import org.springframework.beans.CachedIntrospectionResults; >+ >+/** >+ * Used to prevent ad-hoc Java Bean discovery on lazy bundles. >+ * >+ * @author Bill Gallagher >+ * @author Andy Piper >+ * @author Hal Hildebrand >+ * @author Adrian Colyer >+ * @author Costin Leau >+ * @author Olaf Otto >+ */ >+public class JavaBeansCacheActivator implements BundleActivator { >+ /** >+ * Monitor used for dealing with the bundle activator and synchronous bundle threads >+ */ >+ private final Object monitor = new Object(); >+ private boolean stopped = false; >+ >+ public void start(BundleContext extenderBundleContext) { >+ initJavaBeansCache(); >+ } >+ >+ public void stop(BundleContext extenderBundleContext) { >+ synchronized (monitor) { >+ if (stopped) { >+ return; >+ } >+ stopped = true; >+ } >+ destroyJavaBeansCache(); >+ } >+ >+ private void initJavaBeansCache() { >+ Class<?>[] classes = >+ new Class<?>[] { OsgiServiceFactoryBean.class, OsgiServiceProxyFactoryBean.class, >+ OsgiServiceCollectionProxyFactoryBean.class }; >+ >+ CachedIntrospectionResults.acceptClassLoader(OsgiStringUtils.class.getClassLoader()); >+ >+ for (Class<?> clazz : classes) { >+ BeanUtils.getPropertyDescriptors(clazz); >+ } >+ } >+ >+ private void destroyJavaBeansCache() { >+ CachedIntrospectionResults.clearClassLoader(OsgiStringUtils.class.getClassLoader()); >+ } >+} >+ >+ >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LifecycleManager.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LifecycleManager.java >index 5ad01f2..d563751 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LifecycleManager.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LifecycleManager.java >@@ -14,14 +14,6 @@ > > package org.eclipse.gemini.blueprint.extender.internal.activator; > >-import java.util.ArrayList; >-import java.util.Collection; >-import java.util.Collections; >-import java.util.List; >-import java.util.Map; >-import java.util.Timer; >-import java.util.concurrent.ConcurrentHashMap; >- > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > import org.eclipse.gemini.blueprint.context.ConfigurableOsgiBundleApplicationContext; >@@ -45,6 +37,9 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor; > import org.springframework.core.task.SyncTaskExecutor; > import org.springframework.core.task.TaskExecutor; > >+import java.util.*; >+import java.util.concurrent.ConcurrentHashMap; >+ > /** > * Manager handling the startup/shutdown threading issues regarding OSGi contexts. Used by {@link ContextLoaderListener} > * . >@@ -100,13 +95,13 @@ class LifecycleManager implements DisposableBean { > private final TypeCompatibilityChecker typeChecker; > > LifecycleManager(ExtenderConfiguration extenderConfiguration, VersionMatcher versionMatcher, >- ApplicationContextConfigurationFactory appCtxCfgFactory, OsgiContextProcessor processor, >- TypeCompatibilityChecker checker, BundleContext context) { >+ ApplicationContextConfigurationFactory appCtxCfgFactory, OsgiApplicationContextCreator osgiApplicationContextCreator, OsgiContextProcessor processor, >+ TypeCompatibilityChecker checker, BundleContext context) { > > this.versionMatcher = versionMatcher; > this.extenderConfiguration = extenderConfiguration; > this.contextConfigurationFactory = appCtxCfgFactory; >- >+ this.contextCreator = osgiApplicationContextCreator; > this.processor = processor; > > this.taskExecutor = extenderConfiguration.getTaskExecutor(); >@@ -114,7 +109,6 @@ class LifecycleManager implements DisposableBean { > > this.multicaster = extenderConfiguration.getEventMulticaster(); > >- this.contextCreator = extenderConfiguration.getContextCreator(); > this.postProcessors = extenderConfiguration.getPostProcessors(); > this.typeChecker = checker; > >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListListenerAdapter.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListListenerAdapter.java >index bcb9283..fdba26c 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListListenerAdapter.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListListenerAdapter.java >@@ -14,19 +14,16 @@ > > package org.eclipse.gemini.blueprint.extender.internal.activator; > >-import java.lang.reflect.ParameterizedType; >-import java.lang.reflect.Type; >-import java.lang.reflect.TypeVariable; >-import java.util.Map; >-import java.util.WeakHashMap; >- >+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEvent; >+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener; > import org.osgi.framework.BundleContext; > import org.osgi.util.tracker.ServiceTracker; > import org.springframework.beans.factory.DisposableBean; > import org.springframework.beans.factory.InitializingBean; > import org.springframework.core.GenericTypeResolver; >-import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEvent; >-import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextListener; >+ >+import java.util.Map; >+import java.util.WeakHashMap; > > /** > * Listener interface that delegates to a list of listener. This is useful in OSGi environments when dealing with >@@ -45,8 +42,6 @@ class ListListenerAdapter implements OsgiBundleApplicationContextListener<OsgiBu > > /** > * Constructs a new <code>ListListenerAdapter</code> instance. >- * >- * @param listeners > */ > public ListListenerAdapter(BundleContext bundleContext) { > this.tracker = new ServiceTracker(bundleContext, OsgiBundleApplicationContextListener.class.getName(), null); >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListenerServiceActivator.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListenerServiceActivator.java >new file mode 100644 >index 0000000..6594303 >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/ListenerServiceActivator.java >@@ -0,0 +1,79 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticaster; >+import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; >+import org.osgi.framework.BundleActivator; >+import org.osgi.framework.BundleContext; >+ >+/** >+ * Initializes the event multicaster infrastructure. >+ * >+ * @author Bill Gallagher >+ * @author Andy Piper >+ * @author Hal Hildebrand >+ * @author Adrian Colyer >+ * @author Costin Leau >+ * @author Olaf Otto >+ */ >+public class ListenerServiceActivator implements BundleActivator { >+ /** >+ * Monitor used for dealing with the bundle activator and synchronous bundle threads >+ */ >+ private final Object monitor = new Object(); >+ private boolean stopped = false; >+ private OsgiBundleApplicationContextEventMulticaster multicaster; >+ private volatile ListListenerAdapter osgiListeners; >+ private final Log log = LogFactory.getLog(getClass()); >+ private final ExtenderConfiguration extenderConfiguration; >+ private BundleContext extenderBundleContext; >+ >+ public ListenerServiceActivator(ExtenderConfiguration extenderConfiguration) { >+ this.extenderConfiguration = extenderConfiguration; >+ } >+ >+ public void start(BundleContext extenderBundleContext) throws Exception { >+ this.extenderBundleContext = extenderBundleContext; >+ initListenerService(); >+ } >+ >+ public void stop(BundleContext extenderBundleContext) throws Exception { >+ synchronized (monitor) { >+ if (stopped) { >+ return; >+ } >+ stopped = true; >+ } >+ >+ // release multicaster >+ if (multicaster != null) { >+ multicaster.removeAllListeners(); >+ multicaster = null; >+ } >+ // release listeners >+ osgiListeners.destroy(); >+ osgiListeners = null; >+ } >+ >+ protected void initListenerService() { >+ this.multicaster = extenderConfiguration.getEventMulticaster(); >+ >+ addApplicationListener(multicaster); >+ multicaster.addApplicationListener(extenderConfiguration.getContextEventListener()); >+ >+ if (log.isDebugEnabled()) >+ log.debug("Initialization of OSGi listeners service completed..."); >+ } >+ >+ protected void addApplicationListener(OsgiBundleApplicationContextEventMulticaster multicaster) { >+ osgiListeners = new ListListenerAdapter(this.extenderBundleContext); >+ osgiListeners.afterPropertiesSet(); >+ // register the listener that does the dispatching >+ multicaster.addApplicationListener(osgiListeners); >+ } >+ >+ public OsgiBundleApplicationContextEventMulticaster getMulticaster() { >+ return multicaster; >+ } >+} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LoggingActivator.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LoggingActivator.java >new file mode 100644 >index 0000000..0e79f49 >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/LoggingActivator.java >@@ -0,0 +1,27 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils; >+import org.osgi.framework.BundleActivator; >+import org.osgi.framework.BundleContext; >+import org.osgi.framework.Version; >+ >+/** >+ * Simply writes status convenient status information to the log. >+ * >+ * @author Olaf Otto >+ */ >+public class LoggingActivator implements BundleActivator { >+ private final Log log = LogFactory.getLog(getClass()); >+ >+ public void start(BundleContext extenderBundleContext) throws Exception { >+ Version extenderVersion = OsgiBundleUtils.getBundleVersion(extenderBundleContext.getBundle()); >+ log.info("Starting [" + extenderBundleContext.getBundle().getSymbolicName() + "] bundle v.[" + extenderVersion + "]"); >+ } >+ >+ public void stop(BundleContext extenderBundleContext) throws Exception { >+ Version extenderVersion = OsgiBundleUtils.getBundleVersion(extenderBundleContext.getBundle()); >+ log.info("Stopping [" + extenderBundleContext.getBundle().getSymbolicName() + "] bundle v.[" + extenderVersion + "]"); >+ } >+} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/NamespaceHandlerActivator.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/NamespaceHandlerActivator.java >new file mode 100644 >index 0000000..c33ced0 >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/NamespaceHandlerActivator.java >@@ -0,0 +1,115 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.eclipse.gemini.blueprint.extender.internal.activator.listeners.BaseListener; >+import org.eclipse.gemini.blueprint.extender.internal.activator.listeners.NamespaceBundleLister; >+import org.eclipse.gemini.blueprint.extender.internal.support.NamespaceManager; >+import org.eclipse.gemini.blueprint.extender.support.internal.ConfigUtils; >+import org.eclipse.gemini.blueprint.util.OsgiBundleUtils; >+import org.eclipse.gemini.blueprint.util.OsgiStringUtils; >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleActivator; >+import org.osgi.framework.BundleContext; >+import org.osgi.framework.Version; >+ >+/** >+ * @author Bill Gallagher >+ * @author Andy Piper >+ * @author Hal Hildebrand >+ * @author Adrian Colyer >+ * @author Costin Leau >+ * @author Olaf Otto >+ */ >+public class NamespaceHandlerActivator implements BundleActivator { >+ /** >+ * Monitor used for dealing with the bundle activator and synchronous bundle threads >+ */ >+ private final Object monitor = new Object(); >+ private boolean stopped = false; >+ private final Log log = LogFactory.getLog(getClass()); >+ private NamespaceManager nsManager; >+ private BaseListener nsListener; >+ private long bundleId; >+ private BundleContext extenderBundleContext; >+ private DefaultVersionMatcher versionMatcher; >+ >+ public void start(BundleContext extenderBundleContext) { >+ this.extenderBundleContext = extenderBundleContext; >+ this.nsManager = new NamespaceManager(extenderBundleContext); >+ this.bundleId = extenderBundleContext.getBundle().getBundleId(); >+ Version extenderVersion = OsgiBundleUtils.getBundleVersion(extenderBundleContext.getBundle()); >+ this.versionMatcher = new DefaultVersionMatcher(getManagedBundleExtenderVersionHeader(), extenderVersion); >+ >+ initNamespaceHandlers(extenderBundleContext); >+ } >+ >+ public void stop(BundleContext context) throws Exception { >+ synchronized (monitor) { >+ if (stopped) { >+ return; >+ } >+ stopped = true; >+ } >+ >+ this.nsListener.close(); >+ this.extenderBundleContext.removeBundleListener(this.nsListener); >+ this.nsListener = null; >+ this.nsManager.destroy(); >+ } >+ >+ protected String getManagedBundleExtenderVersionHeader() { >+ return ConfigUtils.EXTENDER_VERSION; >+ } >+ >+ protected void initNamespaceHandlers(BundleContext extenderBundleContext) { >+ nsManager = new NamespaceManager(extenderBundleContext); >+ >+ // register listener first to make sure any bundles in INSTALLED state >+ // are not lost >+ >+ // if the property is defined and true, consider bundles in STARTED/LAZY-INIT state, otherwise use RESOLVED >+ boolean nsResolved = !Boolean.getBoolean("org.eclipse.gemini.blueprint.ns.bundles.started"); >+ nsListener = new NamespaceBundleLister(nsResolved, this); >+ extenderBundleContext.addBundleListener(nsListener); >+ >+ Bundle[] previousBundles = extenderBundleContext.getBundles(); >+ >+ for (Bundle bundle : previousBundles) { >+ // special handling for uber bundle being restarted >+ if ((nsResolved && OsgiBundleUtils.isBundleResolved(bundle)) || (!nsResolved && OsgiBundleUtils.isBundleActive(bundle)) || bundleId == bundle.getBundleId()) { >+ maybeAddNamespaceHandlerFor(bundle, false); >+ } else if (OsgiBundleUtils.isBundleLazyActivated(bundle)) { >+ maybeAddNamespaceHandlerFor(bundle, true); >+ } >+ } >+ >+ // discovery finished, publish the resolvers/parsers in the OSGi space >+ nsManager.afterPropertiesSet(); >+ } >+ >+ >+ public void maybeAddNamespaceHandlerFor(Bundle bundle, boolean isLazy) { >+ if (handlerBundleMatchesExtenderVersion(bundle)) { >+ nsManager.maybeAddNamespaceHandlerFor(bundle, isLazy); >+ } >+ } >+ >+ public void maybeRemoveNameSpaceHandlerFor(Bundle bundle) { >+ if (handlerBundleMatchesExtenderVersion(bundle)) >+ nsManager.maybeRemoveNameSpaceHandlerFor(bundle); >+ } >+ >+ /** >+ * Utility method that does extender range version check and appropriate logging. >+ */ >+ protected boolean handlerBundleMatchesExtenderVersion(Bundle bundle) { >+ if (!versionMatcher.matchVersion(bundle)) { >+ if (log.isDebugEnabled()) >+ log.debug("Ignoring handler bundle " + OsgiStringUtils.nullSafeNameAndSymName(bundle) >+ + "] due to mismatch in expected extender version"); >+ return false; >+ } >+ return true; >+ } >+} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/BaseListener.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/BaseListener.java >new file mode 100644 >index 0000000..0627241 >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/BaseListener.java >@@ -0,0 +1,85 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator.listeners; >+ >+import org.apache.commons.logging.Log; >+import org.apache.commons.logging.LogFactory; >+import org.eclipse.gemini.blueprint.util.OsgiStringUtils; >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleEvent; >+import org.osgi.framework.SynchronousBundleListener; >+ >+import java.util.Map; >+import java.util.WeakHashMap; >+ >+/** >+ * Common base class for {@link org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener} listeners. >+ * >+ * @author Costin Leau >+ */ >+public abstract class BaseListener implements SynchronousBundleListener { >+ public static final int LAZY_ACTIVATION_EVENT_TYPE = 0x00000200; >+ >+ protected final Log log = LogFactory.getLog(getClass()); >+ >+ /** >+ * flag indicating whether the context is down or not - useful during shutdown >+ */ >+ private volatile boolean isClosed = false; >+ >+ /** >+ * common cache used for tracking down bundles started lazily so they don't get processed twice (once when >+ * started lazy, once when started fully) >+ */ >+ protected final Map<Bundle, Object> lazyBundleCache = new WeakHashMap<Bundle, Object>(); >+ /** >+ * dummy value for the bundle cache >+ */ >+ private final Object VALUE = new Object(); >+ >+ // caches the bundle >+ protected void push(Bundle bundle) { >+ synchronized (lazyBundleCache) { >+ lazyBundleCache.put(bundle, VALUE); >+ } >+ } >+ >+ // checks the presence of the bundle as well as removing it >+ protected boolean pop(Bundle bundle) { >+ synchronized (lazyBundleCache) { >+ return (lazyBundleCache.remove(bundle) != null); >+ } >+ } >+ >+ /** >+ * A bundle has been started, stopped, resolved, or unresolved. This method is a synchronous callback, do not do >+ * any long-running work in this thread. >+ * >+ * @see org.osgi.framework.SynchronousBundleListener#bundleChanged >+ */ >+ public void bundleChanged(BundleEvent event) { >+ >+ boolean trace = log.isTraceEnabled(); >+ >+ // check if the listener is still alive >+ if (isClosed) { >+ if (trace) >+ log.trace("Listener is closed; events are being ignored"); >+ return; >+ } >+ if (trace) { >+ log.trace("Processing bundle event [" + OsgiStringUtils.nullSafeToString(event) + "] for bundle [" >+ + OsgiStringUtils.nullSafeSymbolicName(event.getBundle()) + "]"); >+ } >+ try { >+ handleEvent(event); >+ } catch (Exception ex) { >+ /* log exceptions before swallowing */ >+ log.warn("Got exception while handling event " + event, ex); >+ } >+ } >+ >+ protected abstract void handleEvent(BundleEvent event); >+ >+ public void close() { >+ this.isClosed = true; >+ } >+} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/NamespaceBundleLister.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/NamespaceBundleLister.java >new file mode 100644 >index 0000000..9ff17be >--- /dev/null >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/activator/listeners/NamespaceBundleLister.java >@@ -0,0 +1,59 @@ >+package org.eclipse.gemini.blueprint.extender.internal.activator.listeners; >+ >+import org.eclipse.gemini.blueprint.extender.internal.activator.NamespaceHandlerActivator; >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleEvent; >+ >+/** >+ * Bundle listener used for detecting namespace handler/resolvers. Exists as a separate listener so that it can be >+ * registered early to avoid race conditions with bundles in INSTALLING state but still to avoid premature context >+ * creation before the Spring {@link org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener} is not fully initialized. >+ * >+ * @author Costin Leau >+ */ >+public class NamespaceBundleLister extends BaseListener { >+ >+ private final boolean resolved; >+ private final NamespaceHandlerActivator namespaceHandlerActivator; >+ >+ public NamespaceBundleLister(boolean resolvedBundles, NamespaceHandlerActivator namespaceHandlerActivator) { >+ this.resolved = resolvedBundles; >+ this.namespaceHandlerActivator = namespaceHandlerActivator; >+ } >+ >+ protected void handleEvent(BundleEvent event) { >+ Bundle bundle = event.getBundle(); >+ >+ switch (event.getType()) { >+ >+ case BundleEvent.RESOLVED: >+ if (resolved) { >+ this.namespaceHandlerActivator.maybeAddNamespaceHandlerFor(bundle, false); >+ } >+ break; >+ >+ case LAZY_ACTIVATION_EVENT_TYPE: { >+ if (!resolved) { >+ push(bundle); >+ this.namespaceHandlerActivator.maybeAddNamespaceHandlerFor(bundle, true); >+ } >+ break; >+ } >+ case BundleEvent.STARTED: { >+ if (!resolved) { >+ if (!pop(bundle)) { >+ this.namespaceHandlerActivator.maybeAddNamespaceHandlerFor(bundle, false); >+ } >+ } >+ break; >+ } >+ case BundleEvent.STOPPED: { >+ pop(bundle); >+ this.namespaceHandlerActivator.maybeRemoveNameSpaceHandlerFor(bundle); >+ break; >+ } >+ default: >+ break; >+ } >+ } >+} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/BlueprintLoaderListener.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/BlueprintLoaderListener.java >index 27fb197..8104e4c 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/BlueprintLoaderListener.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/BlueprintLoaderListener.java >@@ -14,19 +14,16 @@ > > package org.eclipse.gemini.blueprint.extender.internal.blueprint.activator; > >-import org.osgi.framework.Bundle; >-import org.osgi.framework.BundleContext; >-import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticaster; >-import org.eclipse.gemini.blueprint.extender.internal.activator.ApplicationContextConfigurationFactory; >-import org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener; >-import org.eclipse.gemini.blueprint.extender.internal.activator.OsgiContextProcessor; >-import org.eclipse.gemini.blueprint.extender.internal.activator.TypeCompatibilityChecker; >+import org.eclipse.gemini.blueprint.extender.OsgiApplicationContextCreator; >+import org.eclipse.gemini.blueprint.extender.internal.activator.*; > import org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintConfigUtils; > import org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintContainerConfig; >-import org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintExtenderConfiguration; >+import org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support.BlueprintContainerCreator; > import org.eclipse.gemini.blueprint.extender.internal.blueprint.event.EventAdminDispatcher; > import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; > import org.eclipse.gemini.blueprint.extender.support.ApplicationContextConfiguration; >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleContext; > > /** > * RFC124 extension to the Spring DM extender. >@@ -34,21 +31,24 @@ import org.eclipse.gemini.blueprint.extender.support.ApplicationContextConfigura > * @author Costin Leau > */ > public class BlueprintLoaderListener extends ContextLoaderListener { >- >- private volatile EventAdminDispatcher dispatcher; >- private volatile BlueprintListenerManager listenerManager; >- private volatile Bundle bundle; >- private volatile BlueprintContainerProcessor contextProcessor; >+ private volatile BlueprintListenerManager listenerManager; >+ private volatile BlueprintContainerProcessor contextProcessor; > private volatile TypeCompatibilityChecker typeChecker; >+ private ListenerServiceActivator listenerServiceActivator; > >- @Override >+ public BlueprintLoaderListener(ExtenderConfiguration extenderConfiguration, ListenerServiceActivator listenerServiceActivator) { >+ super(extenderConfiguration); >+ this.listenerServiceActivator = listenerServiceActivator; >+ } >+ >+ @Override > public void start(BundleContext context) throws Exception { > this.listenerManager = new BlueprintListenerManager(context); >- this.dispatcher = new EventAdminDispatcher(context); >- this.bundle = context.getBundle(); >+ EventAdminDispatcher dispatcher = new EventAdminDispatcher(context); >+ Bundle bundle = context.getBundle(); > this.contextProcessor = new BlueprintContainerProcessor(dispatcher, listenerManager, bundle); > this.typeChecker = new BlueprintTypeCompatibilityChecker(bundle); >- >+ this.listenerServiceActivator.getMulticaster().addApplicationListener(this.contextProcessor); > super.start(context); > } > >@@ -59,11 +59,6 @@ public class BlueprintLoaderListener extends ContextLoaderListener { > } > > @Override >- protected ExtenderConfiguration initExtenderConfiguration(BundleContext bundleContext) { >- return new BlueprintExtenderConfiguration(bundleContext, log); >- } >- >- @Override > protected ApplicationContextConfigurationFactory createContextConfigFactory() { > return new ApplicationContextConfigurationFactory() { > >@@ -73,7 +68,18 @@ public class BlueprintLoaderListener extends ContextLoaderListener { > }; > } > >- @Override >+ /** >+ * Always use the {@link BlueprintContainerCreator}, never the configured creator. >+ * Rationale: Backwards compatibility. Both DM and Blueprint extenders are available simultaneously, >+ * however Blueprint extender support is new and must not be broken by existing configurations. Otherwise, existing >+ * users would have to make their creators aware of the difference between blueprint and dm containers. >+ */ >+ @Override >+ protected OsgiApplicationContextCreator getOsgiApplicationContextCreator() { >+ return new BlueprintContainerCreator(); >+ } >+ >+ @Override > protected OsgiContextProcessor createContextProcessor() { > return contextProcessor; > } >@@ -87,15 +93,4 @@ public class BlueprintLoaderListener extends ContextLoaderListener { > protected String getManagedBundleExtenderVersionHeader() { > return BlueprintConfigUtils.EXTENDER_VERSION; > } >- >- @Override >- protected void addApplicationListener(OsgiBundleApplicationContextEventMulticaster multicaster) { >- super.addApplicationListener(multicaster); >- // monitor bootstrapping events >- multicaster.addApplicationListener(contextProcessor); >- } >- >- protected ApplicationContextConfiguration createContextConfig(Bundle bundle) { >- return new BlueprintContainerConfig(bundle); >- } > } >\ No newline at end of file >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/support/BlueprintExtenderConfiguration.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/support/BlueprintExtenderConfiguration.java >deleted file mode 100644 >index e95e7ac..0000000 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/blueprint/activator/support/BlueprintExtenderConfiguration.java >+++ /dev/null >@@ -1,44 +0,0 @@ >-/****************************************************************************** >- * 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.extender.internal.blueprint.activator.support; >- >-import org.apache.commons.logging.Log; >-import org.eclipse.gemini.blueprint.extender.OsgiApplicationContextCreator; >-import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; >-import org.osgi.framework.BundleContext; >- >-/** >- * Extension of the default extender configuration for handling RFC 124 extender semantics. >- * >- * @author Costin Leau >- * >- */ >-public class BlueprintExtenderConfiguration extends ExtenderConfiguration { >- >- private final OsgiApplicationContextCreator contextCreator = new BlueprintContainerCreator(); >- >- /** >- * Constructs a new <code>BlueprintExtenderConfiguration</code> instance. >- * >- * @param bundleContext >- */ >- public BlueprintExtenderConfiguration(BundleContext bundleContext, Log log) { >- super(bundleContext, log); >- } >- >- public OsgiApplicationContextCreator getContextCreator() { >- return contextCreator; >- } >-} >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/boot/ChainActivator.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/boot/ChainActivator.java >index a1605a6..98ad295 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/boot/ChainActivator.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/boot/ChainActivator.java >@@ -16,18 +16,19 @@ package org.eclipse.gemini.blueprint.extender.internal.boot; > > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; >+import org.eclipse.gemini.blueprint.extender.internal.activator.*; >+import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; > import org.osgi.framework.BundleActivator; > import org.osgi.framework.BundleContext; >-import org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener; > import org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.BlueprintLoaderListener; > import org.eclipse.gemini.blueprint.util.OsgiPlatformDetector; > import org.springframework.util.ClassUtils; > > /** > * Bundle activator that simply the lifecycle callbacks to other activators. >- * >+ * > * @author Costin Leau >- * >+ * > */ > public class ChainActivator implements BundleActivator { > >@@ -40,19 +41,51 @@ public class ChainActivator implements BundleActivator { > private final BundleActivator[] CHAIN; > > public ChainActivator() { >- if (OsgiPlatformDetector.isR42()) { >+ final LoggingActivator logStatus = new LoggingActivator(); >+ final JavaBeansCacheActivator activateJavaBeansCache = new JavaBeansCacheActivator(); >+ final NamespaceHandlerActivator activateCustomNamespaceHandling = new NamespaceHandlerActivator(); >+ final NamespaceHandlerActivator activateBlueprintspecificNamespaceHandling = new BlueprintNamespaceHandlerActivator(); >+ final ExtenderConfiguration initializeExtenderConfiguration = new ExtenderConfiguration(); >+ final ListenerServiceActivator activateListeners = new ListenerServiceActivator(initializeExtenderConfiguration); >+ final ContextLoaderListener listenForSpringDmBundles = new ContextLoaderListener(initializeExtenderConfiguration); >+ final BlueprintLoaderListener listenForBlueprintBundles = new BlueprintLoaderListener(initializeExtenderConfiguration, activateListeners); >+ >+ if (OsgiPlatformDetector.isR42()) { > if (BLUEPRINT_AVAILABLE) { > log.info("Blueprint API detected; enabling Blueprint Container functionality"); >- CHAIN = new BundleActivator[] { new ContextLoaderListener(), new BlueprintLoaderListener() }; >+ CHAIN = new BundleActivator[] { >+ logStatus, >+ activateJavaBeansCache, >+ activateCustomNamespaceHandling, >+ activateBlueprintspecificNamespaceHandling, >+ initializeExtenderConfiguration, >+ activateListeners, >+ listenForSpringDmBundles, >+ listenForBlueprintBundles >+ }; > } > else { > log.warn("Blueprint API not found; disabling Blueprint Container functionality"); >- CHAIN = new BundleActivator[] { new ContextLoaderListener() }; >+ CHAIN = new BundleActivator[] { >+ logStatus, >+ activateJavaBeansCache, >+ activateCustomNamespaceHandling, >+ initializeExtenderConfiguration, >+ activateListeners, >+ listenForSpringDmBundles >+ }; > } > } else { > log.warn("Pre-4.2 OSGi platform detected; disabling Blueprint Container functionality"); >- CHAIN = new BundleActivator[] { new ContextLoaderListener() }; >- } >+ CHAIN = new BundleActivator[] { >+ logStatus, >+ activateJavaBeansCache, >+ activateCustomNamespaceHandling, >+ initializeExtenderConfiguration, >+ activateListeners, >+ listenForSpringDmBundles >+ }; >+ } > } > > public void start(BundleContext context) throws Exception { >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/DefaultOsgiBundleApplicationContextListener.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/DefaultOsgiBundleApplicationContextListener.java >index 073e4e6..c91fcff 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/DefaultOsgiBundleApplicationContextListener.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/DefaultOsgiBundleApplicationContextListener.java >@@ -21,10 +21,9 @@ import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextLi > import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextClosedEvent; > import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextFailedEvent; > import org.eclipse.gemini.blueprint.context.event.OsgiBundleContextRefreshedEvent; >-import org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener; > > /** >- * Default application context event logger. Logs (using the {@link ContextLoaderListener} logger, the events received. >+ * Default application context event logger. Logs (using the {@link org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener} logger, the events received. > * > * @author Costin Leau > * @author Andy Piper >diff --git a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfiguration.java b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfiguration.java >index d6dd63e..e526ef6 100644 >--- a/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfiguration.java >+++ b/extender/src/main/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfiguration.java >@@ -14,24 +14,8 @@ > > package org.eclipse.gemini.blueprint.extender.internal.support; > >-import java.io.UnsupportedEncodingException; >-import java.net.URL; >-import java.net.URLDecoder; >-import java.util.ArrayList; >-import java.util.Collections; >-import java.util.Enumeration; >-import java.util.List; >-import java.util.Properties; >-import java.util.Timer; >- > import org.apache.commons.logging.Log; >-import org.osgi.framework.Bundle; >-import org.osgi.framework.BundleContext; >-import org.springframework.beans.BeanUtils; >-import org.springframework.beans.factory.DisposableBean; >-import org.springframework.context.event.SimpleApplicationEventMulticaster; >-import org.springframework.core.task.SimpleAsyncTaskExecutor; >-import org.springframework.core.task.TaskExecutor; >+import org.apache.commons.logging.LogFactory; > import org.eclipse.gemini.blueprint.context.ConfigurableOsgiBundleApplicationContext; > import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticaster; > import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticasterAdapter; >@@ -41,25 +25,37 @@ import org.eclipse.gemini.blueprint.extender.OsgiApplicationContextCreator; > import org.eclipse.gemini.blueprint.extender.OsgiBeanFactoryPostProcessor; > import org.eclipse.gemini.blueprint.extender.OsgiServiceDependencyFactory; > import org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.MandatoryImporterDependencyFactory; >-import org.eclipse.gemini.blueprint.extender.support.DefaultOsgiApplicationContextCreator; > import org.eclipse.gemini.blueprint.extender.support.internal.ConfigUtils; > import org.eclipse.gemini.blueprint.util.BundleDelegatingClassLoader; >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleActivator; >+import org.osgi.framework.BundleContext; >+import org.springframework.beans.BeanUtils; >+import org.springframework.beans.factory.DisposableBean; >+import org.springframework.context.event.SimpleApplicationEventMulticaster; >+import org.springframework.core.task.SimpleAsyncTaskExecutor; >+import org.springframework.core.task.TaskExecutor; > import org.springframework.scheduling.timer.TimerTaskExecutor; > import org.springframework.util.Assert; > import org.springframework.util.ObjectUtils; > >+import java.io.UnsupportedEncodingException; >+import java.net.URL; >+import java.net.URLDecoder; >+import java.util.*; >+ > /** > * Configuration class for the extender. Takes care of locating the extender specific configurations and merging the > * results with the defaults. > * > * @author Costin Leau > */ >-public class ExtenderConfiguration implements DisposableBean { >+public class ExtenderConfiguration implements BundleActivator { > > /** logger */ >- private final Log log; >+ protected final Log log = LogFactory.getLog(getClass()); > >- private static final String TASK_EXECUTOR_NAME = "taskExecutor"; >+ private static final String TASK_EXECUTOR_NAME = "taskExecutor"; > > private static final String SHUTDOWN_TASK_EXECUTOR_NAME = "shutdownTaskExecutor"; > >@@ -118,10 +114,10 @@ public class ExtenderConfiguration implements DisposableBean { > > private boolean forceThreadShutdown; > >- private OsgiApplicationContextCreator contextCreator; >+ private OsgiApplicationContextCreator contextCreator = null; > > /** bundle wrapped class loader */ >- private final ClassLoader classLoader; >+ private ClassLoader classLoader; > /** List of context post processors */ > private final List<OsgiBeanFactoryPostProcessor> postProcessors = > Collections.synchronizedList(new ArrayList<OsgiBeanFactoryPostProcessor>(0)); >@@ -136,25 +132,21 @@ public class ExtenderConfiguration implements DisposableBean { > * Constructs a new <code>ExtenderConfiguration</code> instance. Locates the extender configuration, creates an > * application context which will returned the extender items. > * >- * @param bundleContext extender OSGi bundle context >+ * @param extenderBundleContext extender OSGi bundle context > */ >- public ExtenderConfiguration(BundleContext bundleContext, Log log) { >- this.log = log; >- Bundle bundle = bundleContext.getBundle(); >+ public void start(BundleContext extenderBundleContext) { >+ Bundle bundle = extenderBundleContext.getBundle(); > Properties properties = new Properties(createDefaultProperties()); > > Enumeration<?> enm = bundle.findEntries(EXTENDER_CFG_LOCATION, XML_PATTERN, false); > > if (enm == null) { > log.info("No custom extender configuration detected; using defaults..."); >- > synchronized (lock) { > taskExecutor = createDefaultTaskExecutor(); > shutdownTaskExecutor = createDefaultShutdownTaskExecutor(); > eventMulticaster = createDefaultEventMulticaster(); >- contextCreator = createDefaultApplicationContextCreator(); > contextEventListener = createDefaultApplicationContextListener(); >- > } > classLoader = BundleDelegatingClassLoader.createBundleClassLoaderFor(bundle); > } else { >@@ -163,7 +155,7 @@ public class ExtenderConfiguration implements DisposableBean { > log.info("Detected extender custom configurations at " + ObjectUtils.nullSafeToString(configs)); > // create OSGi specific XML context > ConfigurableOsgiBundleApplicationContext extenderAppCtx = new OsgiBundleXmlApplicationContext(configs); >- extenderAppCtx.setBundleContext(bundleContext); >+ extenderAppCtx.setBundleContext(extenderBundleContext); > extenderAppCtx.refresh(); > > synchronized (lock) { >@@ -187,7 +179,7 @@ public class ExtenderConfiguration implements DisposableBean { > contextCreator = > extenderConfiguration.containsBean(CONTEXT_CREATOR_NAME) ? (OsgiApplicationContextCreator) extenderConfiguration > .getBean(CONTEXT_CREATOR_NAME, OsgiApplicationContextCreator.class) >- : createDefaultApplicationContextCreator(); >+ : null; > > contextEventListener = > extenderConfiguration.containsBean(CONTEXT_LISTENER_NAME) ? (OsgiBundleApplicationContextListener) extenderConfiguration >@@ -243,7 +235,7 @@ public class ExtenderConfiguration implements DisposableBean { > * > * Cleanup the configuration items. > */ >- public void destroy() { >+ public void stop(BundleContext extenderBundleContext) { > > synchronized (lock) { > if (isMulticasterManagedInternally) { >@@ -388,10 +380,6 @@ public class ExtenderConfiguration implements DisposableBean { > return new OsgiBundleApplicationContextEventMulticasterAdapter(new SimpleApplicationEventMulticaster()); > } > >- private OsgiApplicationContextCreator createDefaultApplicationContextCreator() { >- return new DefaultOsgiApplicationContextCreator(); >- } >- > private OsgiBundleApplicationContextListener createDefaultApplicationContextListener() { > return new DefaultOsgiBundleApplicationContextListener(log); > } >diff --git a/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/ContextLoaderListenerTest.java b/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/ContextLoaderListenerTest.java >index 6c496ac..7a0362e 100644 >--- a/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/ContextLoaderListenerTest.java >+++ b/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/ContextLoaderListenerTest.java >@@ -12,112 +12,113 @@ > * VMware Inc. > *****************************************************************************/ > >-package org.eclipse.gemini.blueprint.extender.internal; >- >-import java.util.Dictionary; >-import java.util.Hashtable; >-import java.util.Properties; >- >-import junit.framework.TestCase; >- >-import org.easymock.MockControl; >+package org.eclipse.gemini.blueprint.extender.internal; >+ >+import java.util.Dictionary; >+import java.util.Hashtable; >+import java.util.Properties; >+ >+import junit.framework.TestCase; >+ >+import org.easymock.MockControl; > import org.eclipse.gemini.blueprint.extender.internal.activator.ContextLoaderListener; >+import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; > import org.eclipse.gemini.blueprint.extender.internal.support.TestTaskExecutor; > import org.eclipse.gemini.blueprint.extender.support.internal.ConfigUtils; > import org.eclipse.gemini.blueprint.mock.EntryLookupControllingMockBundle; > import org.eclipse.gemini.blueprint.mock.MockBundle; > import org.eclipse.gemini.blueprint.mock.MockBundleContext; > import org.eclipse.gemini.blueprint.mock.MockServiceRegistration; >-import org.osgi.framework.Bundle; >-import org.osgi.framework.BundleContext; >-import org.osgi.framework.BundleEvent; >-import org.osgi.framework.BundleListener; >-import org.osgi.framework.Constants; >-import org.springframework.core.io.ClassPathResource; >- >-/** >- * @author Adrian Colyer >- * >- */ >-public abstract class ContextLoaderListenerTest extends TestCase { >- >- private ContextLoaderListener listener; >- >- >- protected void setUp() throws Exception { >- super.setUp(); >- this.listener = new ContextLoaderListener(); >- } >- >- public void testStart() throws Exception { >- MockControl bundleContextControl = MockControl.createControl(BundleContext.class); >- BundleContext context = (BundleContext) bundleContextControl.getMock(); >- // platform determination >- >- // extracting bundle id from bundle >- bundleContextControl.expectAndReturn(context.getBundle(), new MockBundle()); >- >- // look for existing resolved bundles >- bundleContextControl.expectAndReturn(context.getBundles(), new Bundle[0], 2); >- >- // register namespace and entity resolving service >- // context.registerService((String[]) null, null, null); >- // bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >- // bundleContextControl.setReturnValue(null); >- >- // register context service >- context.registerService((String[]) null, null, null); >- bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >- bundleContextControl.setReturnValue(null, MockControl.ONE_OR_MORE); >- >- // create task executor >- EntryLookupControllingMockBundle aBundle = new EntryLookupControllingMockBundle(null); >- aBundle.setEntryReturnOnNextCallToGetEntry(null); >- bundleContextControl.expectAndReturn(context.getBundle(), aBundle, MockControl.ONE_OR_MORE); >- >- // listen for bundle events >- context.addBundleListener(null); >- bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >- bundleContextControl.setVoidCallable(2); >- >- bundleContextControl.expectAndReturn(context.registerService(new String[0], null, new Properties()), >- new MockServiceRegistration(), MockControl.ONE_OR_MORE); >- bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >- >- bundleContextControl.replay(); >- >- this.listener.start(context); >- bundleContextControl.verify(); >- } >- >- public void tstTaskExecutor() throws Exception { >- Dictionary headers = new Hashtable(); >- headers.put(Constants.BUNDLE_NAME, "Extender mock bundle"); >- final EntryLookupControllingMockBundle aBundle = new EntryLookupControllingMockBundle(headers); >- aBundle.setEntryReturnOnNextCallToGetEntry(new ClassPathResource("META-INF/spring/moved-extender.xml").getURL()); >- >- MockBundleContext ctx = new MockBundleContext() { >- >- public Bundle getBundle() { >- return aBundle; >- } >- }; >- >- this.listener.start(ctx); >- >- Dictionary hdrs = new Hashtable(); >- hdrs.put(ConfigUtils.SPRING_CONTEXT_HEADER, "bla bla"); >- MockBundle anotherBundle = new MockBundle(hdrs); >- anotherBundle.setBundleId(1); >- >- BundleEvent event = new BundleEvent(BundleEvent.STARTED, anotherBundle); >- >- BundleListener listener = (BundleListener) ctx.getBundleListeners().iterator().next(); >- >- TestTaskExecutor.called = false; >- >- listener.bundleChanged(event); >- assertTrue("task executor should have been called if configured properly", TestTaskExecutor.called); >- } >- >-} >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleContext; >+import org.osgi.framework.BundleEvent; >+import org.osgi.framework.BundleListener; >+import org.osgi.framework.Constants; >+import org.springframework.core.io.ClassPathResource; >+ >+/** >+ * @author Adrian Colyer >+ * >+ */ >+public abstract class ContextLoaderListenerTest extends TestCase { >+ private ContextLoaderListener listener; >+ // TODO: mock & train once there are any applications of this base class. >+ private ExtenderConfiguration configuration; >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ this.listener = new ContextLoaderListener(this.configuration); >+ } >+ >+ public void testStart() throws Exception { >+ MockControl bundleContextControl = MockControl.createControl(BundleContext.class); >+ BundleContext context = (BundleContext) bundleContextControl.getMock(); >+ // platform determination >+ >+ // extracting bundle id from bundle >+ bundleContextControl.expectAndReturn(context.getBundle(), new MockBundle()); >+ >+ // look for existing resolved bundles >+ bundleContextControl.expectAndReturn(context.getBundles(), new Bundle[0], 2); >+ >+ // register namespace and entity resolving service >+ // context.registerService((String[]) null, null, null); >+ // bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >+ // bundleContextControl.setReturnValue(null); >+ >+ // register context service >+ context.registerService((String[]) null, null, null); >+ bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >+ bundleContextControl.setReturnValue(null, MockControl.ONE_OR_MORE); >+ >+ // create task executor >+ EntryLookupControllingMockBundle aBundle = new EntryLookupControllingMockBundle(null); >+ aBundle.setEntryReturnOnNextCallToGetEntry(null); >+ bundleContextControl.expectAndReturn(context.getBundle(), aBundle, MockControl.ONE_OR_MORE); >+ >+ // listen for bundle events >+ context.addBundleListener(null); >+ bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >+ bundleContextControl.setVoidCallable(2); >+ >+ bundleContextControl.expectAndReturn(context.registerService(new String[0], null, new Properties()), >+ new MockServiceRegistration(), MockControl.ONE_OR_MORE); >+ bundleContextControl.setMatcher(MockControl.ALWAYS_MATCHER); >+ >+ bundleContextControl.replay(); >+ >+ this.listener.start(context); >+ bundleContextControl.verify(); >+ } >+ >+ public void tstTaskExecutor() throws Exception { >+ Dictionary headers = new Hashtable(); >+ headers.put(Constants.BUNDLE_NAME, "Extender mock bundle"); >+ final EntryLookupControllingMockBundle aBundle = new EntryLookupControllingMockBundle(headers); >+ aBundle.setEntryReturnOnNextCallToGetEntry(new ClassPathResource("META-INF/spring/moved-extender.xml").getURL()); >+ >+ MockBundleContext ctx = new MockBundleContext() { >+ >+ public Bundle getBundle() { >+ return aBundle; >+ } >+ }; >+ >+ this.listener.start(ctx); >+ >+ Dictionary hdrs = new Hashtable(); >+ hdrs.put(ConfigUtils.SPRING_CONTEXT_HEADER, "bla bla"); >+ MockBundle anotherBundle = new MockBundle(hdrs); >+ anotherBundle.setBundleId(1); >+ >+ BundleEvent event = new BundleEvent(BundleEvent.STARTED, anotherBundle); >+ >+ BundleListener listener = (BundleListener) ctx.getBundleListeners().iterator().next(); >+ >+ TestTaskExecutor.called = false; >+ >+ listener.bundleChanged(event); >+ assertTrue("task executor should have been called if configured properly", TestTaskExecutor.called); >+ } >+ >+} >diff --git a/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationCustomSettingsTest.java b/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationCustomSettingsTest.java >index 66a0ae2..95312d4 100644 >--- a/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationCustomSettingsTest.java >+++ b/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationCustomSettingsTest.java >@@ -14,23 +14,20 @@ > > package org.eclipse.gemini.blueprint.extender.internal.support; > >-import java.net.URL; >-import java.util.Enumeration; >-import java.util.List; >- > import junit.framework.TestCase; >- >-import org.apache.commons.logging.LogFactory; >-import org.osgi.framework.Bundle; >-import org.osgi.framework.BundleContext; >-import org.springframework.core.task.SimpleAsyncTaskExecutor; >-import org.springframework.core.task.TaskExecutor; > import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticasterAdapter; > import org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.MandatoryImporterDependencyFactory; >-import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; > import org.eclipse.gemini.blueprint.mock.ArrayEnumerator; > import org.eclipse.gemini.blueprint.mock.MockBundle; > import org.eclipse.gemini.blueprint.mock.MockBundleContext; >+import org.osgi.framework.Bundle; >+import org.osgi.framework.BundleContext; >+import org.springframework.core.task.SimpleAsyncTaskExecutor; >+import org.springframework.core.task.TaskExecutor; >+ >+import java.net.URL; >+import java.util.Enumeration; >+import java.util.List; > > /** > * @author Costin Leau >@@ -51,11 +48,12 @@ public class ExtenderConfigurationCustomSettingsTest extends TestCase { > }; > > bundleContext = new MockBundleContext(bundle); >- config = new ExtenderConfiguration(bundleContext, LogFactory.getLog(ExtenderConfiguration.class)); >+ config = new ExtenderConfiguration(); >+ config.start(this.bundleContext); > } > > protected void tearDown() throws Exception { >- config.destroy(); >+ config.stop(this.bundleContext); > config = null; > } > >diff --git a/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationDefaultSettingsTest.java b/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationDefaultSettingsTest.java >index 421a413..1d4720c 100644 >--- a/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationDefaultSettingsTest.java >+++ b/extender/src/test/java/org/eclipse/gemini/blueprint/extender/internal/support/ExtenderConfigurationDefaultSettingsTest.java >@@ -14,21 +14,17 @@ > > package org.eclipse.gemini.blueprint.extender.internal.support; > >-import java.util.List; >- > import junit.framework.TestCase; >- >-import org.apache.commons.logging.LogFactory; >-import org.osgi.framework.BundleContext; >-import org.springframework.core.task.SimpleAsyncTaskExecutor; >-import org.springframework.core.task.TaskExecutor; > import org.eclipse.gemini.blueprint.context.event.OsgiBundleApplicationContextEventMulticasterAdapter; > import org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.MandatoryImporterDependencyFactory; >-import org.eclipse.gemini.blueprint.extender.internal.support.ExtenderConfiguration; >-import org.eclipse.gemini.blueprint.extender.support.DefaultOsgiApplicationContextCreator; > import org.eclipse.gemini.blueprint.mock.MockBundleContext; >+import org.osgi.framework.BundleContext; >+import org.springframework.core.task.SimpleAsyncTaskExecutor; >+import org.springframework.core.task.TaskExecutor; > import org.springframework.scheduling.timer.TimerTaskExecutor; > >+import java.util.List; >+ > /** > * @author Costin Leau > */ >@@ -39,11 +35,12 @@ public class ExtenderConfigurationDefaultSettingsTest extends TestCase { > > protected void setUp() throws Exception { > bundleContext = new MockBundleContext(); >- config = new ExtenderConfiguration(bundleContext, LogFactory.getLog(ExtenderConfiguration.class)); >+ config = new ExtenderConfiguration(); >+ this.config.start(this.bundleContext); > } > > protected void tearDown() throws Exception { >- config.destroy(); >+ config.start(this.bundleContext); > config = null; > } > >@@ -61,7 +58,7 @@ public class ExtenderConfigurationDefaultSettingsTest extends TestCase { > } > > public void testApplicationContextCreator() throws Exception { >- assertTrue(config.getContextCreator() instanceof DefaultOsgiApplicationContextCreator); >+ assertNull(config.getContextCreator()); > } > > public void testShutdownWaitTime() throws Exception { >-- >1.8.0.msysgit.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 356683
:
202722
|
202769
|
223184
|
223222
|
223234
|
223379