View Javadoc

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