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

org.mortbay.jetty.webapp.WebAppContext Maven / Gradle / Ivy

There is a newer version: 7.0.0.pre5
Show newest version
//========================================================================
//$Id: WebAppContext.java,v 1.5 2005/11/16 22:02:45 gregwilkins Exp $
//Copyright 2004-2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at 
//http://www.apache.org/licenses/LICENSE-2.0
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//========================================================================

package org.mortbay.jetty.webapp;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.security.PermissionCollection;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionListener;

import org.mortbay.component.AbstractLifeCycle;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.HandlerContainer;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.deployer.ContextDeployer;
import org.mortbay.jetty.deployer.WebAppDeployer;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.handler.ContextHandlerCollection;
import org.mortbay.jetty.handler.ErrorHandler;
import org.mortbay.jetty.handler.HandlerCollection;
import org.mortbay.jetty.security.SecurityHandler;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ErrorPageErrorHandler;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.servlet.SessionHandler;
import org.mortbay.log.Log;
import org.mortbay.resource.JarResource;
import org.mortbay.resource.Resource;
import org.mortbay.util.IO;
import org.mortbay.util.LazyList;
import org.mortbay.util.Loader;
import org.mortbay.util.StringUtil;
import org.mortbay.util.URIUtil;
import org.mortbay.util.UrlEncoded;

/* ------------------------------------------------------------ */
/** Web Application Context Handler.
 * The WebAppContext handler is an extension of ContextHandler that
 * coordinates the construction and configuration of nested handlers:
 * {@link org.mortbay.jetty.security.SecurityHandler}, {@link org.mortbay.jetty.servlet.SessionHandler}
 * and {@link org.mortbay.jetty.servlet.ServletHandler}.
 * The handlers are configured by pluggable configuration classes, with
 * the default being  {@link org.mortbay.jetty.webapp.WebXmlConfiguration} and 
 * {@link org.mortbay.jetty.webapp.JettyWebXmlConfiguration}.
 *      
 * @org.apache.xbean.XBean description="Creates a servlet web application at a given context from a resource base"
 * 
 * @author gregw
 *
 */
public class WebAppContext extends Context
{   
    public final static String WEB_DEFAULTS_XML="org/mortbay/jetty/webapp/webdefault.xml";
    public final static String ERROR_PAGE="org.mortbay.jetty.error_page";
    
    private static String[] __dftConfigurationClasses =  
    { 
        "org.mortbay.jetty.webapp.WebInfConfiguration", 
        "org.mortbay.jetty.webapp.WebXmlConfiguration", 
        "org.mortbay.jetty.webapp.JettyWebXmlConfiguration",
        "org.mortbay.jetty.webapp.TagLibConfiguration" 
    } ;
    private String[] _configurationClasses=__dftConfigurationClasses;
    private Configuration[] _configurations;
    private String _defaultsDescriptor=WEB_DEFAULTS_XML;
    private String _descriptor=null;
    private String _overrideDescriptor=null;
    private boolean _distributable=false;
    private boolean _extractWAR=true;
    private boolean _copyDir=false;
    private boolean _logUrlOnStart =false;
    private boolean _parentLoaderPriority= Boolean.getBoolean("org.mortbay.jetty.webapp.parentLoaderPriority");
    private PermissionCollection _permissions;
    private String[] _systemClasses = {"java.","javax.servlet.","javax.xml.","org.mortbay.","org.xml.","org.w3c.", "org.apache.commons.logging.", "org.apache.log4j."};
    private String[] _serverClasses = {"-org.mortbay.jetty.plus.jaas.", "org.mortbay.jetty.", "org.slf4j."}; // TODO hide all mortbay classes
    private File _tmpDir;
    private boolean _isExistingTmpDir;
    private String _war;
    private String _extraClasspath;
    private Throwable _unavailableException;
    
    
    private transient Map _resourceAliases;
    private transient boolean _ownClassLoader=false;
    private transient boolean _unavailable;

    public static ContextHandler getCurrentWebAppContext()
    {
        ContextHandler.SContext context=ContextHandler.getCurrentContext();
        if (context!=null)
        {
            ContextHandler handler = context.getContextHandler();
            if (handler instanceof WebAppContext)
                return (ContextHandler)handler;
        }
        return null;   
    }
    
    /* ------------------------------------------------------------ */
    /**  Add Web Applications.
     * Add auto webapplications to the server.  The name of the
     * webapp directory or war is used as the context name. If the
     * webapp matches the rootWebApp it is added as the "/" context.
     * @param server Must not be null
     * @param webapps Directory file name or URL to look for auto
     * webapplication.
     * @param defaults The defaults xml filename or URL which is
     * loaded before any in the web app. Must respect the web.dtd.
     * If null the default defaults file is used. If the empty string, then
     * no defaults file is used.
     * @param extract If true, extract war files
     * @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
     * @exception IOException 
     * @deprecated use {@link org.mortbay.jetty.deployer.WebAppDeployer} or {@link org.mortbay.jetty.deployer.ContextDeployer}
     */
    public static void addWebApplications(Server server,
                                          String webapps,
                                          String defaults,
                                          boolean extract,
                                          boolean java2CompliantClassLoader)
        throws IOException
    {
        addWebApplications(server, webapps, defaults, __dftConfigurationClasses, extract, java2CompliantClassLoader);
    }
    
    /* ------------------------------------------------------------ */
    /**  Add Web Applications.
     * Add auto webapplications to the server.  The name of the
     * webapp directory or war is used as the context name. If the
     * webapp matches the rootWebApp it is added as the "/" context.
     * @param server Must not be null.
     * @param webapps Directory file name or URL to look for auto
     * webapplication.
     * @param defaults The defaults xml filename or URL which is
     * loaded before any in the web app. Must respect the web.dtd.
     * If null the default defaults file is used. If the empty string, then
     * no defaults file is used.
     * @param configurations Array of classnames of {@link Configuration} implementations to apply.
     * @param extract If true, extract war files
     * @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
     * @exception IOException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @deprecated use {@link org.mortbay.jetty.deployer.WebAppDeployer} or {@link org.mortbay.jetty.deployer.ContextDeployer}
     */
    public static void addWebApplications(Server server,
                                          String webapps,
                                          String defaults,
                                          String[] configurations,
                                          boolean extract,
                                          boolean java2CompliantClassLoader)
        throws IOException
    {
        HandlerCollection contexts = (HandlerCollection)server.getChildHandlerByClass(ContextHandlerCollection.class);
        if (contexts==null)
            contexts = (HandlerCollection)server.getChildHandlerByClass(HandlerCollection.class);
        
        addWebApplications(contexts,webapps,defaults,configurations,extract,java2CompliantClassLoader);
    }        

    /* ------------------------------------------------------------ */
    /**  Add Web Applications.
     * Add auto webapplications to the server.  The name of the
     * webapp directory or war is used as the context name. If the
     * webapp is called "root" it is added as the "/" context.
     * @param contexts A HandlerContainer to which the contexts will be added
     * @param webapps Directory file name or URL to look for auto
     * webapplication.
     * @param defaults The defaults xml filename or URL which is
     * loaded before any in the web app. Must respect the web.dtd.
     * If null the default defaults file is used. If the empty string, then
     * no defaults file is used.
     * @param configurations Array of classnames of {@link Configuration} implementations to apply.
     * @param extract If true, extract war files
     * @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
     * @exception IOException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @deprecated use {@link WebAppDeployer} or {@link ContextDeployer}
     */
    public static void addWebApplications(HandlerContainer contexts,
                                          String webapps,
                                          String defaults,
                                          boolean extract,
                                          boolean java2CompliantClassLoader)
    throws IOException
    {
        addWebApplications(contexts, webapps, defaults, __dftConfigurationClasses, extract, java2CompliantClassLoader);
    }
    
    /* ------------------------------------------------------------ */
    /**  Add Web Applications.
     * Add auto webapplications to the server.  The name of the
     * webapp directory or war is used as the context name. If the
     * webapp is called "root" it is added as the "/" context.
     * @param contexts A HandlerContainer to which the contexts will be added
     * @param webapps Directory file name or URL to look for auto
     * webapplication.
     * @param defaults The defaults xml filename or URL which is
     * loaded before any in the web app. Must respect the web.dtd.
     * If null the default defaults file is used. If the empty string, then
     * no defaults file is used.
     * @param configurations Array of classnames of {@link Configuration} implementations to apply.
     * @param extract If true, extract war files
     * @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
     * @exception IOException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @deprecated use {@link WebAppDeployer} or {@link ContextDeployer}
     */
    public static void addWebApplications(HandlerContainer contexts,
                                          String webapps,
                                          String defaults,
                                          String[] configurations,
                                          boolean extract,
                                          boolean java2CompliantClassLoader)
        throws IOException
    {
        Log.warn("Deprecated configuration used for "+webapps);
        WebAppDeployer deployer = new WebAppDeployer();
        deployer.setContexts(contexts);
        deployer.setWebAppDir(webapps);
        deployer.setConfigurationClasses(configurations);
        deployer.setExtract(extract);
        deployer.setParentLoaderPriority(java2CompliantClassLoader);
        try
        {
            deployer.start();
        }
        catch(IOException e)
        {
            throw e;
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }
    }
    
    /* ------------------------------------------------------------ */
    public WebAppContext()
    {
        this(null,null,null,null);
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param contextPath The context path
     * @param webApp The URL or filename of the webapp directory or war file.
     */
    public WebAppContext(String webApp,String contextPath)
    {
        super(null,contextPath,SESSIONS|SECURITY);
        setContextPath(contextPath);
        setWar(webApp);
        setErrorHandler(new ErrorPageErrorHandler());
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param parent The parent HandlerContainer.
     * @param contextPath The context path
     * @param webApp The URL or filename of the webapp directory or war file.
     */
    public WebAppContext(HandlerContainer parent, String webApp, String contextPath)
    {
        super(parent,contextPath,SESSIONS|SECURITY);
        setWar(webApp);
        setErrorHandler(new ErrorPageErrorHandler());
    }

    /* ------------------------------------------------------------ */
    /**
     */
    public WebAppContext(SecurityHandler securityHandler,SessionHandler sessionHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
    {
        super(null,
              sessionHandler!=null?sessionHandler:new SessionHandler(),
              securityHandler!=null?securityHandler:new SecurityHandler(),
              servletHandler!=null?servletHandler:new ServletHandler(),
              null);
        
        setErrorHandler(errorHandler!=null?errorHandler:new ErrorPageErrorHandler());
    }    

    /* ------------------------------------------------------------ */
    /** Get an exception that caused the webapp to be unavailable
     * @return A throwable if the webapp is unavailable or null
     */
    public Throwable getUnavailableException()
    {
        return _unavailableException;
    }

    
    /* ------------------------------------------------------------ */
    /** Set Resource Alias.
     * Resource aliases map resource uri's within a context.
     * They may optionally be used by a handler when looking for
     * a resource.  
     * @param alias 
     * @param uri 
     */
    public void setResourceAlias(String alias, String uri)
    {
        if (_resourceAliases == null)
            _resourceAliases= new HashMap(5);
        _resourceAliases.put(alias, uri);
    }

    /* ------------------------------------------------------------ */
    public Map getResourceAliases()
    {
        if (_resourceAliases == null)
            return null;
        return _resourceAliases;
    }
    
    /* ------------------------------------------------------------ */
    public void setResourceAliases(Map map)
    {
        _resourceAliases = map;
    }
    
    /* ------------------------------------------------------------ */
    public String getResourceAlias(String alias)
    {
        if (_resourceAliases == null)
            return null;
        return (String)_resourceAliases.get(alias);
    }

    /* ------------------------------------------------------------ */
    public String removeResourceAlias(String alias)
    {
        if (_resourceAliases == null)
            return null;
        return (String)_resourceAliases.remove(alias);
    }

    /* ------------------------------------------------------------ */
    /* (non-Javadoc)
     * @see org.mortbay.jetty.handler.ContextHandler#setClassLoader(java.lang.ClassLoader)
     */
    public void setClassLoader(ClassLoader classLoader)
    {
        super.setClassLoader(classLoader);
        if (classLoader!=null && classLoader instanceof WebAppClassLoader)
            ((WebAppClassLoader)classLoader).setName(getDisplayName());
    }
    
    /* ------------------------------------------------------------ */
    public Resource getResource(String uriInContext) throws MalformedURLException
    {
        IOException ioe= null;
        Resource resource= null;
        int loop=0;
        while (uriInContext!=null && loop++<100)
        {
            try
            {
                resource= super.getResource(uriInContext);
                if (resource != null && resource.exists())
                    return resource;
                
                uriInContext = getResourceAlias(uriInContext);
            }
            catch (IOException e)
            {
                Log.ignore(e);
                if (ioe==null)
                    ioe= e;
            }
        }

        if (ioe != null && ioe instanceof MalformedURLException)
            throw (MalformedURLException)ioe;

        return resource;
    }
    

    /* ------------------------------------------------------------ */
    /** 
     * @see org.mortbay.jetty.handler.ContextHandler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
     */
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
    throws IOException, ServletException
    {   
        if (_unavailable)
        {
            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
        }
        else
            super.handle(target, request, response, dispatch);
    }

    /* ------------------------------------------------------------ */
    /* 
     * @see org.mortbay.thread.AbstractLifeCycle#doStart()
     */
    protected void doStart() throws Exception
    {
        try
        {
            // Setup configurations 
            loadConfigurations();

            for (int i=0;i<_configurations.length;i++)
                _configurations[i].setWebAppContext(this);

            // Configure classloader
            _ownClassLoader=false;
            if (getClassLoader()==null)
            {
                WebAppClassLoader classLoader = new WebAppClassLoader(this);
                setClassLoader(classLoader);
                _ownClassLoader=true;
            }

            if (Log.isDebugEnabled()) 
            {
                ClassLoader loader = getClassLoader();
                Log.debug("Thread Context class loader is: " + loader);
                loader=loader.getParent();
                while(loader!=null)
                {
                    Log.debug("Parent class loader is: " + loader); 
                    loader=loader.getParent();
                }
            }

            for (int i=0;i<_configurations.length;i++)
                _configurations[i].configureClassLoader();

            getTempDirectory();
            if (_tmpDir!=null && !_isExistingTmpDir && !isTempWorkDirectory())
            {
                File sentinel = new File(_tmpDir, ".active");
                if(!sentinel.exists())
                    sentinel.mkdir();
            }

            super.doStart();

            if (isLogUrlOnStart()) 
                dumpUrl();
        }
        catch (Exception e)
        {
            //start up of the webapp context failed, make sure it is not started
            Log.warn("Failed startup of context "+this, e);
            _unavailableException=e;
            _unavailable = true;
        }
    }

    /* ------------------------------------------------------------ */
    /*
     * Dumps the current web app name and URL to the log
     */
    public void dumpUrl() 
    {
        Connector[] connectors = getServer().getConnectors();
        for (int i=0;i0;)
                _configurations[i].deconfigureWebApp();
            _configurations=null;
            
            // restore security handler
            if (_securityHandler.getHandler()==null)
            {
                _sessionHandler.setHandler(_securityHandler);
                _securityHandler.setHandler(_servletHandler);
            }
            
            // delete temp directory if we had to create it or if it isn't called work
            if (_tmpDir!=null && !_isExistingTmpDir && !isTempWorkDirectory()) //_tmpDir!=null && !"work".equals(_tmpDir.getName()))
            {
                IO.delete(_tmpDir);
                _tmpDir=null;
            }
        }
        finally
        {
            if (_ownClassLoader)
                setClassLoader(null);
            
            _unavailable = false;
            _unavailableException=null;
        }
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @return Returns the configurations.
     */
    public String[] getConfigurationClasses()
    {
        return _configurationClasses;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @return Returns the configurations.
     */
    public Configuration[] getConfigurations()
    {
        return _configurations;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * The default descriptor is a web.xml format file that is applied to the context before the standard WEB-INF/web.xml
     * @return Returns the defaultsDescriptor.
     */
    public String getDefaultsDescriptor()
    {
        return _defaultsDescriptor;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * The override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml
     * @return Returns the Override Descriptor.
     */
    public String getOverrideDescriptor()
    {
        return _overrideDescriptor;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @return Returns the permissions.
     */
    public PermissionCollection getPermissions()
    {
        return _permissions;
    }
    

    /* ------------------------------------------------------------ */
    /**
     * @return Returns the serverClasses.
     */
    public String[] getServerClasses()
    {
        return _serverClasses;
    }
    
    
    /* ------------------------------------------------------------ */
    /**
     * @return Returns the systemClasses.
     */
    public String[] getSystemClasses()
    {
        return _systemClasses;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * Get a temporary directory in which to unpack the war etc etc.
     * The algorithm for determining this is to check these alternatives
     * in the order shown:
     * 
     * 

A. Try to use an explicit directory specifically for this webapp:

*
    *
  1. * Iff an explicit directory is set for this webapp, use it. Do NOT set * delete on exit. *
  2. *
  3. * Iff javax.servlet.context.tempdir context attribute is set for * this webapp && exists && writeable, then use it. Do NOT set delete on exit. *
  4. *
* *

B. Create a directory based on global settings. The new directory * will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost * Work out where to create this directory: *

    *
  1. * Iff $(jetty.home)/work exists create the directory there. Do NOT * set delete on exit. Do NOT delete contents if dir already exists. *
  2. *
  3. * Iff WEB-INF/work exists create the directory there. Do NOT set * delete on exit. Do NOT delete contents if dir already exists. *
  4. *
  5. * Else create dir in $(java.io.tmpdir). Set delete on exit. Delete * contents if dir already exists. *
  6. *
* * @return */ public File getTempDirectory() { if (_tmpDir!=null && _tmpDir.isDirectory() && _tmpDir.canWrite()) return _tmpDir; // Initialize temporary directory // // I'm afraid that this is very much black magic. // but if you can think of better.... Object t = getAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR); if (t!=null && (t instanceof File)) { _tmpDir=(File)t; if (_tmpDir.isDirectory() && _tmpDir.canWrite()) return _tmpDir; } if (t!=null && (t instanceof String)) { try { _tmpDir=new File((String)t); if (_tmpDir.isDirectory() && _tmpDir.canWrite()) { if(Log.isDebugEnabled())Log.debug("Converted to File "+_tmpDir+" for "+this); setAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR,_tmpDir); return _tmpDir; } } catch(Exception e) { Log.warn(Log.EXCEPTION,e); } } // No tempdir so look for a work directory to use as tempDir base File work=null; try { File w=new File(System.getProperty("jetty.home"),"work"); if (w.exists() && w.canWrite() && w.isDirectory()) work=w; else if (getBaseResource()!=null) { Resource web_inf = getWebInf(); if (web_inf !=null && web_inf.exists()) { w=new File(web_inf.getFile(),"work"); if (w.exists() && w.canWrite() && w.isDirectory()) work=w; } } } catch(Exception e) { Log.ignore(e); } // No tempdir set so make one! try { String temp = getCanonicalNameForWebAppTmpDir(); if (work!=null) _tmpDir=new File(work,temp); else { _tmpDir=new File(System.getProperty("java.io.tmpdir"),temp); if (_tmpDir.exists()) { if(Log.isDebugEnabled())Log.debug("Delete existing temp dir "+_tmpDir+" for "+this); if (!IO.delete(_tmpDir)) { if(Log.isDebugEnabled())Log.debug("Failed to delete temp dir "+_tmpDir); } if (_tmpDir.exists()) { String old=_tmpDir.toString(); _tmpDir=File.createTempFile(temp+"_",""); if (_tmpDir.exists()) _tmpDir.delete(); Log.warn("Can't reuse "+old+", using "+_tmpDir); } } } if (!_tmpDir.exists()) _tmpDir.mkdir(); //if not in a dir called "work" then we want to delete it on jvm exit if (!isTempWorkDirectory()) _tmpDir.deleteOnExit(); if(Log.isDebugEnabled())Log.debug("Created temp dir "+_tmpDir+" for "+this); } catch(Exception e) { _tmpDir=null; Log.ignore(e); } if (_tmpDir==null) { try{ // that didn't work, so try something simpler (ish) _tmpDir=File.createTempFile("JettyContext",""); if (_tmpDir.exists()) _tmpDir.delete(); _tmpDir.mkdir(); _tmpDir.deleteOnExit(); if(Log.isDebugEnabled())Log.debug("Created temp dir "+_tmpDir+" for "+this); } catch(IOException e) { Log.warn("tmpdir",e); System.exit(1); } } setAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR,_tmpDir); return _tmpDir; } /** * Check if the _tmpDir itself is called "work", or if the _tmpDir * is in a directory called "work". * @return */ public boolean isTempWorkDirectory () { if (_tmpDir == null) return false; if (_tmpDir.getName().equalsIgnoreCase("work")) return true; File t = _tmpDir.getParentFile(); if (t == null) return false; return (t.getName().equalsIgnoreCase("work")); } /* ------------------------------------------------------------ */ /** * @return Returns the war as a file or URL string (Resource) */ public String getWar() { if (_war==null) _war=getResourceBase(); return _war; } /* ------------------------------------------------------------ */ public Resource getWebInf() throws IOException { resolveWebApp(); // Iw there a WEB-INF directory? Resource web_inf= super.getBaseResource().addPath("WEB-INF/"); if (!web_inf.exists() || !web_inf.isDirectory()) return null; return web_inf; } /* ------------------------------------------------------------ */ /** * @return Returns the distributable. */ public boolean isDistributable() { return _distributable; } /* ------------------------------------------------------------ */ /** * @return Returns the extractWAR. */ public boolean isExtractWAR() { return _extractWAR; } /* ------------------------------------------------------------ */ /** * @return True if the webdir is copied (to allow hot replacement of jars) */ public boolean isCopyWebDir() { return _copyDir; } /* ------------------------------------------------------------ */ /** * @return Returns the java2compliant. */ public boolean isParentLoaderPriority() { return _parentLoaderPriority; } /* ------------------------------------------------------------ */ protected void loadConfigurations() throws Exception { if (_configurations!=null) return; if (_configurationClasses==null) _configurationClasses=__dftConfigurationClasses; _configurations = new Configuration[_configurationClasses.length]; for (int i=0;i<_configurations.length;i++) { _configurations[i]=(Configuration)Loader.loadClass(this.getClass(), _configurationClasses[i]).newInstance(); } } /* ------------------------------------------------------------ */ protected boolean isProtectedTarget(String target) { while (target.startsWith("//")) target=URIUtil.compactPath(target); return StringUtil.startsWithIgnoreCase(target, "/web-inf") || StringUtil.startsWithIgnoreCase(target, "/meta-inf"); } /* ------------------------------------------------------------ */ public String toString() { return this.getClass().getName()+"@"+Integer.toHexString(hashCode())+"{"+getContextPath()+","+(_war==null?getResourceBase():_war)+"}"; } /* ------------------------------------------------------------ */ /** Resolve Web App directory * If the BaseResource has not been set, use the war resource to * derive a webapp resource (expanding WAR if required). */ protected void resolveWebApp() throws IOException { Resource web_app = super.getBaseResource(); if (web_app == null) { if (_war==null || _war.length()==0) _war=getResourceBase(); // Set dir or WAR web_app= Resource.newResource(_war); // Accept aliases for WAR files if (web_app.getAlias() != null) { Log.debug(web_app + " anti-aliased to " + web_app.getAlias()); web_app= Resource.newResource(web_app.getAlias()); } if (Log.isDebugEnabled()) Log.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()); // Is the WAR usable directly? if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:")) { // No - then lets see if it can be turned into a jar URL. Resource jarWebApp= Resource.newResource("jar:" + web_app + "!/"); if (jarWebApp.exists() && jarWebApp.isDirectory()) { web_app= jarWebApp; } } // If we should extract or the URL is still not usable if (web_app.exists() && ( (_copyDir && web_app.getFile()!= null && web_app.getFile().isDirectory()) || (_extractWAR && web_app.getFile()!= null && !web_app.getFile().isDirectory()) || (_extractWAR && web_app.getFile() == null) || !web_app.isDirectory() )) { // Then extract it if necessary. File extractedWebAppDir= new File(getTempDirectory(), "webapp"); if (web_app.getFile()!=null && web_app.getFile().isDirectory()) { // Copy directory Log.info("Copy " + web_app.getFile() + " to " + extractedWebAppDir); IO.copyDir(web_app.getFile(),extractedWebAppDir); } else { if (!extractedWebAppDir.exists()) { //it hasn't been extracted before so extract it extractedWebAppDir.mkdir(); Log.info("Extract " + _war + " to " + extractedWebAppDir); JarResource.extract(web_app, extractedWebAppDir, false); } else { //only extract if the war file is newer if (web_app.lastModified() > extractedWebAppDir.lastModified()) { extractedWebAppDir.delete(); extractedWebAppDir.mkdir(); Log.info("Extract " + _war + " to " + extractedWebAppDir); JarResource.extract(web_app, extractedWebAppDir, false); } } } web_app= Resource.newResource(extractedWebAppDir.getCanonicalPath()); } // Now do we have something usable? if (!web_app.exists() || !web_app.isDirectory()) { Log.warn("Web application not found " + _war); throw new java.io.FileNotFoundException(_war); } if (Log.isDebugEnabled()) Log.debug("webapp=" + web_app); // ResourcePath super.setBaseResource(web_app); } } /* ------------------------------------------------------------ */ /** * @param configurations The configuration class names. If setConfigurations is not called * these classes are used to create a configurations array. */ public void setConfigurationClasses(String[] configurations) { if (isRunning()) throw new IllegalStateException("Running"); _configurationClasses = configurations==null?null:(String[])configurations.clone(); } /* ------------------------------------------------------------ */ /** * @param configurations The configurations to set. */ public void setConfigurations(Configuration[] configurations) { if (isRunning()) throw new IllegalStateException("Running"); _configurations = configurations==null?null:(Configuration[])configurations.clone(); } /* ------------------------------------------------------------ */ /** * The default descriptor is a web.xml format file that is applied to the context before the standard WEB-INF/web.xml * @param defaultsDescriptor The defaultsDescriptor to set. */ public void setDefaultsDescriptor(String defaultsDescriptor) { if (isRunning()) throw new IllegalStateException("Running"); _defaultsDescriptor = defaultsDescriptor; } /* ------------------------------------------------------------ */ /** * The override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml * @param defaultsDescriptor The overrideDescritpor to set. */ public void setOverrideDescriptor(String overrideDescriptor) { if (isRunning()) throw new IllegalStateException("Running"); _overrideDescriptor = overrideDescriptor; } /* ------------------------------------------------------------ */ /** * @return the web.xml descriptor to use. If set to null, WEB-INF/web.xml is used if it exists. */ public String getDescriptor() { return _descriptor; } /* ------------------------------------------------------------ */ /** * @param descriptor the web.xml descriptor to use. If set to null, WEB-INF/web.xml is used if it exists. */ public void setDescriptor(String descriptor) { if (isRunning()) throw new IllegalStateException("Running"); _descriptor=descriptor; } /* ------------------------------------------------------------ */ /** * @param distributable The distributable to set. */ public void setDistributable(boolean distributable) { this._distributable = distributable; } /* ------------------------------------------------------------ */ public void setEventListeners(EventListener[] eventListeners) { if (_sessionHandler!=null) _sessionHandler.clearEventListeners(); super.setEventListeners(eventListeners); for (int i=0; eventListeners!=null && i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy