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.osgi.framework.Bundle;
34  import org.osgi.framework.FrameworkUtil;
35  import org.osgi.framework.ServiceReference;
36  import org.osgi.framework.ServiceRegistration;
37  
38  /**
39   * ServiceContextProvider
40   *
41   *
42   */
43  public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider
44  { 
45      private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
46      
47      private Map<ServiceReference, App> _serviceMap = new HashMap<ServiceReference, App>();
48      
49      private ServiceRegistration _serviceRegForServices;
50      
51      
52      /**
53       * ServiceApp
54       *
55       *
56       */
57      public class ServiceApp extends OSGiApp
58      {
59          public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId)
60          {
61              super(manager, provider, bundle, properties, contextFile, originId);
62          }
63  
64          public ServiceApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile)
65          {
66              super(manager, provider, originId, bundle, contextFile);
67          }
68  
69          @Override
70          public void registerAsOSGiService() throws Exception
71          {
72              //not applicable for apps that are already services
73          }
74  
75          @Override
76          protected void deregisterAsOSGiService() throws Exception
77          {
78              //not applicable for apps that are already services
79          }
80      }
81      
82      
83      
84      /* ------------------------------------------------------------ */
85      public ServiceContextProvider(ServerInstanceWrapper wrapper)
86      {
87          super(wrapper);
88      }
89      
90      
91      /* ------------------------------------------------------------ */
92      public boolean serviceAdded (ServiceReference serviceRef, ContextHandler context)
93      {
94          if (context == null || serviceRef == null)
95              return false;
96          
97          String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK);
98          if (watermark != null && !"".equals(watermark))
99              return false;  //this service represents a contexthandler that has already been registered as a service by another of our deployers
100         
101         ClassLoader cl = Thread.currentThread().getContextClassLoader();
102         Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps());
103         try
104         {
105             //See if there is a context file to apply to this pre-made context
106             String contextFile = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
107             if (contextFile == null)
108                 contextFile = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH); 
109                   
110             String[] keys = serviceRef.getPropertyKeys();
111             Dictionary properties = new Hashtable<String, Object>();
112             if (keys != null)
113             {
114                 for (String key:keys)
115                     properties.put(key, serviceRef.getProperty(key));
116             }
117             Bundle bundle = serviceRef.getBundle();                
118             String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-"+contextFile;
119             ServiceApp app = new ServiceApp(getDeploymentManager(), this, bundle, properties, contextFile, originId);         
120             app.setHandler(context); //set the pre=made ContextHandler instance
121             _serviceMap.put(serviceRef, app);
122             getDeploymentManager().addApp(app);
123             return true;
124         }
125         finally
126         {
127             Thread.currentThread().setContextClassLoader(cl); 
128         }
129     }
130     
131     
132     /* ------------------------------------------------------------ */
133     public boolean serviceRemoved (ServiceReference serviceRef, ContextHandler context)
134     {
135 
136         if (context == null || serviceRef == null)
137             return false;
138         
139         String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK);
140         if (watermark != null && !"".equals(watermark))
141             return false;  //this service represents a contexthandler that will be deregistered as a service by another of our deployers
142         
143         App app = _serviceMap.remove(serviceRef);
144         if (app != null)
145         {
146             getDeploymentManager().removeApp(app);
147             return true;
148         }
149 
150         return false;
151     }
152     
153     
154     
155     /* ------------------------------------------------------------ */
156     @Override
157     protected void doStart() throws Exception
158     {
159         //register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to
160         Dictionary<String,String> properties = new Hashtable<String,String>();
161         properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
162         
163         //register as an osgi service for deploying contexts, advertising the name of the jetty Server instance we are related to
164         _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties);
165         super.doStart();
166     }
167     
168     /* ------------------------------------------------------------ */
169     @Override
170     protected void doStop() throws Exception
171     {
172         //unregister ourselves 
173         if (_serviceRegForServices != null)
174         {
175             try
176             {
177                 _serviceRegForServices.unregister();
178             }
179             catch (Exception e)
180             {
181                 LOG.warn(e);
182             }
183         }
184         super.doStop();
185     }
186 }