View Javadoc

1   // ========================================================================
2   // Copyright (c) 2009 Intalio, Inc.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // Contributors:
13  //    Hugues Malphettes - initial API and implementation
14  // ========================================================================
15  package org.eclipse.jetty.osgi.boot;
16  
17  import java.util.Dictionary;
18  import java.util.Hashtable;
19  import java.util.Properties;
20  
21  import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
22  import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker;
23  import org.eclipse.jetty.osgi.boot.internal.webapp.IWebBundleDeployerHelper;
24  import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerServiceTracker;
25  import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer;
26  import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
27  import org.eclipse.jetty.server.Server;
28  import org.eclipse.jetty.server.handler.ContextHandler;
29  import org.eclipse.jetty.webapp.WebAppContext;
30  import org.osgi.framework.Bundle;
31  import org.osgi.framework.BundleActivator;
32  import org.osgi.framework.BundleContext;
33  import org.osgi.framework.ServiceRegistration;
34  import org.osgi.util.tracker.BundleTracker;
35  
36  /**
37   * Experiment: bootstrap jetty's complete distrib from an OSGi bundle. Progress:
38   * <ol>
39   * <li>basic servlet [ok]</li>
40   * <li>basic jetty.xml [ok]</li>
41   * <li>basic jetty.xml and jetty-plus.xml [ok]</li>
42   * <li>basic jsp [ok with modifications]
43   * <ul>
44   * <li>Needed to modify the headers of jdt.core-3.1.1 so that its dependency on
45   * eclipse.runtime, eclipse.resources and eclipse.text are optional. Also we
46   * should depend on the latest jdt.core from eclipse-3.5 not from eclipse-3.1.1
47   * although that will require actual changes to jasper as some internal APIs of
48   * jdt.core have changed.</li>
49   * <li>Modifications to org.mortbay.jetty.jsp-2.1-glassfish: made all imports to
50   * ant, xalan and sun packages optional.</li>
51   * </ul>
52   * </li>
53   * <li>jsp with tag-libs [ok]</li>
54   * <li>test-jndi with atomikos and derby inside ${jetty.home}/lib/ext [ok]</li>
55   * </ul>
56   */
57  public class JettyBootstrapActivator implements BundleActivator
58  {
59  
60      private static JettyBootstrapActivator INSTANCE = null;
61  
62      public static JettyBootstrapActivator getInstance()
63      {
64          return INSTANCE;
65      }
66  
67      private ServiceRegistration _registeredServer;
68      private Server _server;
69      private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
70      private PackageAdminServiceTracker _packageAdminServiceTracker;
71      private BundleTracker _webBundleTracker;
72      
73  //    private ServiceRegistration _jettyServerFactoryService;
74      private JettyServerServiceTracker _jettyServerServiceTracker;
75      
76  
77      /**
78       * Setup a new jetty Server, registers it as a service. Setup the Service
79       * tracker for the jetty ContextHandlers that are in charge of deploying the
80       * webapps. Setup the BundleListener that supports the extender pattern for
81       * the jetty ContextHandler.
82       * 
83       * @param context
84       */
85      public void start(BundleContext context) throws Exception
86      {
87          INSTANCE = this;
88  
89          // track other bundles and fragments attached to this bundle that we
90          // should activate.
91          _packageAdminServiceTracker = new PackageAdminServiceTracker(context);
92  
93      	_jettyServerServiceTracker = new JettyServerServiceTracker();
94          context.addServiceListener(_jettyServerServiceTracker,"(objectclass=" + Server.class.getName() + ")");
95  
96          //Register the Jetty Server Factory as a ManagedServiceFactory:
97  //          Properties jettyServerMgdFactoryServiceProps = new Properties(); 
98  //          jettyServerMgdFactoryServiceProps.put("pid", OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID);
99  //          _jettyServerFactoryService = context.registerService(
100 //          		ManagedServiceFactory.class.getName(),  new JettyServersManagedFactory(),
101 //          		jettyServerMgdFactoryServiceProps);
102     
103         _jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(_jettyServerServiceTracker);
104 
105         // the tracker in charge of the actual deployment
106         // and that will configure and start the jetty server.
107         context.addServiceListener(_jettyContextHandlerTracker,"(objectclass=" + ContextHandler.class.getName() + ")");
108 
109         //see if we shoult start a default jetty instance right now.
110         DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context);
111         
112         // now ready to support the Extender pattern:        
113         _webBundleTracker = new BundleTracker(context,
114         		Bundle.ACTIVE | Bundle.STOPPING, new WebBundleTrackerCustomizer());
115         _webBundleTracker.open();
116         
117     }
118 
119     /*
120      * (non-Javadoc)
121      * 
122      * @see
123      * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
124      */
125     public void stop(BundleContext context) throws Exception
126     {
127         try
128         {
129         	
130         	if (_webBundleTracker != null)
131         	{
132         		_webBundleTracker.close();
133         		_webBundleTracker = null;
134         	}
135             if (_jettyContextHandlerTracker != null)
136             {
137                 _jettyContextHandlerTracker.stop();
138                 context.removeServiceListener(_jettyContextHandlerTracker);
139                 _jettyContextHandlerTracker = null;
140             }
141             if (_jettyServerServiceTracker != null)
142             {
143             	_jettyServerServiceTracker.stop();
144                 context.removeServiceListener(_jettyServerServiceTracker);
145                 _jettyServerServiceTracker = null;
146             }
147             if (_packageAdminServiceTracker != null)
148             {
149                 _packageAdminServiceTracker.stop();
150                 context.removeServiceListener(_packageAdminServiceTracker);
151                 _packageAdminServiceTracker = null;
152             }
153             if (_registeredServer != null)
154             {
155                 try
156                 {
157                     _registeredServer.unregister();
158                 }
159                 catch (IllegalArgumentException ill)
160                 {
161                     // already unregistered.
162                 }
163                 finally
164                 {
165                 	_registeredServer = null;
166                 }
167             }
168 //        	if (_jettyServerFactoryService != null)
169 //        	{
170 //                try
171 //                {
172 //                	_jettyServerFactoryService.unregister();
173 //                }
174 //                catch (IllegalArgumentException ill)
175 //                {
176 //                    // already unregistered.
177 //                }
178 //                finally
179 //                {
180 //                	_jettyServerFactoryService = null;
181 //                }
182 //        	}
183 
184         }
185         finally
186         {
187             if (_server != null)
188             {
189             	_server.stop();
190             }
191             INSTANCE = null;
192         }
193     }
194 
195     /**
196      * Helper method that creates a new org.jetty.webapp.WebAppContext and
197      * registers it as an OSGi service. The tracker
198      * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
199      * 
200      * @param contributor
201      *            The bundle
202      * @param webappFolderPath
203      *            The path to the root of the webapp. Must be a path relative to
204      *            bundle; either an absolute path.
205      * @param contextPath
206      *            The context path. Must start with "/"
207      * @throws Exception
208      */
209     public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath) throws Exception
210     {
211         WebAppContext contextHandler = new WebAppContext();
212         Properties dic = new Properties();
213         dic.put(OSGiWebappConstants.SERVICE_PROP_WAR,webappFolderPath);
214         dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH,contextPath);
215         contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
216     }
217 
218     /**
219      * Helper method that creates a new org.jetty.webapp.WebAppContext and
220      * registers it as an OSGi service. The tracker
221      * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
222      * 
223      * @param contributor
224      *            The bundle
225      * @param webappFolderPath
226      *            The path to the root of the webapp. Must be a path relative to
227      *            bundle; either an absolute path.
228      * @param contextPath
229      *            The context path. Must start with "/"
230      * @param dic
231      *        TODO: parameter description
232      * @throws Exception
233      */
234     public static void registerWebapplication(Bundle contributor, String webappFolderPath, String contextPath, Dictionary<String, String> dic) throws Exception
235     {
236         WebAppContext contextHandler = new WebAppContext();
237         dic.put(OSGiWebappConstants.SERVICE_PROP_WAR,webappFolderPath);
238         dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH,contextPath);
239         contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
240     }
241 
242     /**
243      * Helper method that creates a new skeleton of a ContextHandler and
244      * registers it as an OSGi service. The tracker
245      * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
246      * 
247      * @param contributor
248      *            The bundle that registers a new context
249      * @param contextFilePath
250      *            The path to the file inside the bundle that defines the
251      *            context.
252      * @throws Exception
253      */
254     public static void registerContext(Bundle contributor, String contextFilePath) throws Exception
255     {
256         registerContext(contributor,contextFilePath,new Hashtable<String, String>());
257     }
258 
259     /**
260      * Helper method that creates a new skeleton of a ContextHandler and
261      * registers it as an OSGi service. The tracker
262      * {@link JettyContextHandlerServiceTracker} will do the actual deployment.
263      * 
264      * @param contributor
265      *            The bundle that registers a new context
266      * @param contextFilePath
267      *            The path to the file inside the bundle that defines the
268      *            context.
269      * @param dic
270      *          TODO: parameter description
271      * @throws Exception
272      */
273     public static void registerContext(Bundle contributor, String contextFilePath, Dictionary<String, String> dic) throws Exception
274     {
275         ContextHandler contextHandler = new ContextHandler();
276         dic.put(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH,contextFilePath);
277         dic.put(IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE,Boolean.TRUE.toString());
278         contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
279     }
280 
281     public static void unregister(String contextPath)
282     {
283         // todo
284     }
285     
286 
287 }