/src/server/servicefacade/src/keymind/keywatch/bundles/servicefacade/Activator.java

http://keywatch.googlecode.com/ · Java · 261 lines · 148 code · 35 blank · 78 comment · 8 complexity · 86047bb63f9fc235c5ae9f50e2f31e5e MD5 · raw file

  1. /**
  2. * -----------------------------------------------------------------------------------------------
  3. * File: Activator.java
  4. *
  5. * Copyright (c) 2007 by Keymind Computing as.
  6. * All rights reserved.
  7. *
  8. * This file is subject to the terms and conditions of the Apache Licence 2.0.
  9. * See the file LICENCE in the main directory of the Keywatch distribution for more details.
  10. *
  11. * Revision History (use svn log or TortoiseSVN):
  12. * $URL: http://keywatch.googlecode.com/svn/trunk/src/server/servicefacade/src/keymind/keywatch/bundles/servicefacade/Activator.java $
  13. * $Date: 2009-04-16 15:23:28 +0200 (Thu, 16 Apr 2009) $, $Rev: 1208 $
  14. * -----------------------------------------------------------------------------------------------
  15. */
  16. package keymind.keywatch.bundles.servicefacade;
  17. import org.osgi.framework.*;
  18. import org.mortbay.jetty.Server;
  19. import org.mortbay.jetty.servlet.WebApplicationContext;
  20. import org.mortbay.http.SocketListener;
  21. import keymind.keywatch.common.IOSGIServiceAccess;
  22. import keymind.keywatch.common.Log;
  23. import java.io.InputStream;
  24. import java.io.FileOutputStream;
  25. import java.io.File;
  26. /**
  27. * Bundle for OSGI. Uses Jetty as web container and offers an interface for accessing
  28. * bundle services.
  29. */
  30. public class Activator implements BundleActivator, IOSGIServiceAccess, FrameworkListener, BundleListener
  31. {
  32. public static BundleContext bundleCtx = null;
  33. private Server servletserver = null;
  34. private SocketListener listener = null;
  35. private WebApplicationContext srvctx = null;
  36. private static IOSGIServiceAccess serviceAccess;
  37. static final String HTTP_PORT = "http.port";
  38. static final String HTTP_DEFAULT_PORT = "8082";
  39. static final String SERVERBUNDLE_STOPPING = "Serverbundle stopping...";
  40. static final String SERVERBUNDLE_STOPPED = "Serverbundle stopped";
  41. static final String RUNTIME_BUILDER = "RuntimeBuilder";
  42. static final String WAR_UPDATING = "Service facade is updating WAR file...";
  43. static final String WAR_UPDATED = "WAR file successfully updated";
  44. static final String MISSING_FRAMEWORK = "Service facade: framework.war not found. Assuming it's in ./webapps/framework.war";
  45. /**
  46. * Called when the bundle starts
  47. *
  48. * @param bundleContext Bundle context
  49. * @throws Exception Exception
  50. */
  51. public void start(BundleContext bundleContext) throws Exception
  52. {
  53. Log.initialize(bundleContext);
  54. Activator.bundleCtx = bundleContext;
  55. serviceAccess = this;
  56. bundleCtx.addFrameworkListener(this);
  57. bundleCtx.addBundleListener(this);
  58. // Set classloader such that Jetty (and the servlet) can look up external services
  59. // (domainmodel etc from the server bundle)
  60. ClassLoader bundleLoader = this.getClass().getClassLoader();
  61. ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
  62. Thread.currentThread().setContextClassLoader(bundleLoader);
  63. // Initialize the servlet-container
  64. servletserver = new Server();
  65. listener = new SocketListener();
  66. listener.setPort(Integer.parseInt(System.getProperty(HTTP_PORT, HTTP_DEFAULT_PORT)));
  67. servletserver.addListener(listener);
  68. // Add context
  69. srvctx = new WebApplicationContext();
  70. // Add the web application, load the servlet
  71. srvctx.setContextPath("");
  72. srvctx.setClassLoaderJava2Compliant(true);
  73. InputStream is = srvctx.getClass().getResourceAsStream("/framework.war");
  74. if (is == null)
  75. {
  76. System.out.println(MISSING_FRAMEWORK);
  77. }
  78. else
  79. {
  80. File dir = new File("webapps");
  81. dir.mkdirs();
  82. File war = new File("webapps/framework.war");
  83. war.delete();
  84. FileOutputStream fos = new FileOutputStream("webapps/framework.war");
  85. int b = is.read();
  86. while (b != -1)
  87. {
  88. fos.write(b);
  89. b = is.read();
  90. }
  91. fos.close();
  92. }
  93. // This is required for hot redeployment
  94. try
  95. {
  96. srvctx.setExtractWAR(true);
  97. srvctx.setWAR("./webapps/framework.war");
  98. servletserver.addContext(srvctx);
  99. servletserver.start();
  100. //Thread.currentThread().setContextClassLoader(oldLoader);
  101. }
  102. catch (Exception ex)
  103. {
  104. Log.error(ex.toString());
  105. }
  106. }
  107. /**
  108. * Called when the bundle stops
  109. *
  110. * @param bundleContext Bundle context
  111. * @throws Exception Exception
  112. */
  113. public void stop(BundleContext bundleContext) throws Exception
  114. {
  115. bundleLog(SERVERBUNDLE_STOPPING);
  116. // Stop jetty gracefully
  117. servletserver.stop();
  118. servletserver.destroy();
  119. srvctx.stop();
  120. srvctx.destroy();
  121. bundleLog(SERVERBUNDLE_STOPPED);
  122. }
  123. /**
  124. * Implements the ServiceAccessFactory - returns an implementation of ServiceAccess-interface
  125. * Could return a separate bundle handling the interface, but for now, this is ok
  126. *
  127. * @return an implementation of ServiceAccess-interface
  128. */
  129. public static IOSGIServiceAccess getServiceAccess()
  130. {
  131. return serviceAccess;
  132. }
  133. /**
  134. * Get static bundle context
  135. *
  136. * @return the bundle context
  137. */
  138. public static synchronized BundleContext getBundleContext()
  139. {
  140. return bundleCtx;
  141. }
  142. /**
  143. * @see IOSGIServiceAccess#bundleLog(String)
  144. */
  145. public void bundleLog(String logString)
  146. {
  147. Log.info(logString);
  148. }
  149. /**
  150. * Used in development to run differnt tests, from local callback to
  151. * end to end test.
  152. * Input desides about the test, result indicates result
  153. *
  154. * @param type Type of test to run
  155. * @return resultstatus
  156. */
  157. public int test(int type)
  158. {
  159. return 0;
  160. }
  161. /**
  162. * Implements the OSGiServiceAccess interface to give the "client" access to services
  163. * even if it is not a bundle
  164. *
  165. * @param serviceName Service name
  166. * @return the service or null if not found
  167. */
  168. public Object getService(String serviceName)
  169. {
  170. synchronized (this)
  171. {
  172. try
  173. {
  174. return bundleCtx.getService(bundleCtx.getServiceReference(serviceName));
  175. }
  176. catch (Exception ignored)
  177. {
  178. bundleLog("Serviceaccess could not look up " + serviceName);
  179. return null;
  180. }
  181. }
  182. }
  183. /**
  184. * Reload WAR file when refreshing packages
  185. *
  186. * @param frameworkEvent Framework event
  187. */
  188. public void frameworkEvent(FrameworkEvent frameworkEvent)
  189. {
  190. try
  191. {
  192. if (frameworkEvent.getType() == FrameworkEvent.PACKAGES_REFRESHED)
  193. {
  194. srvctx.stop();
  195. srvctx.start();
  196. }
  197. }
  198. catch (Exception e)
  199. {
  200. e.printStackTrace();
  201. }
  202. }
  203. /**
  204. * Reload WAR file when RuntimeBuilder stops, since this indicates a client rebuild
  205. *
  206. * @param bundleEvent Bundle event
  207. */
  208. public void bundleChanged(BundleEvent bundleEvent)
  209. {
  210. if (bundleEvent.getType() == BundleEvent.STOPPED &&
  211. bundleEvent.getBundle().getSymbolicName().equals(RUNTIME_BUILDER))
  212. {
  213. try
  214. {
  215. Log.info(WAR_UPDATING);
  216. stop(bundleCtx);
  217. start(bundleCtx);
  218. Log.info(WAR_UPDATED);
  219. }
  220. catch (Exception e)
  221. {
  222. e.printStackTrace();
  223. }
  224. }
  225. }
  226. }