103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.webapp; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.File; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URI; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URISyntaxException; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URL; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URLClassLoader; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ArrayList; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Locale; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.regex.Pattern; 3103928aee4356845252ac6b662d5c72c29903813eJake Slack 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Connector; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Server; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.IO; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.PatternMatcher; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.URIUtil; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.JarResource; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.Resource; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.ResourceCollection; 4203928aee4356845252ac6b662d5c72c29903813eJake Slack 4303928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class WebInfConfiguration extends AbstractConfiguration 4403928aee4356845252ac6b662d5c72c29903813eJake Slack{ 4503928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(WebInfConfiguration.class); 4603928aee4356845252ac6b662d5c72c29903813eJake Slack 4703928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured"; 4803928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"; 4903928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern"; 5003928aee4356845252ac6b662d5c72c29903813eJake Slack 5103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * If set, to a list of URLs, these resources are added to the context 5303928aee4356845252ac6b662d5c72c29903813eJake Slack * resource base as a resource collection. 5403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 5503928aee4356845252ac6b662d5c72c29903813eJake Slack public static final String RESOURCE_URLS = "org.eclipse.jetty.resources"; 5603928aee4356845252ac6b662d5c72c29903813eJake Slack 5703928aee4356845252ac6b662d5c72c29903813eJake Slack protected Resource _preUnpackBaseResource; 5803928aee4356845252ac6b662d5c72c29903813eJake Slack 5903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 6003928aee4356845252ac6b662d5c72c29903813eJake Slack public void preConfigure(final WebAppContext context) throws Exception 6103928aee4356845252ac6b662d5c72c29903813eJake Slack { 6203928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for a work directory 6303928aee4356845252ac6b662d5c72c29903813eJake Slack File work = findWorkDirectory(context); 6403928aee4356845252ac6b662d5c72c29903813eJake Slack if (work != null) 6503928aee4356845252ac6b662d5c72c29903813eJake Slack makeTempDirectory(work, context, false); 6603928aee4356845252ac6b662d5c72c29903813eJake Slack 6703928aee4356845252ac6b662d5c72c29903813eJake Slack //Make a temp directory for the webapp if one is not already set 6803928aee4356845252ac6b662d5c72c29903813eJake Slack resolveTempDirectory(context); 6903928aee4356845252ac6b662d5c72c29903813eJake Slack 7003928aee4356845252ac6b662d5c72c29903813eJake Slack //Extract webapp if necessary 7103928aee4356845252ac6b662d5c72c29903813eJake Slack unpack (context); 7203928aee4356845252ac6b662d5c72c29903813eJake Slack 7303928aee4356845252ac6b662d5c72c29903813eJake Slack 7403928aee4356845252ac6b662d5c72c29903813eJake Slack //Apply an initial ordering to the jars which governs which will be scanned for META-INF 7503928aee4356845252ac6b662d5c72c29903813eJake Slack //info and annotations. The ordering is based on inclusion patterns. 7603928aee4356845252ac6b662d5c72c29903813eJake Slack String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN); 7703928aee4356845252ac6b662d5c72c29903813eJake Slack Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp)); 7803928aee4356845252ac6b662d5c72c29903813eJake Slack tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN); 7903928aee4356845252ac6b662d5c72c29903813eJake Slack Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp)); 8003928aee4356845252ac6b662d5c72c29903813eJake Slack 8103928aee4356845252ac6b662d5c72c29903813eJake Slack //Apply ordering to container jars - if no pattern is specified, we won't 8203928aee4356845252ac6b662d5c72c29903813eJake Slack //match any of the container jars 8303928aee4356845252ac6b662d5c72c29903813eJake Slack PatternMatcher containerJarNameMatcher = new PatternMatcher () 8403928aee4356845252ac6b662d5c72c29903813eJake Slack { 8503928aee4356845252ac6b662d5c72c29903813eJake Slack public void matched(URI uri) throws Exception 8603928aee4356845252ac6b662d5c72c29903813eJake Slack { 8703928aee4356845252ac6b662d5c72c29903813eJake Slack context.getMetaData().addContainerJar(Resource.newResource(uri)); 8803928aee4356845252ac6b662d5c72c29903813eJake Slack } 8903928aee4356845252ac6b662d5c72c29903813eJake Slack }; 9003928aee4356845252ac6b662d5c72c29903813eJake Slack ClassLoader loader = null; 9103928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getClassLoader() != null) 9203928aee4356845252ac6b662d5c72c29903813eJake Slack loader = context.getClassLoader().getParent(); 9303928aee4356845252ac6b662d5c72c29903813eJake Slack 9403928aee4356845252ac6b662d5c72c29903813eJake Slack while (loader != null && (loader instanceof URLClassLoader)) 9503928aee4356845252ac6b662d5c72c29903813eJake Slack { 9603928aee4356845252ac6b662d5c72c29903813eJake Slack URL[] urls = ((URLClassLoader)loader).getURLs(); 9703928aee4356845252ac6b662d5c72c29903813eJake Slack if (urls != null) 9803928aee4356845252ac6b662d5c72c29903813eJake Slack { 9903928aee4356845252ac6b662d5c72c29903813eJake Slack URI[] containerUris = new URI[urls.length]; 10003928aee4356845252ac6b662d5c72c29903813eJake Slack int i=0; 10103928aee4356845252ac6b662d5c72c29903813eJake Slack for (URL u : urls) 10203928aee4356845252ac6b662d5c72c29903813eJake Slack { 10303928aee4356845252ac6b662d5c72c29903813eJake Slack try 10403928aee4356845252ac6b662d5c72c29903813eJake Slack { 10503928aee4356845252ac6b662d5c72c29903813eJake Slack containerUris[i] = u.toURI(); 10603928aee4356845252ac6b662d5c72c29903813eJake Slack } 10703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (URISyntaxException e) 10803928aee4356845252ac6b662d5c72c29903813eJake Slack { 10903928aee4356845252ac6b662d5c72c29903813eJake Slack containerUris[i] = new URI(u.toString().replaceAll(" ", "%20")); 11003928aee4356845252ac6b662d5c72c29903813eJake Slack } 11103928aee4356845252ac6b662d5c72c29903813eJake Slack i++; 11203928aee4356845252ac6b662d5c72c29903813eJake Slack } 11303928aee4356845252ac6b662d5c72c29903813eJake Slack containerJarNameMatcher.match(containerPattern, containerUris, false); 11403928aee4356845252ac6b662d5c72c29903813eJake Slack } 11503928aee4356845252ac6b662d5c72c29903813eJake Slack loader = loader.getParent(); 11603928aee4356845252ac6b662d5c72c29903813eJake Slack } 11703928aee4356845252ac6b662d5c72c29903813eJake Slack 11803928aee4356845252ac6b662d5c72c29903813eJake Slack //Apply ordering to WEB-INF/lib jars 11903928aee4356845252ac6b662d5c72c29903813eJake Slack PatternMatcher webInfJarNameMatcher = new PatternMatcher () 12003928aee4356845252ac6b662d5c72c29903813eJake Slack { 12103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 12203928aee4356845252ac6b662d5c72c29903813eJake Slack public void matched(URI uri) throws Exception 12303928aee4356845252ac6b662d5c72c29903813eJake Slack { 12403928aee4356845252ac6b662d5c72c29903813eJake Slack context.getMetaData().addWebInfJar(Resource.newResource(uri)); 12503928aee4356845252ac6b662d5c72c29903813eJake Slack } 12603928aee4356845252ac6b662d5c72c29903813eJake Slack }; 12703928aee4356845252ac6b662d5c72c29903813eJake Slack List<Resource> jars = findJars(context); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack 12903928aee4356845252ac6b662d5c72c29903813eJake Slack //Convert to uris for matching 13003928aee4356845252ac6b662d5c72c29903813eJake Slack URI[] uris = null; 13103928aee4356845252ac6b662d5c72c29903813eJake Slack if (jars != null) 13203928aee4356845252ac6b662d5c72c29903813eJake Slack { 13303928aee4356845252ac6b662d5c72c29903813eJake Slack uris = new URI[jars.size()]; 13403928aee4356845252ac6b662d5c72c29903813eJake Slack int i=0; 13503928aee4356845252ac6b662d5c72c29903813eJake Slack for (Resource r: jars) 13603928aee4356845252ac6b662d5c72c29903813eJake Slack { 13703928aee4356845252ac6b662d5c72c29903813eJake Slack uris[i++] = r.getURI(); 13803928aee4356845252ac6b662d5c72c29903813eJake Slack } 13903928aee4356845252ac6b662d5c72c29903813eJake Slack } 14003928aee4356845252ac6b662d5c72c29903813eJake Slack webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match 14103928aee4356845252ac6b662d5c72c29903813eJake Slack } 14203928aee4356845252ac6b662d5c72c29903813eJake Slack 14303928aee4356845252ac6b662d5c72c29903813eJake Slack 14403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 14503928aee4356845252ac6b662d5c72c29903813eJake Slack public void configure(WebAppContext context) throws Exception 14603928aee4356845252ac6b662d5c72c29903813eJake Slack { 14703928aee4356845252ac6b662d5c72c29903813eJake Slack //cannot configure if the context is already started 14803928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.isStarted()) 14903928aee4356845252ac6b662d5c72c29903813eJake Slack { 15003928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 15103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Cannot configure webapp "+context+" after it is started"); 15203928aee4356845252ac6b662d5c72c29903813eJake Slack return; 15303928aee4356845252ac6b662d5c72c29903813eJake Slack } 15403928aee4356845252ac6b662d5c72c29903813eJake Slack 15503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf = context.getWebInf(); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack 15703928aee4356845252ac6b662d5c72c29903813eJake Slack // Add WEB-INF classes and lib classpaths 15803928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf != null && web_inf.isDirectory() && context.getClassLoader() instanceof WebAppClassLoader) 15903928aee4356845252ac6b662d5c72c29903813eJake Slack { 16003928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for classes directory 16103928aee4356845252ac6b662d5c72c29903813eJake Slack Resource classes= web_inf.addPath("classes/"); 16203928aee4356845252ac6b662d5c72c29903813eJake Slack if (classes.exists()) 16303928aee4356845252ac6b662d5c72c29903813eJake Slack ((WebAppClassLoader)context.getClassLoader()).addClassPath(classes); 16403928aee4356845252ac6b662d5c72c29903813eJake Slack 16503928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for jars 16603928aee4356845252ac6b662d5c72c29903813eJake Slack Resource lib= web_inf.addPath("lib/"); 16703928aee4356845252ac6b662d5c72c29903813eJake Slack if (lib.exists() || lib.isDirectory()) 16803928aee4356845252ac6b662d5c72c29903813eJake Slack ((WebAppClassLoader)context.getClassLoader()).addJars(lib); 16903928aee4356845252ac6b662d5c72c29903813eJake Slack } 17003928aee4356845252ac6b662d5c72c29903813eJake Slack 17103928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for extra resource 17203928aee4356845252ac6b662d5c72c29903813eJake Slack @SuppressWarnings("unchecked") 17303928aee4356845252ac6b662d5c72c29903813eJake Slack List<Resource> resources = (List<Resource>)context.getAttribute(RESOURCE_URLS); 17403928aee4356845252ac6b662d5c72c29903813eJake Slack if (resources!=null) 17503928aee4356845252ac6b662d5c72c29903813eJake Slack { 17603928aee4356845252ac6b662d5c72c29903813eJake Slack Resource[] collection=new Resource[resources.size()+1]; 17703928aee4356845252ac6b662d5c72c29903813eJake Slack int i=0; 17803928aee4356845252ac6b662d5c72c29903813eJake Slack collection[i++]=context.getBaseResource(); 17903928aee4356845252ac6b662d5c72c29903813eJake Slack for (Resource resource : resources) 18003928aee4356845252ac6b662d5c72c29903813eJake Slack collection[i++]=resource; 18103928aee4356845252ac6b662d5c72c29903813eJake Slack context.setBaseResource(new ResourceCollection(collection)); 18203928aee4356845252ac6b662d5c72c29903813eJake Slack } 18303928aee4356845252ac6b662d5c72c29903813eJake Slack } 18403928aee4356845252ac6b662d5c72c29903813eJake Slack 18503928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 18603928aee4356845252ac6b662d5c72c29903813eJake Slack public void deconfigure(WebAppContext context) throws Exception 18703928aee4356845252ac6b662d5c72c29903813eJake Slack { 18803928aee4356845252ac6b662d5c72c29903813eJake Slack // delete temp directory if we had to create it or if it isn't called work 18903928aee4356845252ac6b662d5c72c29903813eJake Slack Boolean tmpdirConfigured = (Boolean)context.getAttribute(TEMPDIR_CONFIGURED); 19003928aee4356845252ac6b662d5c72c29903813eJake Slack 19103928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getTempDirectory()!=null && (tmpdirConfigured == null || !tmpdirConfigured.booleanValue()) && !isTempWorkDirectory(context.getTempDirectory())) 19203928aee4356845252ac6b662d5c72c29903813eJake Slack { 19303928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(context.getTempDirectory()); 19403928aee4356845252ac6b662d5c72c29903813eJake Slack context.setTempDirectory(null); 19503928aee4356845252ac6b662d5c72c29903813eJake Slack 19603928aee4356845252ac6b662d5c72c29903813eJake Slack //clear out the context attributes for the tmp dir only if we had to 19703928aee4356845252ac6b662d5c72c29903813eJake Slack //create the tmp dir 19803928aee4356845252ac6b662d5c72c29903813eJake Slack context.setAttribute(TEMPDIR_CONFIGURED, null); 19903928aee4356845252ac6b662d5c72c29903813eJake Slack context.setAttribute(WebAppContext.TEMPDIR, null); 20003928aee4356845252ac6b662d5c72c29903813eJake Slack } 20103928aee4356845252ac6b662d5c72c29903813eJake Slack 20203928aee4356845252ac6b662d5c72c29903813eJake Slack 20303928aee4356845252ac6b662d5c72c29903813eJake Slack //reset the base resource back to what it was before we did any unpacking of resources 20403928aee4356845252ac6b662d5c72c29903813eJake Slack context.setBaseResource(_preUnpackBaseResource); 20503928aee4356845252ac6b662d5c72c29903813eJake Slack } 20603928aee4356845252ac6b662d5c72c29903813eJake Slack 20703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 20803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 20903928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.webapp.AbstractConfiguration#cloneConfigure(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.WebAppContext) 21003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 21103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 21203928aee4356845252ac6b662d5c72c29903813eJake Slack public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception 21303928aee4356845252ac6b662d5c72c29903813eJake Slack { 21403928aee4356845252ac6b662d5c72c29903813eJake Slack File tmpDir=File.createTempFile(WebInfConfiguration.getCanonicalNameForWebAppTmpDir(context),"",template.getTempDirectory().getParentFile()); 21503928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir.exists()) 21603928aee4356845252ac6b662d5c72c29903813eJake Slack { 21703928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(tmpDir); 21803928aee4356845252ac6b662d5c72c29903813eJake Slack } 21903928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir.mkdir(); 22003928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir.deleteOnExit(); 22103928aee4356845252ac6b662d5c72c29903813eJake Slack context.setTempDirectory(tmpDir); 22203928aee4356845252ac6b662d5c72c29903813eJake Slack } 22303928aee4356845252ac6b662d5c72c29903813eJake Slack 22403928aee4356845252ac6b662d5c72c29903813eJake Slack 22503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 22603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 22703928aee4356845252ac6b662d5c72c29903813eJake Slack * Get a temporary directory in which to unpack the war etc etc. 22803928aee4356845252ac6b662d5c72c29903813eJake Slack * The algorithm for determining this is to check these alternatives 22903928aee4356845252ac6b662d5c72c29903813eJake Slack * in the order shown: 23003928aee4356845252ac6b662d5c72c29903813eJake Slack * 23103928aee4356845252ac6b662d5c72c29903813eJake Slack * <p>A. Try to use an explicit directory specifically for this webapp:</p> 23203928aee4356845252ac6b662d5c72c29903813eJake Slack * <ol> 23303928aee4356845252ac6b662d5c72c29903813eJake Slack * <li> 23403928aee4356845252ac6b662d5c72c29903813eJake Slack * Iff an explicit directory is set for this webapp, use it. Do NOT set 23503928aee4356845252ac6b662d5c72c29903813eJake Slack * delete on exit. 23603928aee4356845252ac6b662d5c72c29903813eJake Slack * </li> 23703928aee4356845252ac6b662d5c72c29903813eJake Slack * <li> 23803928aee4356845252ac6b662d5c72c29903813eJake Slack * Iff javax.servlet.context.tempdir context attribute is set for 23903928aee4356845252ac6b662d5c72c29903813eJake Slack * this webapp && exists && writeable, then use it. Do NOT set delete on exit. 24003928aee4356845252ac6b662d5c72c29903813eJake Slack * </li> 24103928aee4356845252ac6b662d5c72c29903813eJake Slack * </ol> 24203928aee4356845252ac6b662d5c72c29903813eJake Slack * 24303928aee4356845252ac6b662d5c72c29903813eJake Slack * <p>B. Create a directory based on global settings. The new directory 24403928aee4356845252ac6b662d5c72c29903813eJake Slack * will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost 24503928aee4356845252ac6b662d5c72c29903813eJake Slack * Work out where to create this directory: 24603928aee4356845252ac6b662d5c72c29903813eJake Slack * <ol> 24703928aee4356845252ac6b662d5c72c29903813eJake Slack * <li> 24803928aee4356845252ac6b662d5c72c29903813eJake Slack * Iff $(jetty.home)/work exists create the directory there. Do NOT 24903928aee4356845252ac6b662d5c72c29903813eJake Slack * set delete on exit. Do NOT delete contents if dir already exists. 25003928aee4356845252ac6b662d5c72c29903813eJake Slack * </li> 25103928aee4356845252ac6b662d5c72c29903813eJake Slack * <li> 25203928aee4356845252ac6b662d5c72c29903813eJake Slack * Iff WEB-INF/work exists create the directory there. Do NOT set 25303928aee4356845252ac6b662d5c72c29903813eJake Slack * delete on exit. Do NOT delete contents if dir already exists. 25403928aee4356845252ac6b662d5c72c29903813eJake Slack * </li> 25503928aee4356845252ac6b662d5c72c29903813eJake Slack * <li> 25603928aee4356845252ac6b662d5c72c29903813eJake Slack * Else create dir in $(java.io.tmpdir). Set delete on exit. Delete 25703928aee4356845252ac6b662d5c72c29903813eJake Slack * contents if dir already exists. 25803928aee4356845252ac6b662d5c72c29903813eJake Slack * </li> 25903928aee4356845252ac6b662d5c72c29903813eJake Slack * </ol> 26003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 26103928aee4356845252ac6b662d5c72c29903813eJake Slack public void resolveTempDirectory (WebAppContext context) 26203928aee4356845252ac6b662d5c72c29903813eJake Slack { 26303928aee4356845252ac6b662d5c72c29903813eJake Slack //If a tmp directory is already set, we're done 26403928aee4356845252ac6b662d5c72c29903813eJake Slack File tmpDir = context.getTempDirectory(); 26503928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir != null && tmpDir.isDirectory() && tmpDir.canWrite()) 26603928aee4356845252ac6b662d5c72c29903813eJake Slack { 26703928aee4356845252ac6b662d5c72c29903813eJake Slack context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE); 26803928aee4356845252ac6b662d5c72c29903813eJake Slack return; // Already have a suitable tmp dir configured 26903928aee4356845252ac6b662d5c72c29903813eJake Slack } 27003928aee4356845252ac6b662d5c72c29903813eJake Slack 27103928aee4356845252ac6b662d5c72c29903813eJake Slack 27203928aee4356845252ac6b662d5c72c29903813eJake Slack // No temp directory configured, try to establish one. 27303928aee4356845252ac6b662d5c72c29903813eJake Slack // First we check the context specific, javax.servlet specified, temp directory attribute 27403928aee4356845252ac6b662d5c72c29903813eJake Slack File servletTmpDir = asFile(context.getAttribute(WebAppContext.TEMPDIR)); 27503928aee4356845252ac6b662d5c72c29903813eJake Slack if (servletTmpDir != null && servletTmpDir.isDirectory() && servletTmpDir.canWrite()) 27603928aee4356845252ac6b662d5c72c29903813eJake Slack { 27703928aee4356845252ac6b662d5c72c29903813eJake Slack // Use as tmpDir 27803928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir = servletTmpDir; 27903928aee4356845252ac6b662d5c72c29903813eJake Slack // Ensure Attribute has File object 28003928aee4356845252ac6b662d5c72c29903813eJake Slack context.setAttribute(WebAppContext.TEMPDIR,tmpDir); 28103928aee4356845252ac6b662d5c72c29903813eJake Slack // Set as TempDir in context. 28203928aee4356845252ac6b662d5c72c29903813eJake Slack context.setTempDirectory(tmpDir); 28303928aee4356845252ac6b662d5c72c29903813eJake Slack return; 28403928aee4356845252ac6b662d5c72c29903813eJake Slack } 28503928aee4356845252ac6b662d5c72c29903813eJake Slack 28603928aee4356845252ac6b662d5c72c29903813eJake Slack try 28703928aee4356845252ac6b662d5c72c29903813eJake Slack { 28803928aee4356845252ac6b662d5c72c29903813eJake Slack // Put the tmp dir in the work directory if we had one 28903928aee4356845252ac6b662d5c72c29903813eJake Slack File work = new File(System.getProperty("jetty.home"),"work"); 29003928aee4356845252ac6b662d5c72c29903813eJake Slack if (work.exists() && work.canWrite() && work.isDirectory()) 29103928aee4356845252ac6b662d5c72c29903813eJake Slack { 29203928aee4356845252ac6b662d5c72c29903813eJake Slack makeTempDirectory(work, context, false); //make a tmp dir inside work, don't delete if it exists 29303928aee4356845252ac6b662d5c72c29903813eJake Slack } 29403928aee4356845252ac6b662d5c72c29903813eJake Slack else 29503928aee4356845252ac6b662d5c72c29903813eJake Slack { 29603928aee4356845252ac6b662d5c72c29903813eJake Slack File baseTemp = asFile(context.getAttribute(WebAppContext.BASETEMPDIR)); 29703928aee4356845252ac6b662d5c72c29903813eJake Slack if (baseTemp != null && baseTemp.isDirectory() && baseTemp.canWrite()) 29803928aee4356845252ac6b662d5c72c29903813eJake Slack { 29903928aee4356845252ac6b662d5c72c29903813eJake Slack // Use baseTemp directory (allow the funky Jetty_0_0_0_0.. subdirectory logic to kick in 30003928aee4356845252ac6b662d5c72c29903813eJake Slack makeTempDirectory(baseTemp,context,false); 30103928aee4356845252ac6b662d5c72c29903813eJake Slack } 30203928aee4356845252ac6b662d5c72c29903813eJake Slack else 30303928aee4356845252ac6b662d5c72c29903813eJake Slack { 30403928aee4356845252ac6b662d5c72c29903813eJake Slack makeTempDirectory(new File(System.getProperty("java.io.tmpdir")),context,true); //make a tmpdir, delete if it already exists 30503928aee4356845252ac6b662d5c72c29903813eJake Slack } 30603928aee4356845252ac6b662d5c72c29903813eJake Slack } 30703928aee4356845252ac6b662d5c72c29903813eJake Slack } 30803928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 30903928aee4356845252ac6b662d5c72c29903813eJake Slack { 31003928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir=null; 31103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 31203928aee4356845252ac6b662d5c72c29903813eJake Slack } 31303928aee4356845252ac6b662d5c72c29903813eJake Slack 31403928aee4356845252ac6b662d5c72c29903813eJake Slack //Third ... Something went wrong trying to make the tmp directory, just make 31503928aee4356845252ac6b662d5c72c29903813eJake Slack //a jvm managed tmp directory 31603928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getTempDirectory() == null) 31703928aee4356845252ac6b662d5c72c29903813eJake Slack { 31803928aee4356845252ac6b662d5c72c29903813eJake Slack try 31903928aee4356845252ac6b662d5c72c29903813eJake Slack { 32003928aee4356845252ac6b662d5c72c29903813eJake Slack // Last resort 32103928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir=File.createTempFile("JettyContext",""); 32203928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir.exists()) 32303928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(tmpDir); 32403928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir.mkdir(); 32503928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir.deleteOnExit(); 32603928aee4356845252ac6b662d5c72c29903813eJake Slack context.setTempDirectory(tmpDir); 32703928aee4356845252ac6b662d5c72c29903813eJake Slack } 32803928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 32903928aee4356845252ac6b662d5c72c29903813eJake Slack { 33003928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir = null; 33103928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("Cannot create tmp dir in "+System.getProperty("java.io.tmpdir")+ " for context "+context,e); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack } 33303928aee4356845252ac6b662d5c72c29903813eJake Slack } 33403928aee4356845252ac6b662d5c72c29903813eJake Slack } 33503928aee4356845252ac6b662d5c72c29903813eJake Slack 33603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 33703928aee4356845252ac6b662d5c72c29903813eJake Slack * Given an Object, return File reference for object. 33803928aee4356845252ac6b662d5c72c29903813eJake Slack * Typically used to convert anonymous Object from getAttribute() calls to a File object. 33903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param fileattr the file attribute to analyze and return from (supports type File and type String, all others return null) 34003928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the File object, null if null, or null if not a File or String 34103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 34203928aee4356845252ac6b662d5c72c29903813eJake Slack private File asFile(Object fileattr) 34303928aee4356845252ac6b662d5c72c29903813eJake Slack { 34403928aee4356845252ac6b662d5c72c29903813eJake Slack if (fileattr == null) 34503928aee4356845252ac6b662d5c72c29903813eJake Slack { 34603928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 34703928aee4356845252ac6b662d5c72c29903813eJake Slack } 34803928aee4356845252ac6b662d5c72c29903813eJake Slack if (fileattr instanceof File) 34903928aee4356845252ac6b662d5c72c29903813eJake Slack { 35003928aee4356845252ac6b662d5c72c29903813eJake Slack return (File)fileattr; 35103928aee4356845252ac6b662d5c72c29903813eJake Slack } 35203928aee4356845252ac6b662d5c72c29903813eJake Slack if (fileattr instanceof String) 35303928aee4356845252ac6b662d5c72c29903813eJake Slack { 35403928aee4356845252ac6b662d5c72c29903813eJake Slack return new File((String)fileattr); 35503928aee4356845252ac6b662d5c72c29903813eJake Slack } 35603928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 35703928aee4356845252ac6b662d5c72c29903813eJake Slack } 35803928aee4356845252ac6b662d5c72c29903813eJake Slack 35903928aee4356845252ac6b662d5c72c29903813eJake Slack 36003928aee4356845252ac6b662d5c72c29903813eJake Slack 36103928aee4356845252ac6b662d5c72c29903813eJake Slack public void makeTempDirectory (File parent, WebAppContext context, boolean deleteExisting) 36203928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 36303928aee4356845252ac6b662d5c72c29903813eJake Slack { 36403928aee4356845252ac6b662d5c72c29903813eJake Slack if (parent != null && parent.exists() && parent.canWrite() && parent.isDirectory()) 36503928aee4356845252ac6b662d5c72c29903813eJake Slack { 36603928aee4356845252ac6b662d5c72c29903813eJake Slack String temp = getCanonicalNameForWebAppTmpDir(context); 36703928aee4356845252ac6b662d5c72c29903813eJake Slack File tmpDir = new File(parent,temp); 36803928aee4356845252ac6b662d5c72c29903813eJake Slack 36903928aee4356845252ac6b662d5c72c29903813eJake Slack if (deleteExisting && tmpDir.exists()) 37003928aee4356845252ac6b662d5c72c29903813eJake Slack { 37103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!IO.delete(tmpDir)) 37203928aee4356845252ac6b662d5c72c29903813eJake Slack { 37303928aee4356845252ac6b662d5c72c29903813eJake Slack if(LOG.isDebugEnabled())LOG.debug("Failed to delete temp dir "+tmpDir); 37403928aee4356845252ac6b662d5c72c29903813eJake Slack } 37503928aee4356845252ac6b662d5c72c29903813eJake Slack 37603928aee4356845252ac6b662d5c72c29903813eJake Slack //If we can't delete the existing tmp dir, create a new one 37703928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir.exists()) 37803928aee4356845252ac6b662d5c72c29903813eJake Slack { 37903928aee4356845252ac6b662d5c72c29903813eJake Slack String old=tmpDir.toString(); 38003928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir=File.createTempFile(temp+"_",""); 38103928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir.exists()) 38203928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(tmpDir); 38303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Can't reuse "+old+", using "+tmpDir); 38403928aee4356845252ac6b662d5c72c29903813eJake Slack } 38503928aee4356845252ac6b662d5c72c29903813eJake Slack } 38603928aee4356845252ac6b662d5c72c29903813eJake Slack 38703928aee4356845252ac6b662d5c72c29903813eJake Slack if (!tmpDir.exists()) 38803928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir.mkdir(); 38903928aee4356845252ac6b662d5c72c29903813eJake Slack 39003928aee4356845252ac6b662d5c72c29903813eJake Slack //If the parent is not a work directory 39103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!isTempWorkDirectory(tmpDir)) 39203928aee4356845252ac6b662d5c72c29903813eJake Slack { 39303928aee4356845252ac6b662d5c72c29903813eJake Slack tmpDir.deleteOnExit(); 39403928aee4356845252ac6b662d5c72c29903813eJake Slack } 39503928aee4356845252ac6b662d5c72c29903813eJake Slack 39603928aee4356845252ac6b662d5c72c29903813eJake Slack if(LOG.isDebugEnabled()) 39703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Set temp dir "+tmpDir); 39803928aee4356845252ac6b662d5c72c29903813eJake Slack context.setTempDirectory(tmpDir); 39903928aee4356845252ac6b662d5c72c29903813eJake Slack } 40003928aee4356845252ac6b662d5c72c29903813eJake Slack } 40103928aee4356845252ac6b662d5c72c29903813eJake Slack 40203928aee4356845252ac6b662d5c72c29903813eJake Slack 40303928aee4356845252ac6b662d5c72c29903813eJake Slack public void unpack (WebAppContext context) throws IOException 40403928aee4356845252ac6b662d5c72c29903813eJake Slack { 40503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_app = context.getBaseResource(); 40603928aee4356845252ac6b662d5c72c29903813eJake Slack _preUnpackBaseResource = context.getBaseResource(); 40703928aee4356845252ac6b662d5c72c29903813eJake Slack 40803928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_app == null) 40903928aee4356845252ac6b662d5c72c29903813eJake Slack { 41003928aee4356845252ac6b662d5c72c29903813eJake Slack String war = context.getWar(); 41103928aee4356845252ac6b662d5c72c29903813eJake Slack if (war!=null && war.length()>0) 41203928aee4356845252ac6b662d5c72c29903813eJake Slack web_app = context.newResource(war); 41303928aee4356845252ac6b662d5c72c29903813eJake Slack else 41403928aee4356845252ac6b662d5c72c29903813eJake Slack web_app=context.getBaseResource(); 41503928aee4356845252ac6b662d5c72c29903813eJake Slack 41603928aee4356845252ac6b662d5c72c29903813eJake Slack // Accept aliases for WAR files 41703928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_app.getAlias() != null) 41803928aee4356845252ac6b662d5c72c29903813eJake Slack { 41903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug(web_app + " anti-aliased to " + web_app.getAlias()); 42003928aee4356845252ac6b662d5c72c29903813eJake Slack web_app = context.newResource(web_app.getAlias()); 42103928aee4356845252ac6b662d5c72c29903813eJake Slack } 42203928aee4356845252ac6b662d5c72c29903813eJake Slack 42303928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 42403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()+" file="+(web_app.getFile())); 42503928aee4356845252ac6b662d5c72c29903813eJake Slack // Is the WAR usable directly? 42603928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:")) 42703928aee4356845252ac6b662d5c72c29903813eJake Slack { 42803928aee4356845252ac6b662d5c72c29903813eJake Slack // No - then lets see if it can be turned into a jar URL. 42903928aee4356845252ac6b662d5c72c29903813eJake Slack Resource jarWebApp = JarResource.newJarResource(web_app); 43003928aee4356845252ac6b662d5c72c29903813eJake Slack if (jarWebApp.exists() && jarWebApp.isDirectory()) 43103928aee4356845252ac6b662d5c72c29903813eJake Slack web_app= jarWebApp; 43203928aee4356845252ac6b662d5c72c29903813eJake Slack } 43303928aee4356845252ac6b662d5c72c29903813eJake Slack 43403928aee4356845252ac6b662d5c72c29903813eJake Slack // If we should extract or the URL is still not usable 43503928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_app.exists() && ( 43603928aee4356845252ac6b662d5c72c29903813eJake Slack (context.isCopyWebDir() && web_app.getFile() != null && web_app.getFile().isDirectory()) || 43703928aee4356845252ac6b662d5c72c29903813eJake Slack (context.isExtractWAR() && web_app.getFile() != null && !web_app.getFile().isDirectory()) || 43803928aee4356845252ac6b662d5c72c29903813eJake Slack (context.isExtractWAR() && web_app.getFile() == null) || 43903928aee4356845252ac6b662d5c72c29903813eJake Slack !web_app.isDirectory()) 44003928aee4356845252ac6b662d5c72c29903813eJake Slack ) 44103928aee4356845252ac6b662d5c72c29903813eJake Slack { 44203928aee4356845252ac6b662d5c72c29903813eJake Slack // Look for sibling directory. 44303928aee4356845252ac6b662d5c72c29903813eJake Slack File extractedWebAppDir = null; 44403928aee4356845252ac6b662d5c72c29903813eJake Slack 44503928aee4356845252ac6b662d5c72c29903813eJake Slack if (war!=null) 44603928aee4356845252ac6b662d5c72c29903813eJake Slack { 44703928aee4356845252ac6b662d5c72c29903813eJake Slack // look for a sibling like "foo/" to a "foo.war" 44803928aee4356845252ac6b662d5c72c29903813eJake Slack File warfile=Resource.newResource(war).getFile(); 44903928aee4356845252ac6b662d5c72c29903813eJake Slack if (warfile!=null && warfile.getName().toLowerCase(Locale.ENGLISH).endsWith(".war")) 45003928aee4356845252ac6b662d5c72c29903813eJake Slack { 45103928aee4356845252ac6b662d5c72c29903813eJake Slack File sibling = new File(warfile.getParent(),warfile.getName().substring(0,warfile.getName().length()-4)); 45203928aee4356845252ac6b662d5c72c29903813eJake Slack if (sibling.exists() && sibling.isDirectory() && sibling.canWrite()) 45303928aee4356845252ac6b662d5c72c29903813eJake Slack extractedWebAppDir=sibling; 45403928aee4356845252ac6b662d5c72c29903813eJake Slack } 45503928aee4356845252ac6b662d5c72c29903813eJake Slack } 45603928aee4356845252ac6b662d5c72c29903813eJake Slack 45703928aee4356845252ac6b662d5c72c29903813eJake Slack if (extractedWebAppDir==null) 45803928aee4356845252ac6b662d5c72c29903813eJake Slack // Then extract it if necessary to the temporary location 45903928aee4356845252ac6b662d5c72c29903813eJake Slack extractedWebAppDir= new File(context.getTempDirectory(), "webapp"); 46003928aee4356845252ac6b662d5c72c29903813eJake Slack 46103928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_app.getFile()!=null && web_app.getFile().isDirectory()) 46203928aee4356845252ac6b662d5c72c29903813eJake Slack { 46303928aee4356845252ac6b662d5c72c29903813eJake Slack // Copy directory 46403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.info("Copy " + web_app + " to " + extractedWebAppDir); 46503928aee4356845252ac6b662d5c72c29903813eJake Slack web_app.copyTo(extractedWebAppDir); 46603928aee4356845252ac6b662d5c72c29903813eJake Slack } 46703928aee4356845252ac6b662d5c72c29903813eJake Slack else 46803928aee4356845252ac6b662d5c72c29903813eJake Slack { 46903928aee4356845252ac6b662d5c72c29903813eJake Slack //Use a sentinel file that will exist only whilst the extraction is taking place. 47003928aee4356845252ac6b662d5c72c29903813eJake Slack //This will help us detect interrupted extractions. 47103928aee4356845252ac6b662d5c72c29903813eJake Slack File extractionLock = new File (context.getTempDirectory(), ".extract_lock"); 47203928aee4356845252ac6b662d5c72c29903813eJake Slack 47303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!extractedWebAppDir.exists()) 47403928aee4356845252ac6b662d5c72c29903813eJake Slack { 47503928aee4356845252ac6b662d5c72c29903813eJake Slack //it hasn't been extracted before so extract it 47603928aee4356845252ac6b662d5c72c29903813eJake Slack extractionLock.createNewFile(); 47703928aee4356845252ac6b662d5c72c29903813eJake Slack extractedWebAppDir.mkdir(); 47803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.info("Extract " + web_app + " to " + extractedWebAppDir); 47903928aee4356845252ac6b662d5c72c29903813eJake Slack Resource jar_web_app = JarResource.newJarResource(web_app); 48003928aee4356845252ac6b662d5c72c29903813eJake Slack jar_web_app.copyTo(extractedWebAppDir); 48103928aee4356845252ac6b662d5c72c29903813eJake Slack extractionLock.delete(); 48203928aee4356845252ac6b662d5c72c29903813eJake Slack } 48303928aee4356845252ac6b662d5c72c29903813eJake Slack else 48403928aee4356845252ac6b662d5c72c29903813eJake Slack { 48503928aee4356845252ac6b662d5c72c29903813eJake Slack //only extract if the war file is newer, or a .extract_lock file is left behind meaning a possible partial extraction 48603928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_app.lastModified() > extractedWebAppDir.lastModified() || extractionLock.exists()) 48703928aee4356845252ac6b662d5c72c29903813eJake Slack { 48803928aee4356845252ac6b662d5c72c29903813eJake Slack extractionLock.createNewFile(); 48903928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(extractedWebAppDir); 49003928aee4356845252ac6b662d5c72c29903813eJake Slack extractedWebAppDir.mkdir(); 49103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.info("Extract " + web_app + " to " + extractedWebAppDir); 49203928aee4356845252ac6b662d5c72c29903813eJake Slack Resource jar_web_app = JarResource.newJarResource(web_app); 49303928aee4356845252ac6b662d5c72c29903813eJake Slack jar_web_app.copyTo(extractedWebAppDir); 49403928aee4356845252ac6b662d5c72c29903813eJake Slack extractionLock.delete(); 49503928aee4356845252ac6b662d5c72c29903813eJake Slack } 49603928aee4356845252ac6b662d5c72c29903813eJake Slack } 49703928aee4356845252ac6b662d5c72c29903813eJake Slack } 49803928aee4356845252ac6b662d5c72c29903813eJake Slack web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath()); 49903928aee4356845252ac6b662d5c72c29903813eJake Slack } 50003928aee4356845252ac6b662d5c72c29903813eJake Slack 50103928aee4356845252ac6b662d5c72c29903813eJake Slack // Now do we have something usable? 50203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!web_app.exists() || !web_app.isDirectory()) 50303928aee4356845252ac6b662d5c72c29903813eJake Slack { 50403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Web application not found " + war); 50503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new java.io.FileNotFoundException(war); 50603928aee4356845252ac6b662d5c72c29903813eJake Slack } 50703928aee4356845252ac6b662d5c72c29903813eJake Slack 50803928aee4356845252ac6b662d5c72c29903813eJake Slack context.setBaseResource(web_app); 50903928aee4356845252ac6b662d5c72c29903813eJake Slack 51003928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 51103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("webapp=" + web_app); 51203928aee4356845252ac6b662d5c72c29903813eJake Slack } 51303928aee4356845252ac6b662d5c72c29903813eJake Slack 51403928aee4356845252ac6b662d5c72c29903813eJake Slack 51503928aee4356845252ac6b662d5c72c29903813eJake Slack // Do we need to extract WEB-INF/lib? 51603928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.isCopyWebInf() && !context.isCopyWebDir()) 51703928aee4356845252ac6b662d5c72c29903813eJake Slack { 51803928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf= web_app.addPath("WEB-INF/"); 51903928aee4356845252ac6b662d5c72c29903813eJake Slack 52003928aee4356845252ac6b662d5c72c29903813eJake Slack File extractedWebInfDir= new File(context.getTempDirectory(), "webinf"); 52103928aee4356845252ac6b662d5c72c29903813eJake Slack if (extractedWebInfDir.exists()) 52203928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(extractedWebInfDir); 52303928aee4356845252ac6b662d5c72c29903813eJake Slack extractedWebInfDir.mkdir(); 52403928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf_lib = web_inf.addPath("lib/"); 52503928aee4356845252ac6b662d5c72c29903813eJake Slack File webInfDir=new File(extractedWebInfDir,"WEB-INF"); 52603928aee4356845252ac6b662d5c72c29903813eJake Slack webInfDir.mkdir(); 52703928aee4356845252ac6b662d5c72c29903813eJake Slack 52803928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf_lib.exists()) 52903928aee4356845252ac6b662d5c72c29903813eJake Slack { 53003928aee4356845252ac6b662d5c72c29903813eJake Slack File webInfLibDir = new File(webInfDir, "lib"); 53103928aee4356845252ac6b662d5c72c29903813eJake Slack if (webInfLibDir.exists()) 53203928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(webInfLibDir); 53303928aee4356845252ac6b662d5c72c29903813eJake Slack webInfLibDir.mkdir(); 53403928aee4356845252ac6b662d5c72c29903813eJake Slack 53503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); 53603928aee4356845252ac6b662d5c72c29903813eJake Slack web_inf_lib.copyTo(webInfLibDir); 53703928aee4356845252ac6b662d5c72c29903813eJake Slack } 53803928aee4356845252ac6b662d5c72c29903813eJake Slack 53903928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf_classes = web_inf.addPath("classes/"); 54003928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf_classes.exists()) 54103928aee4356845252ac6b662d5c72c29903813eJake Slack { 54203928aee4356845252ac6b662d5c72c29903813eJake Slack File webInfClassesDir = new File(webInfDir, "classes"); 54303928aee4356845252ac6b662d5c72c29903813eJake Slack if (webInfClassesDir.exists()) 54403928aee4356845252ac6b662d5c72c29903813eJake Slack IO.delete(webInfClassesDir); 54503928aee4356845252ac6b662d5c72c29903813eJake Slack webInfClassesDir.mkdir(); 54603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.info("Copying WEB-INF/classes from "+web_inf_classes+" to "+webInfClassesDir.getAbsolutePath()); 54703928aee4356845252ac6b662d5c72c29903813eJake Slack web_inf_classes.copyTo(webInfClassesDir); 54803928aee4356845252ac6b662d5c72c29903813eJake Slack } 54903928aee4356845252ac6b662d5c72c29903813eJake Slack 55003928aee4356845252ac6b662d5c72c29903813eJake Slack web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath()); 55103928aee4356845252ac6b662d5c72c29903813eJake Slack 55203928aee4356845252ac6b662d5c72c29903813eJake Slack ResourceCollection rc = new ResourceCollection(web_inf,web_app); 55303928aee4356845252ac6b662d5c72c29903813eJake Slack 55403928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 55503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("context.resourcebase = "+rc); 55603928aee4356845252ac6b662d5c72c29903813eJake Slack 55703928aee4356845252ac6b662d5c72c29903813eJake Slack context.setBaseResource(rc); 55803928aee4356845252ac6b662d5c72c29903813eJake Slack } 55903928aee4356845252ac6b662d5c72c29903813eJake Slack } 56003928aee4356845252ac6b662d5c72c29903813eJake Slack 56103928aee4356845252ac6b662d5c72c29903813eJake Slack 56203928aee4356845252ac6b662d5c72c29903813eJake Slack public File findWorkDirectory (WebAppContext context) throws IOException 56303928aee4356845252ac6b662d5c72c29903813eJake Slack { 56403928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getBaseResource() != null) 56503928aee4356845252ac6b662d5c72c29903813eJake Slack { 56603928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf = context.getWebInf(); 56703928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf !=null && web_inf.exists()) 56803928aee4356845252ac6b662d5c72c29903813eJake Slack { 56903928aee4356845252ac6b662d5c72c29903813eJake Slack return new File(web_inf.getFile(),"work"); 57003928aee4356845252ac6b662d5c72c29903813eJake Slack } 57103928aee4356845252ac6b662d5c72c29903813eJake Slack } 57203928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 57303928aee4356845252ac6b662d5c72c29903813eJake Slack } 57403928aee4356845252ac6b662d5c72c29903813eJake Slack 57503928aee4356845252ac6b662d5c72c29903813eJake Slack 57603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 57703928aee4356845252ac6b662d5c72c29903813eJake Slack * Check if the tmpDir itself is called "work", or if the tmpDir 57803928aee4356845252ac6b662d5c72c29903813eJake Slack * is in a directory called "work". 57903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return true if File is a temporary or work directory 58003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 58103928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isTempWorkDirectory (File tmpDir) 58203928aee4356845252ac6b662d5c72c29903813eJake Slack { 58303928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir == null) 58403928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 58503928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmpDir.getName().equalsIgnoreCase("work")) 58603928aee4356845252ac6b662d5c72c29903813eJake Slack return true; 58703928aee4356845252ac6b662d5c72c29903813eJake Slack File t = tmpDir.getParentFile(); 58803928aee4356845252ac6b662d5c72c29903813eJake Slack if (t == null) 58903928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 59003928aee4356845252ac6b662d5c72c29903813eJake Slack return (t.getName().equalsIgnoreCase("work")); 59103928aee4356845252ac6b662d5c72c29903813eJake Slack } 59203928aee4356845252ac6b662d5c72c29903813eJake Slack 59303928aee4356845252ac6b662d5c72c29903813eJake Slack 59403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 59503928aee4356845252ac6b662d5c72c29903813eJake Slack * Create a canonical name for a webapp temp directory. 59603928aee4356845252ac6b662d5c72c29903813eJake Slack * The form of the name is: 59703928aee4356845252ac6b662d5c72c29903813eJake Slack * <code>"Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string</code> 59803928aee4356845252ac6b662d5c72c29903813eJake Slack * 59903928aee4356845252ac6b662d5c72c29903813eJake Slack * host and port uniquely identify the server 60003928aee4356845252ac6b662d5c72c29903813eJake Slack * context and virtual host uniquely identify the webapp 60103928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the canonical name for the webapp temp directory 60203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 60303928aee4356845252ac6b662d5c72c29903813eJake Slack public static String getCanonicalNameForWebAppTmpDir (WebAppContext context) 60403928aee4356845252ac6b662d5c72c29903813eJake Slack { 60503928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuffer canonicalName = new StringBuffer(); 60603928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("jetty-"); 60703928aee4356845252ac6b662d5c72c29903813eJake Slack 60803928aee4356845252ac6b662d5c72c29903813eJake Slack //get the host and the port from the first connector 60903928aee4356845252ac6b662d5c72c29903813eJake Slack Server server=context.getServer(); 61003928aee4356845252ac6b662d5c72c29903813eJake Slack if (server!=null) 61103928aee4356845252ac6b662d5c72c29903813eJake Slack { 61203928aee4356845252ac6b662d5c72c29903813eJake Slack Connector[] connectors = context.getServer().getConnectors(); 61303928aee4356845252ac6b662d5c72c29903813eJake Slack 61403928aee4356845252ac6b662d5c72c29903813eJake Slack if (connectors.length>0) 61503928aee4356845252ac6b662d5c72c29903813eJake Slack { 61603928aee4356845252ac6b662d5c72c29903813eJake Slack //Get the host 61703928aee4356845252ac6b662d5c72c29903813eJake Slack String host = (connectors==null||connectors[0]==null?"":connectors[0].getHost()); 61803928aee4356845252ac6b662d5c72c29903813eJake Slack if (host == null) 61903928aee4356845252ac6b662d5c72c29903813eJake Slack host = "0.0.0.0"; 62003928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append(host); 62103928aee4356845252ac6b662d5c72c29903813eJake Slack 62203928aee4356845252ac6b662d5c72c29903813eJake Slack //Get the port 62303928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("-"); 62403928aee4356845252ac6b662d5c72c29903813eJake Slack //try getting the real port being listened on 62503928aee4356845252ac6b662d5c72c29903813eJake Slack int port = (connectors==null||connectors[0]==null?0:connectors[0].getLocalPort()); 62603928aee4356845252ac6b662d5c72c29903813eJake Slack //if not available (eg no connectors or connector not started), 62703928aee4356845252ac6b662d5c72c29903813eJake Slack //try getting one that was configured. 62803928aee4356845252ac6b662d5c72c29903813eJake Slack if (port < 0) 62903928aee4356845252ac6b662d5c72c29903813eJake Slack port = connectors[0].getPort(); 63003928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append(port); 63103928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("-"); 63203928aee4356845252ac6b662d5c72c29903813eJake Slack } 63303928aee4356845252ac6b662d5c72c29903813eJake Slack } 63403928aee4356845252ac6b662d5c72c29903813eJake Slack 63503928aee4356845252ac6b662d5c72c29903813eJake Slack 63603928aee4356845252ac6b662d5c72c29903813eJake Slack //Resource base 63703928aee4356845252ac6b662d5c72c29903813eJake Slack try 63803928aee4356845252ac6b662d5c72c29903813eJake Slack { 63903928aee4356845252ac6b662d5c72c29903813eJake Slack Resource resource = context.getBaseResource(); 64003928aee4356845252ac6b662d5c72c29903813eJake Slack if (resource == null) 64103928aee4356845252ac6b662d5c72c29903813eJake Slack { 64203928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getWar()==null || context.getWar().length()==0) 64303928aee4356845252ac6b662d5c72c29903813eJake Slack resource=context.newResource(context.getResourceBase()); 64403928aee4356845252ac6b662d5c72c29903813eJake Slack 64503928aee4356845252ac6b662d5c72c29903813eJake Slack // Set dir or WAR 64603928aee4356845252ac6b662d5c72c29903813eJake Slack resource = context.newResource(context.getWar()); 64703928aee4356845252ac6b662d5c72c29903813eJake Slack } 64803928aee4356845252ac6b662d5c72c29903813eJake Slack 64903928aee4356845252ac6b662d5c72c29903813eJake Slack String tmp = URIUtil.decodePath(resource.getURL().getPath()); 65003928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmp.endsWith("/")) 65103928aee4356845252ac6b662d5c72c29903813eJake Slack tmp = tmp.substring(0, tmp.length()-1); 65203928aee4356845252ac6b662d5c72c29903813eJake Slack if (tmp.endsWith("!")) 65303928aee4356845252ac6b662d5c72c29903813eJake Slack tmp = tmp.substring(0, tmp.length() -1); 65403928aee4356845252ac6b662d5c72c29903813eJake Slack //get just the last part which is the filename 65503928aee4356845252ac6b662d5c72c29903813eJake Slack int i = tmp.lastIndexOf("/"); 65603928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append(tmp.substring(i+1, tmp.length())); 65703928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("-"); 65803928aee4356845252ac6b662d5c72c29903813eJake Slack } 65903928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 66003928aee4356845252ac6b662d5c72c29903813eJake Slack { 66103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Can't generate resourceBase as part of webapp tmp dir name", e); 66203928aee4356845252ac6b662d5c72c29903813eJake Slack } 66303928aee4356845252ac6b662d5c72c29903813eJake Slack 66403928aee4356845252ac6b662d5c72c29903813eJake Slack //Context name 66503928aee4356845252ac6b662d5c72c29903813eJake Slack String contextPath = context.getContextPath(); 66603928aee4356845252ac6b662d5c72c29903813eJake Slack contextPath=contextPath.replace('/','_'); 66703928aee4356845252ac6b662d5c72c29903813eJake Slack contextPath=contextPath.replace('\\','_'); 66803928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append(contextPath); 66903928aee4356845252ac6b662d5c72c29903813eJake Slack 67003928aee4356845252ac6b662d5c72c29903813eJake Slack //Virtual host (if there is one) 67103928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("-"); 67203928aee4356845252ac6b662d5c72c29903813eJake Slack String[] vhosts = context.getVirtualHosts(); 67303928aee4356845252ac6b662d5c72c29903813eJake Slack if (vhosts == null || vhosts.length <= 0) 67403928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("any"); 67503928aee4356845252ac6b662d5c72c29903813eJake Slack else 67603928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append(vhosts[0]); 67703928aee4356845252ac6b662d5c72c29903813eJake Slack 67803928aee4356845252ac6b662d5c72c29903813eJake Slack // sanitize 67903928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;i<canonicalName.length();i++) 68003928aee4356845252ac6b662d5c72c29903813eJake Slack { 68103928aee4356845252ac6b662d5c72c29903813eJake Slack char c=canonicalName.charAt(i); 68203928aee4356845252ac6b662d5c72c29903813eJake Slack if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c)<0) 68303928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.setCharAt(i,'.'); 68403928aee4356845252ac6b662d5c72c29903813eJake Slack } 68503928aee4356845252ac6b662d5c72c29903813eJake Slack 68603928aee4356845252ac6b662d5c72c29903813eJake Slack canonicalName.append("-"); 68703928aee4356845252ac6b662d5c72c29903813eJake Slack return canonicalName.toString(); 68803928aee4356845252ac6b662d5c72c29903813eJake Slack } 68903928aee4356845252ac6b662d5c72c29903813eJake Slack 69003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 69103928aee4356845252ac6b662d5c72c29903813eJake Slack * Look for jars in WEB-INF/lib 69203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param context 69303928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the list of jar resources found within context 69403928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 69503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 69603928aee4356845252ac6b662d5c72c29903813eJake Slack protected List<Resource> findJars (WebAppContext context) 69703928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 69803928aee4356845252ac6b662d5c72c29903813eJake Slack { 69903928aee4356845252ac6b662d5c72c29903813eJake Slack List<Resource> jarResources = new ArrayList<Resource>(); 70003928aee4356845252ac6b662d5c72c29903813eJake Slack 70103928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf = context.getWebInf(); 70203928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf==null || !web_inf.exists()) 70303928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 70403928aee4356845252ac6b662d5c72c29903813eJake Slack 70503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource web_inf_lib = web_inf.addPath("/lib"); 70603928aee4356845252ac6b662d5c72c29903813eJake Slack 70703928aee4356845252ac6b662d5c72c29903813eJake Slack 70803928aee4356845252ac6b662d5c72c29903813eJake Slack if (web_inf_lib.exists() && web_inf_lib.isDirectory()) 70903928aee4356845252ac6b662d5c72c29903813eJake Slack { 71003928aee4356845252ac6b662d5c72c29903813eJake Slack String[] files=web_inf_lib.list(); 71103928aee4356845252ac6b662d5c72c29903813eJake Slack for (int f=0;files!=null && f<files.length;f++) 71203928aee4356845252ac6b662d5c72c29903813eJake Slack { 71303928aee4356845252ac6b662d5c72c29903813eJake Slack try 71403928aee4356845252ac6b662d5c72c29903813eJake Slack { 71503928aee4356845252ac6b662d5c72c29903813eJake Slack Resource file = web_inf_lib.addPath(files[f]); 71603928aee4356845252ac6b662d5c72c29903813eJake Slack String fnlc = file.getName().toLowerCase(Locale.ENGLISH); 71703928aee4356845252ac6b662d5c72c29903813eJake Slack int dot = fnlc.lastIndexOf('.'); 71803928aee4356845252ac6b662d5c72c29903813eJake Slack String extension = (dot < 0 ? null : fnlc.substring(dot)); 71903928aee4356845252ac6b662d5c72c29903813eJake Slack if (extension != null && (extension.equals(".jar") || extension.equals(".zip"))) 72003928aee4356845252ac6b662d5c72c29903813eJake Slack { 72103928aee4356845252ac6b662d5c72c29903813eJake Slack jarResources.add(file); 72203928aee4356845252ac6b662d5c72c29903813eJake Slack } 72303928aee4356845252ac6b662d5c72c29903813eJake Slack } 72403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception ex) 72503928aee4356845252ac6b662d5c72c29903813eJake Slack { 72603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(Log.EXCEPTION,ex); 72703928aee4356845252ac6b662d5c72c29903813eJake Slack } 72803928aee4356845252ac6b662d5c72c29903813eJake Slack } 72903928aee4356845252ac6b662d5c72c29903813eJake Slack } 73003928aee4356845252ac6b662d5c72c29903813eJake Slack return jarResources; 73103928aee4356845252ac6b662d5c72c29903813eJake Slack } 73203928aee4356845252ac6b662d5c72c29903813eJake Slack} 733