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