/**
* EasyBeans
* Copyright (C) 2010 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: Jetty7Deployer.java 5369 2010-02-24 14:58:19Z benoitf $
* --------------------------------------------------------------------------
*/
package org.ow2.easybeans.deployer.web.jetty;
import java.net.URL;
import java.util.List;
import javax.servlet.ServletContextEvent;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler.Context;
import org.eclipse.jetty.webapp.WebAppContext;
import org.ow2.easybeans.deployer.AbsWebContainerDeployer;
import org.ow2.easybeans.deployment.api.EZBInjectionHolder;
import org.ow2.util.archive.api.ArchiveException;
import org.ow2.util.ee.deploy.api.deployable.EARDeployable;
import org.ow2.util.ee.deploy.api.deployable.WARDeployable;
import org.ow2.util.ee.deploy.api.deployer.DeployerException;
import org.ow2.util.ee.deploy.api.deployer.IDeployer;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
/**
* Deployer used when EasyBeans is embedded in Jetty 7.x.
* @author Florent Benoit
*/
public class Jetty7Deployer extends AbsWebContainerDeployer implements IDeployer {
/**
* Logger.
*/
private static Log logger = LogFactory.getLog(Jetty7Deployer.class);
/**
* List of the contexts deployed on the current jetty server.
*/
private ContextHandlerCollection contextHandlerCollection = null;
/**
* Link to the Jetty Server used to deploy the web applications. Static as
* shared by all jetty deployers.
*/
private Server jettyServer = null;
/**
* Build a new instance of this deployer.
* @throws DeployerException if the instance is not built.
*/
public Jetty7Deployer(final ServletContextEvent servletContextEvent) throws DeployerException {
super();
// First, try to get the source on the given context event
Object source = servletContextEvent.getSource();
if (source == null) {
throw new DeployerException("No source object on the given contextEvent '" + servletContextEvent + "'.");
}
if (!(source instanceof Context)) {
throw new DeployerException("Invalid source object '" + source + "'.");
}
Context context = (Context) source;
ContextHandler contextHandler = context.getContextHandler();
this.jettyServer = contextHandler.getServer();
// No server ?
if (this.jettyServer == null) {
throw new DeployerException("No Jetty server found on the servlet context event '" + servletContextEvent + "'.");
}
// Get handler collection
HandlerCollection handlerCollection = (HandlerCollection) this.jettyServer
.getChildHandlerByClass(HandlerCollection.class);
// Get the context handler collection
this.contextHandlerCollection = (ContextHandlerCollection) handlerCollection
.getChildHandlerByClass(HandlerCollection.class);
}
/**
* Deploy the WAR files present in the given EAR.
* @param earDeployable the EAR containing the WARs
* @param earURL the EAR URL
* @param earClassLoader the EAR classloader
* @param parentClassLoader the parent classloader (EJB) to use
* @param ejbInjectionHolder the EasyBeans injection holder object
* @throws DeployerException if the wars are not deployed.
*/
@Override
protected void deployWARs(final EARDeployable earDeployable, final URL earURL, final ClassLoader earClassLoader,
final ClassLoader parentClassLoader, final EZBInjectionHolder ejbInjectionHolder) throws DeployerException {
// First, try to see if there are .war in this EAR
List<WARDeployable> wars = earDeployable.getWARDeployables();
for (WARDeployable war : wars) {
// Build a new instance of the webapp context
WebAppContext webAppContext = new WebAppContext();
// invoke setters
// for the URL of the war file
try {
webAppContext.setWar(war.getArchive().getURL().getPath());
} catch (ArchiveException e) {
throw new DeployerException("Cannot get URL from the archive '" + war.getArchive() + "'.", e);
}
// Defines the name of the context
webAppContext.setContextPath("/" + war.getContextRoot());
// Java delegation model = true
webAppContext.setParentLoaderPriority(true);
// add the built context on the existing list
this.contextHandlerCollection.addHandler(webAppContext);
// set the thread context classloader to the parent classloader
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(parentClassLoader);
// start context
try {
webAppContext.start();
} catch (Exception e) {
throw new DeployerException("Cannot start the context '" + war.getContextRoot() + "'", e);
} finally {
// reset classloader
Thread.currentThread().setContextClassLoader(oldCl);
}
// War has been deployed
logger.info("The war ''{0}'' has been deployed on the ''{1}'' context.", war, war.getContextRoot());
}
}
/**
* Undeploy an given WAR (called by the undeploy method).
* @param warDeployable a given WAR deployable
* @throws DeployerException if the undeployment is not done.
*/
@Override
protected void undeployWAR(final WARDeployable warDeployable) throws DeployerException {
// get the root context of this deployable
String contextRoot = warDeployable.getContextRoot();
// Get all handlers
Handler[] handlers = this.contextHandlerCollection.getHandlers();
// For each handler, check the name of the context root
WebAppContext webAppContext = null;
for (Handler handler : handlers) {
// Handler is a webapp context ?
if (handler.getClass().equals(WebAppContext.class)) {
webAppContext = (WebAppContext) handler;
// get context
String foundCtx = webAppContext.getContextPath();
if (contextRoot.equals(foundCtx) || ("/" + contextRoot).equals(foundCtx)) {
// found !
break;
}
}
}
// Context not found
if (webAppContext == null) {
throw new DeployerException("Unable to find a context with the name '" + contextRoot
+ "' for the War deployable '" + warDeployable + "'.");
}
// Stop the context
try {
webAppContext.stop();
} catch (Exception e) {
logger.error("Unable to stop web app context", e);
}
// Remove the context
this.contextHandlerCollection.removeHandler(webAppContext);
logger.info("The context ''{0}'' of the War ''{1}'' has been undeployed", contextRoot, warDeployable);
}
}