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.ArrayList;
22  import java.util.Dictionary;
23  import java.util.HashMap;
24  import java.util.Hashtable;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.eclipse.jetty.deploy.App;
29  import org.eclipse.jetty.deploy.DeploymentManager;
30  import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
31  import org.eclipse.jetty.osgi.boot.utils.EventSender;
32  import org.eclipse.jetty.server.handler.ContextHandler;
33  import org.eclipse.jetty.util.log.Log;
34  import org.eclipse.jetty.util.log.Logger;
35  import org.eclipse.jetty.webapp.WebAppContext;
36  import org.osgi.framework.Bundle;
37  import org.osgi.framework.FrameworkUtil;
38  import org.osgi.framework.ServiceReference;
39  import org.osgi.framework.ServiceRegistration;
40  
41  
42  
43  /**
44   * BundleContextProvider
45   *
46   * Handles deploying bundles that define a context xml file for configuring them.
47   * 
48   *
49   */
50  public class BundleContextProvider extends AbstractContextProvider implements BundleProvider
51  {    
52      private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
53      
54  
55      private Map<String, App> _appMap = new HashMap<String, App>();
56      
57      private Map<Bundle, List<App>> _bundleMap = new HashMap<Bundle, List<App>>();
58      
59      private ServiceRegistration _serviceRegForBundles;
60      
61  
62      
63    
64      /* ------------------------------------------------------------ */
65      public BundleContextProvider(ServerInstanceWrapper wrapper)
66      {
67          super(wrapper);
68      }
69      
70      
71      /* ------------------------------------------------------------ */
72      @Override
73      protected void doStart() throws Exception
74      {
75          //register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to
76          Dictionary<String,String> properties = new Hashtable<String,String>();
77          properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
78          _serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties);
79          super.doStart();
80      }
81  
82      /* ------------------------------------------------------------ */
83      @Override
84      protected void doStop() throws Exception
85      {
86          //unregister ourselves
87          if (_serviceRegForBundles != null)
88          {
89              try
90              {
91                  _serviceRegForBundles.unregister();
92              }
93              catch (Exception e)
94              {
95                  LOG.warn(e);
96              }
97          }
98      }
99  
100 
101 
102 
103     /* ------------------------------------------------------------ */
104     /**
105      * @param bundle
106      * @param contextFiles
107      * @return
108      */
109     public boolean bundleAdded (Bundle bundle) throws Exception
110     {
111         if (bundle == null)
112             return false;
113 
114         String contextFiles  = (String)bundle.getHeaders().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
115         if (contextFiles == null)
116             contextFiles = (String)bundle.getHeaders().get(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
117         
118         if (contextFiles == null)
119             return false;
120         
121         boolean added = false;
122         //bundle defines JETTY_CONTEXT_FILE_PATH header,
123         //a comma separated list of context xml files that each define a ContextHandler
124         //TODO: (could be WebAppContexts)       
125         String[] tmp = contextFiles.split(",;");
126         for (String contextFile : tmp)
127         {
128             String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-"+contextFile;
129             OSGiApp app = new OSGiApp(getDeploymentManager(), this, originId, bundle, contextFile);
130             _appMap.put(originId,app);
131             List<App> apps = _bundleMap.get(bundle);
132             if (apps == null)
133             {
134                 apps = new ArrayList<App>();
135                 _bundleMap.put(bundle, apps);
136             }
137             apps.add(app);
138             getDeploymentManager().addApp(app);
139         }
140 
141         return added; //true if even 1 context from this bundle was added
142     }
143     
144     
145     /* ------------------------------------------------------------ */
146     /** 
147      * Bundle has been removed. If it was a context we deployed, undeploy it.
148      * @param bundle
149      * 
150      * @return true if this was a context we had deployed, false otherwise
151      */
152     public boolean bundleRemoved (Bundle bundle) throws Exception
153     {
154         List<App> apps = _bundleMap.remove(bundle);
155         boolean removed = false;
156         if (apps != null)
157         {
158             for (App app:apps)
159             {
160                 _appMap.remove(app.getOriginId());
161                 getDeploymentManager().removeApp(app);
162                 removed = true;
163             }
164         }
165         return removed; //true if even 1 context was removed associated with this bundle
166     }
167     
168    
169 }