Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlyn Normington2010-12-31 08:07:00 -0500
committerGlyn Normington2010-12-31 08:07:00 -0500
commit277b221152da02d1608e240e7fa856a7e18cd5b9 (patch)
treedebef08452373f096bd1232f682f63e47a614a12 /org.eclipse.virgo.kernel.userregionfactory
parent3314e251d26bfcf18bc4b81c247472f93a876a77 (diff)
downloadorg.eclipse.virgo.kernel-277b221152da02d1608e240e7fa856a7e18cd5b9.tar.gz
org.eclipse.virgo.kernel-277b221152da02d1608e240e7fa856a7e18cd5b9.tar.xz
org.eclipse.virgo.kernel-277b221152da02d1608e240e7fa856a7e18cd5b9.zip
bug 330776: move user region creation into user region factory bundle
Diffstat (limited to 'org.eclipse.virgo.kernel.userregionfactory')
-rw-r--r--org.eclipse.virgo.kernel.userregionfactory/.classpath10
-rw-r--r--org.eclipse.virgo.kernel.userregionfactory/ivy.xml12
-rw-r--r--org.eclipse.virgo.kernel.userregionfactory/src/main/java/org/eclipse/virgo/kernel/userregionfactory/Activator.java226
-rw-r--r--org.eclipse.virgo.kernel.userregionfactory/template.mf8
4 files changed, 247 insertions, 9 deletions
diff --git a/org.eclipse.virgo.kernel.userregionfactory/.classpath b/org.eclipse.virgo.kernel.userregionfactory/.classpath
index 82516e30..53255481 100644
--- a/org.eclipse.virgo.kernel.userregionfactory/.classpath
+++ b/org.eclipse.virgo.kernel.userregionfactory/.classpath
@@ -8,5 +8,15 @@
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/KERNEL_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.7.0.v20101022/org.eclipse.osgi-3.7.0.v20101022.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.7.0.v20101022/org.eclipse.osgi-sources-3.7.0.v20101022.jar"/>
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar" sourcepath="/KERNEL_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.core"/>
+ <classpathentry kind="src" path="/org.eclipse.virgo.kernel.osgi"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.apache.felix/org.apache.felix.eventadmin/1.0.0/org.apache.felix.eventadmin-1.0.0.jar" sourcepath="/KERNEL_IVY_CACHE/org.apache.felix/org.apache.felix.eventadmin/1.0.0/org.apache.felix.eventadmin-sources-1.0.0.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/2.2.0.D-20101207150849/org.eclipse.virgo.medic-2.2.0.D-20101207150849.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/1.0.0.CI-B20/org.eclipse.virgo.medic-sources-1.0.0.CI-B20.jar">
+ <attributes>
+ <attribute name="org.eclipse.ajdt.aspectpath" value="org.eclipse.ajdt.aspectpath"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.osgi/org.eclipse.virgo.osgi.launcher/2.2.0.D-20101207145732/org.eclipse.virgo.osgi.launcher-2.2.0.D-20101207145732.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.osgi/org.eclipse.virgo.osgi.launcher/2.2.0.D-20101207145732/org.eclipse.virgo.osgi.launcher-sources-2.2.0.D-20101207145732.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.2.0.D-20101207150035/org.eclipse.virgo.util.osgi-2.2.0.D-20101207150035.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.2.0.D-20101207150035/org.eclipse.virgo.util.osgi-sources-2.2.0.D-20101207150035.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
diff --git a/org.eclipse.virgo.kernel.userregionfactory/ivy.xml b/org.eclipse.virgo.kernel.userregionfactory/ivy.xml
index a3851a14..7939bedc 100644
--- a/org.eclipse.virgo.kernel.userregionfactory/ivy.xml
+++ b/org.eclipse.virgo.kernel.userregionfactory/ivy.xml
@@ -14,14 +14,20 @@
</publications>
<dependencies>
- <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/>
<dependency org="org.eclipse.osgi" name='org.eclipse.osgi' rev='${org.eclipse.osgi}' conf='compile->compile' />
- <!-- TEST -->
+ <dependency org='org.eclipse.virgo.medic' name='org.eclipse.virgo.medic' rev='${org.eclipse.virgo.medic}' conf='aspects, compile->runtime'/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.osgi" rev="latest.integration" conf="compile->compile"/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.core" rev="latest.integration" conf="compile->compile"/>
+ <dependency org="org.eclipse.virgo.osgi" name="org.eclipse.virgo.osgi.launcher" rev="${org.eclipse.virgo.osgi}" conf="compile->compile"/>
+ <dependency org='org.eclipse.virgo.util' name='org.eclipse.virgo.util.osgi' rev='${org.eclipse.virgo.util}' conf='compile->compile' />
+ <!-- TEST -->
+ <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/>
<dependency org="org.slf4j" name="com.springsource.slf4j.nop" rev="${org.slf4j}" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="${org.easymock}" conf="test->runtime"/>
<dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic.test" rev="${org.eclipse.virgo.medic}" conf="test->runtime"/>
-
+
+
<override org="org.slf4j" rev="${org.slf4j}"/>
</dependencies>
diff --git a/org.eclipse.virgo.kernel.userregionfactory/src/main/java/org/eclipse/virgo/kernel/userregionfactory/Activator.java b/org.eclipse.virgo.kernel.userregionfactory/src/main/java/org/eclipse/virgo/kernel/userregionfactory/Activator.java
index 259f136b..89ab878b 100644
--- a/org.eclipse.virgo.kernel.userregionfactory/src/main/java/org/eclipse/virgo/kernel/userregionfactory/Activator.java
+++ b/org.eclipse.virgo.kernel.userregionfactory/src/main/java/org/eclipse/virgo/kernel/userregionfactory/Activator.java
@@ -13,8 +13,40 @@
package org.eclipse.virgo.kernel.userregionfactory;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.virgo.kernel.core.Shutdown;
+import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkLogEvents;
+import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkUtils;
+import org.eclipse.virgo.kernel.osgi.framework.OsgiServiceHolder;
+import org.eclipse.virgo.kernel.osgi.region.ImmutableRegion;
+import org.eclipse.virgo.kernel.osgi.region.Region;
+import org.eclipse.virgo.kernel.osgi.region.RegionMembership;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.osgi.launcher.parser.ArgumentParser;
+import org.eclipse.virgo.osgi.launcher.parser.BundleEntry;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
/**
*{@link Activator} initialises the user region factory bundle.
@@ -22,16 +54,180 @@ import org.osgi.framework.BundleContext;
*
* <strong>Concurrent Semantics</strong><br />
*
- * Thread safe.
+ * Not thread safe.
*
*/
public final class Activator implements BundleActivator {
+
+ private static final long MAX_SECONDS_WAIT_FOR_SERVICE = 30;
+
+ private static final long MAX_MILLIS_WAIT_FOR_SERVICE = TimeUnit.SECONDS.toMillis(MAX_SECONDS_WAIT_FOR_SERVICE);
+
+ private static final String USER_REGION_CONFIGURATION_PID = "org.eclipse.virgo.kernel.userregion";
+
+ private static final String USER_REGION_BASE_BUNDLES_PROPERTY = "baseBundles";
+
+ private static final String USER_REGION_PACKAGE_IMPORTS_PROPERTY = "packageImports";
+
+ private static final String USER_REGION_SERVICE_IMPORTS_PROPERTY = "serviceImports";
+
+ private static final String USER_REGION_SERVICE_EXPORTS_PROPERTY = "serviceExports";
+
+ private static final String USER_REGION_BUNDLE_CONTEXT_SERVICE_PROPERTY = "org.eclipse.virgo.kernel.regionContext";
+
+ private static final String REGION_USER = "org.eclipse.virgo.region.user";
+
+ private static final String EVENT_REGION_STARTING = "org/eclipse/virgo/kernel/region/STARTING";
+
+ private static final String EVENT_PROPERTY_REGION_BUNDLECONTEXT = "region.bundleContext";
+
+ private static final String USER_REGION_LOCATION_TAG = "userregion@";
+
+ private static final String REFERENCE_SCHEME = "reference:";
+
+ private static final String FILE_SCHEME = "file:";
+
+ private EventAdmin eventAdmin;
+
+ private String regionBundles;
+
+ private String regionImports;
+
+ private String regionServiceImports;
+
+ private String regionServiceExports;
+
+ private BundleContext bundleContext;
+
+ private final ArgumentParser parser = new ArgumentParser();
+
+ private final ServiceRegistrationTracker tracker = new ServiceRegistrationTracker();
/**
* {@inheritDoc}
*/
@Override
- public void start(BundleContext context) throws Exception {
+ public void start(BundleContext bundleContext) throws Exception {
+ this.bundleContext = bundleContext;
+ RegionMembership regionMembership = getPotentiallyDelayedService(bundleContext, RegionMembership.class);
+ this.eventAdmin = getPotentiallyDelayedService(bundleContext, EventAdmin.class);
+ ConfigurationAdmin configAdmin= getPotentiallyDelayedService(bundleContext, ConfigurationAdmin.class);
+ EventLogger eventLogger = getPotentiallyDelayedService(bundleContext, EventLogger.class);
+ Shutdown shutdown = getPotentiallyDelayedService(bundleContext, Shutdown.class);
+ getRegionConfiguration(configAdmin, eventLogger, shutdown);
+
+ createUserRegion(bundleContext, regionMembership);
+ }
+
+ private void getRegionConfiguration(ConfigurationAdmin configAdmin, EventLogger eventLogger, Shutdown shutdown) {
+ try {
+ Configuration config = configAdmin.getConfiguration(USER_REGION_CONFIGURATION_PID, null);
+
+ @SuppressWarnings("unchecked")
+ Dictionary<String, String> properties = config.getProperties();
+
+ if (properties != null) {
+ this.regionBundles = properties.get(USER_REGION_BASE_BUNDLES_PROPERTY);
+ this.regionImports = properties.get(USER_REGION_PACKAGE_IMPORTS_PROPERTY);
+ this.regionServiceImports = properties.get(USER_REGION_SERVICE_IMPORTS_PROPERTY);
+ this.regionServiceExports = properties.get(USER_REGION_SERVICE_EXPORTS_PROPERTY);
+ } else {
+ eventLogger.log(OsgiFrameworkLogEvents.USER_REGION_CONFIGURATION_UNAVAILABLE);
+ shutdown.immediateShutdown();
+ }
+ } catch (Exception e) {
+ eventLogger.log(OsgiFrameworkLogEvents.USER_REGION_CONFIGURATION_UNAVAILABLE, e);
+ shutdown.immediateShutdown();
+ }
+ }
+
+
+ private void createUserRegion(BundleContext userRegionBundleContext, RegionMembership regionMembership) throws BundleException {
+
+ ImmutableRegion userRegion = new ImmutableRegion(REGION_USER, userRegionBundleContext);
+ regionMembership.setUserRegion(userRegion);
+ notifyUserRegionStarting(userRegionBundleContext);
+
+ initialiseUserRegionBundles();
+
+ registerRegionService(userRegion);
+ publishUserRegionBundleContext(userRegionBundleContext);
+ }
+
+ private void notifyUserRegionStarting(BundleContext userRegionBundleContext) {
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put(EVENT_PROPERTY_REGION_BUNDLECONTEXT, userRegionBundleContext);
+ this.eventAdmin.sendEvent(new Event(EVENT_REGION_STARTING, properties));
+ }
+
+ private void initialiseUserRegionBundles() throws BundleException {
+
+ String userRegionBundlesProperty = this.regionBundles != null ? this.regionBundles
+ : this.bundleContext.getProperty(USER_REGION_BASE_BUNDLES_PROPERTY);
+
+ if (userRegionBundlesProperty != null) {
+ List<Bundle> bundlesToStart = new ArrayList<Bundle>();
+
+ for (BundleEntry entry : this.parser.parseBundleEntries(userRegionBundlesProperty)) {
+ URI uri = entry.getURI();
+ Bundle bundle = this.bundleContext.installBundle(USER_REGION_LOCATION_TAG + uri.toString(), openBundleStream(uri));
+
+ if (entry.isAutoStart()) {
+ bundlesToStart.add(bundle);
+ }
+ }
+
+ for (Bundle bundle : bundlesToStart) {
+ try {
+ bundle.start();
+ } catch (BundleException e) {
+ throw new BundleException("Failed to start bundle " + bundle.getSymbolicName() + " " + bundle.getVersion(), e);
+ }
+ }
+ }
+ }
+
+ private InputStream openBundleStream(URI uri) throws BundleException {
+ String absoluteBundleUriString = getAbsoluteUriString(uri);
+
+ try {
+ // Use the reference: scheme to obtain an InputStream for either a file or a directory.
+ return new URL(REFERENCE_SCHEME + absoluteBundleUriString).openStream();
+
+ } catch (MalformedURLException e) {
+ throw new BundleException(USER_REGION_BASE_BUNDLES_PROPERTY + " property resulted in an invalid bundle URI '" + absoluteBundleUriString
+ + "'", e);
+ } catch (IOException e) {
+ throw new BundleException(USER_REGION_BASE_BUNDLES_PROPERTY + " property referred to an invalid bundle at URI '"
+ + absoluteBundleUriString + "'", e);
+ }
+ }
+
+ private String getAbsoluteUriString(URI uri) throws BundleException {
+ String bundleUriString = uri.toString();
+
+ if (!bundleUriString.startsWith(FILE_SCHEME)) {
+ throw new BundleException(USER_REGION_BASE_BUNDLES_PROPERTY + " property contained an entry '" + bundleUriString
+ + "' which did not start with '" + FILE_SCHEME + "'");
+ }
+
+ String filePath = bundleUriString.substring(FILE_SCHEME.length());
+
+ return FILE_SCHEME + new File(filePath).getAbsolutePath();
+ }
+
+
+
+ private void registerRegionService(Region region) {
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("org.eclipse.virgo.kernel.region.name", region.getName());
+ this.tracker.track(this.bundleContext.registerService(Region.class, region, props));
+ }
+
+ private void publishUserRegionBundleContext(BundleContext userRegionBundleContext) {
+ Dictionary<String, String> properties = new Hashtable<String, String>();
+ properties.put(USER_REGION_BUNDLE_CONTEXT_SERVICE_PROPERTY, "true");
+ this.bundleContext.registerService(BundleContext.class, userRegionBundleContext, properties);
}
/**
@@ -41,4 +237,30 @@ public final class Activator implements BundleActivator {
public void stop(BundleContext context) throws Exception {
}
+ private static <T> T getPotentiallyDelayedService(BundleContext context, Class<T> serviceClass) throws TimeoutException, InterruptedException {
+ T service = null;
+ OsgiServiceHolder<T> serviceHolder;
+ long millisWaited = 0;
+ while (service == null && millisWaited <= MAX_MILLIS_WAIT_FOR_SERVICE) {
+ try {
+ serviceHolder = OsgiFrameworkUtils.getService(context, serviceClass);
+ if (serviceHolder != null) {
+ service = serviceHolder.getService();
+ } else {
+ millisWaited += sleepABitMore();
+ }
+ } catch (IllegalStateException e) {
+ }
+ }
+ if (service == null) {
+ throw new TimeoutException(serviceClass.getName());
+ }
+ return service;
+ }
+
+ private static long sleepABitMore() throws InterruptedException {
+ long before = System.currentTimeMillis();
+ Thread.sleep(100);
+ return (System.currentTimeMillis() - before);
+ }
}
diff --git a/org.eclipse.virgo.kernel.userregionfactory/template.mf b/org.eclipse.virgo.kernel.userregionfactory/template.mf
index b0b31458..abd5d6f6 100644
--- a/org.eclipse.virgo.kernel.userregionfactory/template.mf
+++ b/org.eclipse.virgo.kernel.userregionfactory/template.mf
@@ -9,9 +9,9 @@ Import-Template:
org.eclipse.osgi.framework.*;version="0",
org.eclipse.osgi.service.resolver.*;version="0",
org.osgi.framework.*;version="0",
- org.osgi.service.*;version="0"
+ org.osgi.service.*;version="0",
+ org.eclipse.virgo.medic.*;version="${org.eclipse.virgo.medic:[=.=.=, =.+1)}"
Bundle-Activator: org.eclipse.virgo.kernel.userregionfactory.Activator
-Excluded-Imports: org.easymock
+Excluded-Imports: org.easymock,
+ org.eclipse.virgo.osgi.launcher.*
Excluded-Exports: *
-
-

Back to the top