// ========================================================================
// Copyright (c) 2006-2009 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.deploy;
import java.util.ArrayList;
import org.eclipse.jetty.deploy.providers.ScanningAppProvider;
import org.eclipse.jetty.server.Handler;
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.util.AttributesMap;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* Legacy Web Application Deployer.
*
* <p>
* Note: The WebAppDeployer is being phased out of Jetty in favor of the {@link DeploymentManager} and
* {@link org.eclipse.jetty.deploy.providers.WebAppProvider} implementation.
*
* <p>
* The class searches a directory for and deploys standard web application. At startup, the directory specified by
* {@link #setWebAppDir(String)} is searched for subdirectories (excluding hidden and CVS) or files ending with ".zip"
* or "*.war". For each webapp discovered is passed to a new instance of {@link WebAppContext} (or a subclass specified
* by {@link #getContexts()}. {@link ContextHandlerCollection#getContextClass()}
*
* <p>
* This deployer does not do hot deployment or undeployment. Nor does it support per web application configuration. For
* these features see {@link ContextDeployer}.
*
* @deprecated
* @see DeploymentManager
* @see ScanningAppProvider
* @see ContextDeployer
*/
@SuppressWarnings("unchecked")
public class WebAppDeployer extends AbstractLifeCycle
{
private static final Logger LOG = Log.getLogger(WebAppDeployer.class);
private HandlerCollection _contexts;
private String _webAppDir;
private String _defaultsDescriptor;
private String[] _configurationClasses;
private boolean _extract;
private boolean _parentLoaderPriority;
private boolean _allowDuplicates;
private ArrayList _deployed;
private AttributesMap _contextAttributes = new AttributesMap();
public WebAppDeployer()
{
LOG.warn("WebAppDeployer is deprecated. Use WebAppProvider");
}
public String[] getConfigurationClasses()
{
return _configurationClasses;
}
public void setConfigurationClasses(String[] configurationClasses)
{
_configurationClasses=configurationClasses;
}
public HandlerCollection getContexts()
{
return _contexts;
}
public void setContexts(HandlerCollection contexts)
{
_contexts=contexts;
}
public String getDefaultsDescriptor()
{
return _defaultsDescriptor;
}
public void setDefaultsDescriptor(String defaultsDescriptor)
{
_defaultsDescriptor=defaultsDescriptor;
}
public boolean isExtract()
{
return _extract;
}
public void setExtract(boolean extract)
{
_extract=extract;
}
public boolean isParentLoaderPriority()
{
return _parentLoaderPriority;
}
public void setParentLoaderPriority(boolean parentPriorityClassLoading)
{
_parentLoaderPriority=parentPriorityClassLoading;
}
public String getWebAppDir()
{
return _webAppDir;
}
public void setWebAppDir(String dir)
{
_webAppDir=dir;
}
public boolean getAllowDuplicates()
{
return _allowDuplicates;
}
/* ------------------------------------------------------------ */
/**
* @param allowDuplicates If false, do not deploy webapps that have already been deployed or duplicate context path
*/
public void setAllowDuplicates(boolean allowDuplicates)
{
_allowDuplicates=allowDuplicates;
}
/**
* Set a contextAttribute that will be set for every Context deployed by this deployer.
* @param name
* @param value
*/
public void setAttribute (String name, Object value)
{
_contextAttributes.setAttribute(name,value);
}
/**
* Get a contextAttribute that will be set for every Context deployed by this deployer.
* @param name
* @return the attribute value
*/
public Object getAttribute (String name)
{
return _contextAttributes.getAttribute(name);
}
/**
* Remove a contextAttribute that will be set for every Context deployed by this deployer.
* @param name
*/
public void removeAttribute(String name)
{
_contextAttributes.removeAttribute(name);
}
/* ------------------------------------------------------------ */
/**
* @throws Exception
*/
@Override
public void doStart() throws Exception
{
_deployed=new ArrayList();
scan();
}
/* ------------------------------------------------------------ */
/** Scan for webapplications.
*
* @throws Exception
*/
public void scan() throws Exception
{
if (_contexts==null)
throw new IllegalArgumentException("No HandlerContainer");
Resource r=Resource.newResource(_webAppDir);
if (!r.exists())
throw new IllegalArgumentException("No such webapps resource "+r);
if (!r.isDirectory())
throw new IllegalArgumentException("Not directory webapps resource "+r);
String[] files=r.list();
files: for (int f=0; files!=null&&f<files.length; f++)
{
String context=files[f];
if (context.equalsIgnoreCase("CVS/")||context.equalsIgnoreCase("CVS")||context.startsWith("."))
continue;
Resource app=r.addPath(r.encode(context));
if (context.toLowerCase().endsWith(".war")||context.toLowerCase().endsWith(".jar"))
{
context=context.substring(0,context.length()-4);
Resource unpacked=r.addPath(context);
if (unpacked!=null&&unpacked.exists()&&unpacked.isDirectory())
continue;
}
else if (!app.isDirectory())
continue;
if (context.equalsIgnoreCase("root")||context.equalsIgnoreCase("root/"))
context=URIUtil.SLASH;
else
context="/"+context;
if (context.endsWith("/")&&context.length()>0)
context=context.substring(0,context.length()-1);
// Check the context path has not already been added or the webapp itself is not already deployed
if (!_allowDuplicates)
{
Handler[] installed=_contexts.getChildHandlersByClass(ContextHandler.class);
for (int i=0; i<installed.length; i++)
{
ContextHandler c = (ContextHandler)installed[i];
if (context.equals(c.getContextPath()))
continue files;
try
{
String path = null;
if (c instanceof WebAppContext)
path = Resource.newResource(((WebAppContext)c).getWar()).getFile().getCanonicalPath();
else if (c.getBaseResource() != null)
path = c.getBaseResource().getFile().getCanonicalPath();
if (path != null && path.equals(app.getFile().getCanonicalPath()))
{
LOG.debug("Already deployed: {}",path);
continue files;
}
}
catch (Exception e)
{
LOG.ignore(e);
}
}
}
// create a webapp
WebAppContext wah=null;
if (_contexts instanceof ContextHandlerCollection &&
WebAppContext.class.isAssignableFrom(((ContextHandlerCollection)_contexts).getContextClass()))
{
try
{
wah=(WebAppContext)((ContextHandlerCollection)_contexts).getContextClass().newInstance();
}
catch (Exception e)
{
throw new Error(e);
}
}
else
{
wah=new WebAppContext();
}
// configure it
wah.setContextPath(context);
if (_configurationClasses!=null)
wah.setConfigurationClasses(_configurationClasses);
if (_defaultsDescriptor!=null)
wah.setDefaultsDescriptor(_defaultsDescriptor);
wah.setExtractWAR(_extract);
wah.setWar(app.toString());
wah.setParentLoaderPriority(_parentLoaderPriority);
//set up any contextAttributes
wah.setAttributes(new AttributesMap(_contextAttributes));
// add it
_contexts.addHandler(wah);
_deployed.add(wah);
if (_contexts.isStarted())
wah.start(); // TODO Multi exception
}
}
@Override
public void doStop() throws Exception
{
for (int i=_deployed.size();i-->0;)
{
ContextHandler wac = (ContextHandler)_deployed.get(i);
wac.stop();// TODO Multi exception
}
}
}