Move Eclipse 3 components to legacy.
[lgpl/argeo-commons.git] / legacy / org.argeo.cms.ui.workbench / src / org / argeo / eclipse / spring / ApplicationContextTracker.java
diff --git a/legacy/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/ApplicationContextTracker.java b/legacy/org.argeo.cms.ui.workbench/src/org/argeo/eclipse/spring/ApplicationContextTracker.java
new file mode 100644 (file)
index 0000000..1d3df43
--- /dev/null
@@ -0,0 +1,152 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.eclipse.spring;\r
+\r
+import static java.text.MessageFormat.format;\r
+\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.osgi.framework.Bundle;\r
+import org.osgi.framework.BundleContext;\r
+import org.osgi.framework.BundleException;\r
+import org.osgi.framework.FrameworkUtil;\r
+import org.osgi.framework.InvalidSyntaxException;\r
+import org.osgi.util.tracker.ServiceTracker;\r
+import org.springframework.context.ApplicationContext;\r
+\r
+/**\r
+ * Tracks Spring application context published as services.\r
+ * \r
+ * @author Heiko Seeberger\r
+ * @author Mathieu Baudier\r
+ */\r
+class ApplicationContextTracker {\r
+       private final static Log log = LogFactory\r
+                       .getLog(ApplicationContextTracker.class);\r
+\r
+       private static final String FILTER = "(&(objectClass=org.springframework.context.ApplicationContext)" //$NON-NLS-1$\r
+                       + "(org.springframework.context.service.name={0}))"; //$NON-NLS-1$\r
+\r
+       public final static String APPLICATION_CONTEXT_TRACKER_TIMEOUT = "org.argeo.eclipse.spring.applicationContextTrackerTimeout";\r
+\r
+       private static Long defaultTimeout = Long.parseLong(System.getProperty(\r
+                       APPLICATION_CONTEXT_TRACKER_TIMEOUT, "30000"));\r
+\r
+       @SuppressWarnings("rawtypes")\r
+       private ServiceTracker applicationContextServiceTracker;\r
+\r
+       /**\r
+        * @param contributorBundle\r
+        *            OSGi bundle for which the Spring application context is to be\r
+        *            tracked. Must not be null!\r
+        * @param factoryBundleContext\r
+        *            BundleContext object which can be used to track services\r
+        * @throws IllegalArgumentException\r
+        *             if the given bundle is null.\r
+        */\r
+       @SuppressWarnings({ "unchecked", "rawtypes" })\r
+       public ApplicationContextTracker(final Bundle contributorBundle,\r
+                       final BundleContext factoryBundleContext) {\r
+               final String filter = format(FILTER,\r
+                               contributorBundle.getSymbolicName());\r
+               try {\r
+                       applicationContextServiceTracker = new ServiceTracker(\r
+                                       factoryBundleContext, FrameworkUtil.createFilter(filter),\r
+                                       null);\r
+                       // applicationContextServiceTracker.open();\r
+               } catch (final InvalidSyntaxException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public void open() {\r
+               if (applicationContextServiceTracker != null) {\r
+                       applicationContextServiceTracker.open();\r
+               }\r
+       }\r
+\r
+       public void close() {\r
+               if (applicationContextServiceTracker != null) {\r
+                       applicationContextServiceTracker.close();\r
+               }\r
+       }\r
+\r
+       public ApplicationContext getApplicationContext() {\r
+               ApplicationContext applicationContext = null;\r
+               if (applicationContextServiceTracker != null) {\r
+                       try {\r
+                               applicationContext = (ApplicationContext) applicationContextServiceTracker\r
+                                               .waitForService(defaultTimeout);\r
+                       } catch (InterruptedException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+               return applicationContext;\r
+       }\r
+\r
+       @Override\r
+       protected void finalize() throws Throwable {\r
+               close();\r
+               super.finalize();\r
+       }\r
+\r
+       static ApplicationContext getApplicationContext(String bundleSymbolicName) {\r
+               Bundle contributorBundle = Platform.getBundle(bundleSymbolicName);\r
+               return getApplicationContext(contributorBundle);\r
+       }\r
+\r
+       static ApplicationContext getApplicationContext(\r
+                       final Bundle contributorBundle) {\r
+               if (log.isTraceEnabled())\r
+                       log.trace("Get application context for bundle " + contributorBundle);\r
+\r
+               // Start if not yet started (also if in STARTING state, may be lazy)\r
+               if (contributorBundle.getState() != Bundle.ACTIVE) {\r
+                       if (log.isTraceEnabled())\r
+                               log.trace("Starting bundle: "\r
+                                               + contributorBundle.getSymbolicName());\r
+                       // Thread startBundle = new Thread("Start bundle "\r
+                       // + contributorBundle.getSymbolicName()) {\r
+                       // public void run() {\r
+                       try {\r
+                               contributorBundle.start();\r
+                       } catch (BundleException e) {\r
+                               log.error("Cannot start bundle " + contributorBundle, e);\r
+                       }\r
+                       // }\r
+                       // };\r
+                       // startBundle.start();\r
+                       // try {\r
+                       // startBundle.join(10 * 1000l);\r
+                       // } catch (InterruptedException e) {\r
+                       // // silent\r
+                       // }\r
+               }\r
+\r
+               final ApplicationContextTracker applicationContextTracker = new ApplicationContextTracker(\r
+                               contributorBundle, contributorBundle.getBundleContext());\r
+               ApplicationContext applicationContext = null;\r
+               try {\r
+                       applicationContextTracker.open();\r
+                       applicationContext = applicationContextTracker\r
+                                       .getApplicationContext();\r
+               } finally {\r
+                       applicationContextTracker.close();\r
+               }\r
+               return applicationContext;\r
+       }\r
+}\r