View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.osgi.boot;
20  
21  import java.util.Dictionary;
22  import java.util.HashMap;
23  import java.util.Hashtable;
24  import java.util.Map;
25  
26  import org.eclipse.jetty.deploy.App;
27  import org.eclipse.jetty.deploy.AppProvider;
28  import org.eclipse.jetty.deploy.DeploymentManager;
29  import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
30  import org.eclipse.jetty.server.handler.ContextHandler;
31  import org.eclipse.jetty.util.log.Log;
32  import org.eclipse.jetty.util.log.Logger;
33  import org.eclipse.jetty.webapp.WebAppContext;
34  import org.osgi.framework.Bundle;
35  import org.osgi.framework.FrameworkUtil;
36  import org.osgi.framework.ServiceReference;
37  import org.osgi.framework.ServiceRegistration;
38  
39  
40  
41  /**
42   * ServiceWebAppProvider
43   *
44   * Jetty Provider that knows how to deploy a WebApp that has been registered as an OSGi service.
45   * 
46   */
47  public class ServiceWebAppProvider extends AbstractWebAppProvider implements ServiceProvider
48  {   
49      private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class);
50      
51      
52      /**
53       * Map of ServiceRef to App. Used when it is an osgi service that is a WebAppContext.
54       */
55      private Map<ServiceReference, App> _serviceMap = new HashMap<ServiceReference, App>();
56      
57      private ServiceRegistration _serviceRegForServices;
58      
59      
60      /**
61       * ServiceApp
62       *
63       *
64       */
65      public class ServiceApp extends OSGiApp
66      {
67  
68          public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId)
69          {
70              super(manager, provider, bundle, properties, originId);
71          }
72  
73          public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId)
74          {
75              super(manager, provider, bundle, originId);
76          }
77  
78          @Override
79          public void registerAsOSGiService() throws Exception
80          {
81              //not applicable for apps that are already services
82          }
83  
84          @Override
85          protected void deregisterAsOSGiService() throws Exception
86          {
87              //not applicable for apps that are already services
88          }
89      }
90      
91      
92      
93      /* ------------------------------------------------------------ */
94      /**
95       * @param wrapper
96       */
97      public ServiceWebAppProvider (ServerInstanceWrapper wrapper)
98      {
99          super(wrapper);
100     }
101     
102     
103     /* ------------------------------------------------------------ */
104     /**
105      * A webapp that was deployed as an osgi service has been added,
106      * and we want to deploy it.
107      * 
108      * @param context the webapp
109      */
110     public boolean serviceAdded (ServiceReference serviceRef, ContextHandler context)
111     {   
112         if (context == null || !(context instanceof WebAppContext))
113             return false;
114         
115         String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK);
116         if (watermark != null && !"".equals(watermark))
117             return false;  //this service represents a webapp that has already been registered as a service by another of our deployers
118         
119         
120         WebAppContext webApp = (WebAppContext)context;
121         Dictionary properties = new Hashtable<String,String>();
122         
123         String contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
124         if (contextPath == null)
125             contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
126         if (contextPath == null)
127             return false; //No context path
128      
129         String base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH);
130         if (base == null)
131             base = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_WAR);
132         
133        if (base == null)
134            return false; //No webapp base
135         
136         String webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH);
137         if (webdefaultXml == null)
138             webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH);
139         if (webdefaultXml != null)
140             properties.put(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH, webdefaultXml);
141 
142         String webXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WEB_XML_PATH);
143         if (webXml == null)
144             webXml = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH);
145         if (webXml != null)
146             properties.put(OSGiWebappConstants.JETTY_WEB_XML_PATH, webXml);
147 
148         String extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH);
149         if (extraClassPath == null)
150             extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH);
151         if (extraClassPath != null)
152             properties.put(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH, extraClassPath);
153 
154         String bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE);
155         if (bundleInstallOverride == null)
156             bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE);
157         if (bundleInstallOverride != null)
158             properties.put(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE, bundleInstallOverride);
159 
160         String  requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
161         if (requiredTlds == null)
162             requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE);
163         if (requiredTlds != null)
164             properties.put(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requiredTlds);
165 
166         ClassLoader cl = Thread.currentThread().getContextClassLoader();
167         Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps());
168         try
169         {
170             String originId = getOriginId(serviceRef.getBundle(), base);
171             ServiceApp app = new ServiceApp(getDeploymentManager(), this, serviceRef.getBundle(), properties, originId);
172             app.setContextPath(contextPath);
173             app.setWebAppPath(base);
174             app.setWebAppContext(webApp); //set the pre=made webapp instance
175             _serviceMap.put(serviceRef, app);
176             getDeploymentManager().addApp(app);
177             return true;
178         }
179         finally
180         {
181             Thread.currentThread().setContextClassLoader(cl); 
182         }
183     }
184     
185     
186     
187     /* ------------------------------------------------------------ */
188     /**
189      * @param context the webapp
190      */
191     public boolean serviceRemoved (ServiceReference serviceRef, ContextHandler context)
192     {
193         if (context == null || !(context instanceof WebAppContext))
194             return false;
195         
196         String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK);
197         if (watermark != null && !"".equals(watermark))
198             return false;  //this service represents a contexthandler that will be deregistered as a service by another of our deployers
199         
200         App app = _serviceMap.remove(serviceRef);
201         if (app != null)
202         {
203             getDeploymentManager().removeApp(app);
204             return true;
205         }
206         return false;
207     }
208     
209     
210     /* ------------------------------------------------------------ */
211     /** 
212      * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
213      */
214     protected void doStart() throws Exception
215     {
216         //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to
217         Dictionary<String,String> properties = new Hashtable<String,String>();
218         properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
219        
220         //register as an osgi service for deploying contexts (discovered as osgi services), advertising the name of the jetty Server instance we are related to
221         _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties);
222         super.doStart();
223     }
224 
225     /* ------------------------------------------------------------ */
226     /** 
227      * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
228      */
229     @Override
230     protected void doStop() throws Exception
231     {
232         //unregister ourselves
233         if (_serviceRegForServices != null)
234         {
235             try
236             {
237                 _serviceRegForServices.unregister();
238             }
239             catch (Exception e)
240             {
241                 LOG.warn(e);
242             }
243         }
244         super.doStop();
245     }
246 
247 }