All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.osgi.BundleWebAppProvider Maven / Gradle / Ivy

There is a newer version: 12.1.0.alpha0
Show newest version
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.osgi;

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.osgi.util.Util;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.StringUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.BundleTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * BundleWebAppProvider
 * 

* A Jetty Provider that knows how to deploy a WebApp contained inside a Bundle. */ public class BundleWebAppProvider extends AbstractContextProvider implements BundleProvider { private static final Logger LOG = LoggerFactory.getLogger(AbstractContextProvider.class); /** * Map of Bundle to App. Used when a Bundle contains a webapp. */ private Map _bundleMap = new HashMap<>(); private ServiceRegistration _serviceRegForBundles; private WebAppTracker _webappTracker; public class WebAppTracker extends BundleTracker { protected String _managedServerName; public WebAppTracker(BundleContext bundleContext, String managedServerName) { super(bundleContext, Bundle.ACTIVE | Bundle.STOPPING, null); _managedServerName = managedServerName; } @Override public Object addingBundle(Bundle bundle, BundleEvent event) { try { String serverName = bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME)) || (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName)))) { if (bundleAdded(bundle)) return bundle; } } catch (Exception e) { LOG.warn("Unable to add bundle {}", bundle, e); } return null; } @Override public void removedBundle(Bundle bundle, BundleEvent event, Object object) { try { bundleRemoved(bundle); } catch (Exception e) { LOG.warn("Unable to remove bundle {}", bundle, e); } } } public BundleWebAppProvider(String environment, Server server, ContextFactory contextFactory) { super(environment, server, contextFactory); } @Override protected void doStart() throws Exception { String serverName = (String)getServer().getAttribute(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); _webappTracker = new WebAppTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), serverName); _webappTracker.open(); //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to Dictionary properties = new Hashtable<>(); properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName); _serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties); super.doStart(); } @Override protected void doStop() throws Exception { _webappTracker.close(); //unregister ourselves if (_serviceRegForBundles != null) { try { _serviceRegForBundles.unregister(); } catch (Exception e) { LOG.warn("Unable to unregister {}", _serviceRegForBundles, e); } } super.doStop(); } @Override public boolean isDeployable(Bundle bundle) { //is it destined for my environment? if (!super.isDeployable(bundle)) return false; //has a war path, could be a webapp if (!StringUtil.isBlank(Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, bundle.getHeaders()))) return true; //has a context path header, could be a webapp if (!StringUtil.isBlank(Util.getManifestHeaderValue(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH, bundle.getHeaders()))) return true; //has a web.xml, could be a webapp if (bundle.getEntry("/WEB-INF/web.xml") != null) return true; //not a webapp return false; } /** * A bundle has been added that could be a webapp * * @param bundle the bundle */ @Override public boolean bundleAdded(Bundle bundle) throws Exception { if (bundle == null) return false; //can this bundle be deployed to my environment? if (!isDeployable(bundle)) return false; ClassLoader cl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader((ClassLoader)getServer().getAttribute(OSGiServerConstants.SERVER_CLASSLOADER)); try { @SuppressWarnings("unchecked") Dictionary headers = bundle.getHeaders(); //does the bundle have a OSGiWebappConstants.JETTY_WAR_FOLDER_PATH String staticResourcesLocation = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, headers); if (staticResourcesLocation != null) { //TODO : we don't know whether an app is actually deployed, as deploymentManager swallows all //exceptions inside the impl of addApp. Need to send the Event and also register as a service //only if the deployment succeeded OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); app.setPathToResourceBase(staticResourcesLocation); _bundleMap.put(bundle, app); getDeploymentManager().addApp(app); return true; } //does the bundle have a WEB-INF/web.xml if (bundle.getEntry("/WEB-INF/web.xml") != null) { String base = "."; OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); app.setPathToResourceBase(base); _bundleMap.put(bundle, app); getDeploymentManager().addApp(app); return true; } //does the bundle define a OSGiWebappConstants.RFC66_WEB_CONTEXTPATH if (headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH) != null) { //Could be a static webapp with no web.xml String base = "."; OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle); app.setPathToResourceBase(base); _bundleMap.put(bundle, app); getDeploymentManager().addApp(app); return true; } //not a webapp return false; } finally { Thread.currentThread().setContextClassLoader(cl); } } /** * Bundle has been removed. If it was a webapp we deployed, undeploy it. * * @param bundle the bundle * @return true if this was a webapp we had deployed, false otherwise */ @Override public boolean bundleRemoved(Bundle bundle) throws Exception { App app = _bundleMap.remove(bundle); if (app != null) { getDeploymentManager().removeApp(app); return true; } return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy