| // |
| // ======================================================================== |
| // Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.osgi.boot; |
| |
| import java.util.Dictionary; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Map; |
| |
| import org.eclipse.jetty.deploy.App; |
| import org.eclipse.jetty.deploy.AppProvider; |
| import org.eclipse.jetty.deploy.DeploymentManager; |
| import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper; |
| import org.eclipse.jetty.server.handler.ContextHandler; |
| import org.eclipse.jetty.util.log.Log; |
| import org.eclipse.jetty.util.log.Logger; |
| import org.eclipse.jetty.webapp.WebAppContext; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.FrameworkUtil; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.ServiceRegistration; |
| |
| /** |
| * ServiceWebAppProvider |
| * <p> |
| * Jetty Provider that knows how to deploy a WebApp that has been registered as an OSGi service. |
| */ |
| public class ServiceWebAppProvider extends AbstractWebAppProvider implements ServiceProvider |
| { |
| private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class); |
| |
| /** |
| * Map of ServiceRef to App. Used when it is an osgi service that is a WebAppContext. |
| */ |
| private Map<ServiceReference, App> _serviceMap = new HashMap<ServiceReference, App>(); |
| |
| private ServiceRegistration _serviceRegForServices; |
| |
| /** |
| * ServiceApp |
| * |
| * |
| */ |
| public class ServiceApp extends OSGiApp |
| { |
| |
| public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId) |
| { |
| super(manager, provider, bundle, properties, originId); |
| } |
| |
| public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId) |
| { |
| super(manager, provider, bundle, originId); |
| } |
| |
| @Override |
| public void registerAsOSGiService() throws Exception |
| { |
| //not applicable for apps that are already services |
| } |
| |
| @Override |
| protected void deregisterAsOSGiService() throws Exception |
| { |
| //not applicable for apps that are already services |
| } |
| } |
| |
| |
| |
| /* ------------------------------------------------------------ */ |
| public ServiceWebAppProvider (ServerInstanceWrapper wrapper) |
| { |
| super(wrapper); |
| } |
| |
| |
| /* ------------------------------------------------------------ */ |
| /** |
| * A webapp that was deployed as an osgi service has been added, |
| * and we want to deploy it. |
| * |
| * @param context the webapp |
| */ |
| public boolean serviceAdded (ServiceReference serviceRef, ContextHandler context) |
| { |
| if (context == null || !(context instanceof WebAppContext)) |
| return false; |
| |
| String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); |
| if (watermark != null && !"".equals(watermark)) |
| return false; //this service represents a webapp that has already been registered as a service by another of our deployers |
| |
| |
| WebAppContext webApp = (WebAppContext)context; |
| Dictionary properties = new Hashtable<String,String>(); |
| |
| String contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH); |
| if (contextPath == null) |
| contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH); |
| if (contextPath == null) |
| return false; //No context path |
| |
| String base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH); |
| if (base == null) |
| base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH); |
| if (base == null) |
| base = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_WAR); |
| |
| if (base == null) |
| return false; //No webapp base |
| |
| String webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH); |
| if (webdefaultXml == null) |
| webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH); |
| if (webdefaultXml != null) |
| properties.put(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH, webdefaultXml); |
| |
| String webXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WEB_XML_PATH); |
| if (webXml == null) |
| webXml = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH); |
| if (webXml != null) |
| properties.put(OSGiWebappConstants.JETTY_WEB_XML_PATH, webXml); |
| |
| String extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH); |
| if (extraClassPath == null) |
| extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH); |
| if (extraClassPath != null) |
| properties.put(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH, extraClassPath); |
| |
| String bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE); |
| if (bundleInstallOverride == null) |
| bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE); |
| if (bundleInstallOverride != null) |
| properties.put(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE, bundleInstallOverride); |
| |
| String requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.REQUIRE_TLD_BUNDLE); |
| if (requiredTlds == null) |
| requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE); |
| if (requiredTlds != null) |
| properties.put(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requiredTlds); |
| |
| ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
| Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps()); |
| try |
| { |
| String originId = getOriginId(serviceRef.getBundle(), base); |
| ServiceApp app = new ServiceApp(getDeploymentManager(), this, serviceRef.getBundle(), properties, originId); |
| app.setContextPath(contextPath); |
| app.setWebAppPath(base); |
| app.setWebAppContext(webApp); //set the pre=made webapp instance |
| _serviceMap.put(serviceRef, app); |
| getDeploymentManager().addApp(app); |
| return true; |
| } |
| finally |
| { |
| Thread.currentThread().setContextClassLoader(cl); |
| } |
| } |
| |
| |
| |
| /* ------------------------------------------------------------ */ |
| /** |
| * @param context the webapp |
| */ |
| public boolean serviceRemoved (ServiceReference serviceRef, ContextHandler context) |
| { |
| if (context == null || !(context instanceof WebAppContext)) |
| return false; |
| |
| String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK); |
| if (watermark != null && !"".equals(watermark)) |
| return false; //this service represents a contexthandler that will be deregistered as a service by another of our deployers |
| |
| App app = _serviceMap.remove(serviceRef); |
| if (app != null) |
| { |
| getDeploymentManager().removeApp(app); |
| return true; |
| } |
| return false; |
| } |
| |
| |
| /* ------------------------------------------------------------ */ |
| /** |
| * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() |
| */ |
| protected void doStart() throws Exception |
| { |
| //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to |
| Dictionary<String,String> properties = new Hashtable<String,String>(); |
| properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName()); |
| |
| //register as an osgi service for deploying contexts (discovered as osgi services), advertising the name of the jetty Server instance we are related to |
| _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties); |
| super.doStart(); |
| } |
| |
| /* ------------------------------------------------------------ */ |
| /** |
| * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() |
| */ |
| @Override |
| protected void doStop() throws Exception |
| { |
| //unregister ourselves |
| if (_serviceRegForServices != null) |
| { |
| try |
| { |
| _serviceRegForServices.unregister(); |
| } |
| catch (Exception e) |
| { |
| LOG.warn(e); |
| } |
| } |
| super.doStop(); |
| } |
| |
| } |