Ensure MetaInfConfiguration finds all candidate jars from the container path and also from web-inf, then applies inclusion patterns to them to do an initial ordering. Jetty-8 will modify this ordering based on web-fragment ordering. The list of jars is passed around as a context attribute. The inclusion patterns are specified as context attributes. The ContextDeployer and WebAppDeployer can be configured with context attributes (such as the default inclusion patterns) that are set on every context they deploy. The list of jars are passed around as a List of Resources, and the pattern matching is done based on the URI (ie as a name string) rather than as a jar URL.
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@310 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
0ef6db092a
commit
4675e38841
|
@ -13,6 +13,10 @@
|
|||
|
||||
package org.eclipse.jetty.annotations;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -25,6 +29,7 @@ import org.eclipse.jetty.util.LazyList;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
|
||||
/**
|
||||
* Configuration
|
||||
|
@ -33,8 +38,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
*/
|
||||
public class AnnotationConfiguration extends org.eclipse.jetty.plus.webapp.Configuration
|
||||
{
|
||||
public static final String __web_inf_pattern = "org.eclipse.jetty.server.webapp.WebInfIncludeAnnotationJarPattern";
|
||||
public static final String __container_pattern = "org.eclipse.jetty.server.webapp.ContainerIncludeAnnotationJarPattern";
|
||||
public static final String JAR_RESOURCES = WebInfConfiguration.JAR_RESOURCES;
|
||||
|
||||
|
||||
|
||||
|
@ -89,7 +93,25 @@ public class AnnotationConfiguration extends org.eclipse.jetty.plus.webapp.Confi
|
|||
{
|
||||
//if no pattern for the container path is defined, then by default scan NOTHING
|
||||
Log.debug("Scanning container jars");
|
||||
parseAnnotationsFromJars(context, finder, context.getClassLoader().getParent(), context.getInitParameter(__container_pattern),true, false,
|
||||
|
||||
//Get the container jar uris
|
||||
|
||||
ArrayList<URI> containerCandidateUris = findJars (context.getClassLoader().getParent(), true);
|
||||
|
||||
//Pick out the uris from JAR_RESOURCES that match those uris to be scanned
|
||||
ArrayList<URI> containerUris = new ArrayList<URI>();
|
||||
List<Resource> jarResources = (List<Resource>)context.getAttribute(JAR_RESOURCES);
|
||||
for (Resource r : jarResources)
|
||||
{
|
||||
URI uri = r.getURI();
|
||||
if (containerCandidateUris.contains(uri))
|
||||
{
|
||||
containerUris.add(uri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
finder.find (containerUris.toArray(new URI[containerUris.size()]),
|
||||
new ClassNameResolver ()
|
||||
{
|
||||
public boolean isExcluded (String name)
|
||||
|
@ -114,8 +136,23 @@ public class AnnotationConfiguration extends org.eclipse.jetty.plus.webapp.Confi
|
|||
throws Exception
|
||||
{
|
||||
Log.debug("Scanning WEB-INF/lib jars");
|
||||
//Get the uris of jars on the webapp classloader
|
||||
ArrayList<URI> candidateUris = findJars(context.getClassLoader(), false);
|
||||
|
||||
//Pick out the uris from JAR_RESOURCES that match those to be scanned
|
||||
ArrayList<URI> webInfUris = new ArrayList<URI>();
|
||||
List<Resource> jarResources = (List<Resource>)context.getAttribute(JAR_RESOURCES);
|
||||
for (Resource r : jarResources)
|
||||
{
|
||||
URI uri = r.getURI();
|
||||
if (candidateUris.contains(uri))
|
||||
{
|
||||
webInfUris.add(uri);
|
||||
}
|
||||
}
|
||||
|
||||
//if no pattern for web-inf/lib is defined, then by default scan everything in it
|
||||
parseAnnotationsFromJars (context, finder, context.getClassLoader(), context.getInitParameter(__web_inf_pattern), false, true,
|
||||
finder.find(webInfUris.toArray(new URI[webInfUris.size()]),
|
||||
new ClassNameResolver()
|
||||
{
|
||||
public boolean isExcluded (String name)
|
||||
|
@ -140,37 +177,54 @@ public class AnnotationConfiguration extends org.eclipse.jetty.plus.webapp.Confi
|
|||
throws Exception
|
||||
{
|
||||
Log.debug("Scanning classes in WEB-INF/classes");
|
||||
parseAnnotationsFromDir (context, finder, context.getWebInf().addPath("classes/"),
|
||||
new ClassNameResolver()
|
||||
finder.find(context.getWebInf().addPath("classes/"),
|
||||
new ClassNameResolver()
|
||||
{
|
||||
public boolean isExcluded (String name)
|
||||
{
|
||||
if (context.isSystemClass(name)) return true;
|
||||
if (context.isServerClass(name)) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldOverride (String name)
|
||||
{
|
||||
//looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
|
||||
if (context.isParentLoaderPriority())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ArrayList<URI> findJars (ClassLoader loader, boolean visitParent)
|
||||
{
|
||||
ArrayList<URI> uris = new ArrayList<URI>();
|
||||
|
||||
while (loader != null && (loader instanceof URLClassLoader))
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
{
|
||||
for (URL u : urls)
|
||||
{
|
||||
public boolean isExcluded (String name)
|
||||
try
|
||||
{
|
||||
if (context.isSystemClass(name)) return true;
|
||||
if (context.isServerClass(name)) return false;
|
||||
return false;
|
||||
uris.add(u.toURI());
|
||||
}
|
||||
|
||||
public boolean shouldOverride (String name)
|
||||
catch (Exception e)
|
||||
{
|
||||
//looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
|
||||
if (context.isParentLoaderPriority())
|
||||
return false;
|
||||
return true;
|
||||
Log.warn(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void parseAnnotationsFromJars (final WebAppContext context, final AnnotationFinder finder, final ClassLoader classloader, final String pattern, boolean visitParents, boolean isNullInclusive, ClassNameResolver resolver)
|
||||
throws Exception
|
||||
{
|
||||
finder.find (classloader, visitParents, pattern, isNullInclusive,resolver);
|
||||
}
|
||||
|
||||
public void parseAnnotationsFromDir (final WebAppContext context, final AnnotationFinder finder, final Resource dir, ClassNameResolver resolver)
|
||||
throws Exception
|
||||
{
|
||||
finder.find(dir, resolver);
|
||||
}
|
||||
}
|
||||
if (visitParent)
|
||||
loader = loader.getParent();
|
||||
else
|
||||
loader = null;
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.io.InputStream;
|
|||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
|
@ -586,7 +587,7 @@ public class AnnotationFinder
|
|||
* @param resolver
|
||||
* @throws Exception
|
||||
*/
|
||||
public void find (ClassLoader loader, boolean visitParents, String jarNamePattern, boolean nullInclusive, final ClassNameResolver resolver)
|
||||
public void find (ClassLoader loader, boolean visitParents, boolean nullInclusive, final ClassNameResolver resolver)
|
||||
throws Exception
|
||||
{
|
||||
if (loader==null)
|
||||
|
@ -597,7 +598,7 @@ public class AnnotationFinder
|
|||
|
||||
JarScanner scanner = new JarScanner()
|
||||
{
|
||||
public void processEntry(URL jarUrl, JarEntry entry)
|
||||
public void processEntry(URI jarUri, JarEntry entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -610,7 +611,7 @@ public class AnnotationFinder
|
|||
if ((parsedClasses.get(shortName) == null) || (resolver.shouldOverride(shortName)))
|
||||
{
|
||||
parsedClasses.remove(shortName);
|
||||
Resource clazz = Resource.newResource("jar:"+jarUrl+"!/"+name);
|
||||
Resource clazz = Resource.newResource("jar:"+jarUri+"!/"+name);
|
||||
scanClass(clazz.getInputStream());
|
||||
}
|
||||
}
|
||||
|
@ -623,32 +624,26 @@ public class AnnotationFinder
|
|||
}
|
||||
|
||||
};
|
||||
Pattern pattern = null;
|
||||
if (jarNamePattern!=null)
|
||||
pattern = Pattern.compile(jarNamePattern);
|
||||
|
||||
scanner.scan(pattern, loader, nullInclusive, visitParents);
|
||||
|
||||
scanner.scan(null, loader, nullInclusive, visitParents);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find annotations in classes in classes in the supplied url of jar files.
|
||||
* @param urls
|
||||
* @param visitParents
|
||||
* @param jarNamePattern
|
||||
* @param nullInclusive
|
||||
* Find annotations in classes in the supplied url of jar files.
|
||||
* @param uris
|
||||
* @param resolver
|
||||
* @throws Exception
|
||||
*/
|
||||
public void find (URL[] urls, boolean visitParents, String jarNamePattern, boolean nullInclusive, final ClassNameResolver resolver)
|
||||
public void find (URI[] uris, final ClassNameResolver resolver)
|
||||
throws Exception
|
||||
{
|
||||
if (urls==null)
|
||||
if (uris==null)
|
||||
return;
|
||||
|
||||
JarScanner scanner = new JarScanner()
|
||||
{
|
||||
public void processEntry(URL jarUrl, JarEntry entry)
|
||||
public void processEntry(URI jarUri, JarEntry entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -661,7 +656,7 @@ public class AnnotationFinder
|
|||
if ((parsedClasses.get(shortName) == null) || (resolver.shouldOverride(shortName)))
|
||||
{
|
||||
parsedClasses.remove(shortName);
|
||||
Resource clazz = Resource.newResource("jar:"+jarUrl+"!/"+name);
|
||||
Resource clazz = Resource.newResource("jar:"+jarUri+"!/"+name);
|
||||
scanClass(clazz.getInputStream());
|
||||
}
|
||||
}
|
||||
|
@ -673,12 +668,8 @@ public class AnnotationFinder
|
|||
}
|
||||
}
|
||||
|
||||
};
|
||||
Pattern pattern = null;
|
||||
if (jarNamePattern!=null)
|
||||
pattern = Pattern.compile(jarNamePattern);
|
||||
|
||||
scanner.scan(pattern, urls, nullInclusive);
|
||||
};
|
||||
scanner.scan(null, uris, true);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.util.Scanner;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -73,7 +74,8 @@ public class ContextDeployer extends AbstractLifeCycle
|
|||
private ContextHandlerCollection _contexts;
|
||||
private ConfigurationManager _configMgr;
|
||||
private boolean _recursive = false;
|
||||
|
||||
private AttributesMap _contextAttributes = new AttributesMap();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected class ScannerListener implements Scanner.DiscreteListener
|
||||
{
|
||||
|
@ -255,6 +257,39 @@ public class ContextDeployer extends AbstractLifeCycle
|
|||
{
|
||||
return _recursive;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a contextAttribute that will be set for every Context deployed by this deployer.
|
||||
* @param name
|
||||
* @param value
|
||||
*/
|
||||
public void setAttribute (String name, Object value)
|
||||
{
|
||||
_contextAttributes.setAttribute(name,value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a contextAttribute that will be set for every Context deployed by this deployer.
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public Object getAttribute (String name)
|
||||
{
|
||||
return _contextAttributes.getAttribute(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a contextAttribute that will be set for every Context deployed by this deployer.
|
||||
* @param name
|
||||
*/
|
||||
public void removeAttribute(String name)
|
||||
{
|
||||
_contextAttributes.removeAttribute(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void deploy(String filename) throws Exception
|
||||
{
|
||||
|
@ -365,6 +400,7 @@ public class ContextDeployer extends AbstractLifeCycle
|
|||
|
||||
xmlConfiguration.setProperties(properties);
|
||||
ContextHandler context=(ContextHandler)xmlConfiguration.configure();
|
||||
context.setAttributes(new AttributesMap(_contextAttributes));
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ package org.eclipse.jetty.deploy;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.HandlerContainer;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
@ -51,6 +51,7 @@ public class WebAppDeployer extends AbstractLifeCycle
|
|||
private boolean _parentLoaderPriority;
|
||||
private boolean _allowDuplicates;
|
||||
private ArrayList _deployed;
|
||||
private AttributesMap _contextAttributes = new AttributesMap();
|
||||
|
||||
public String[] getConfigurationClasses()
|
||||
{
|
||||
|
@ -126,6 +127,38 @@ public class WebAppDeployer extends AbstractLifeCycle
|
|||
_allowDuplicates=allowDuplicates;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a contextAttribute that will be set for every Context deployed by this deployer.
|
||||
* @param name
|
||||
* @param value
|
||||
*/
|
||||
public void setAttribute (String name, Object value)
|
||||
{
|
||||
_contextAttributes.setAttribute(name,value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a contextAttribute that will be set for every Context deployed by this deployer.
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public Object getAttribute (String name)
|
||||
{
|
||||
return _contextAttributes.getAttribute(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a contextAttribute that will be set for every Context deployed by this deployer.
|
||||
* @param name
|
||||
*/
|
||||
public void removeAttribute(String name)
|
||||
{
|
||||
_contextAttributes.removeAttribute(name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @throws Exception
|
||||
|
@ -234,6 +267,10 @@ public class WebAppDeployer extends AbstractLifeCycle
|
|||
wah.setExtractWAR(_extract);
|
||||
wah.setWar(app.toString());
|
||||
wah.setParentLoaderPriority(_parentLoaderPriority);
|
||||
|
||||
//set up any contextAttributes
|
||||
wah.setAttributes(_contextAttributes);
|
||||
|
||||
// add it
|
||||
_contexts.addHandler(wah);
|
||||
_deployed.add(wah);
|
||||
|
|
|
@ -201,7 +201,6 @@ public abstract class NamingEntry
|
|||
objectName.addAll(0, prefix);
|
||||
objectNameString = objectName.toString();
|
||||
NamingUtil.bind(ic, objectNameString, objectToBind);
|
||||
System.err.println("Bound: "+objectName.toString()+" to "+objectToBind);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -411,7 +411,7 @@ public abstract class AbstractConfiguration implements Configuration
|
|||
{
|
||||
bindUserTransaction(context);
|
||||
|
||||
WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||
WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
|
||||
if (webXmlProcessor == null)
|
||||
throw new IllegalStateException ("No processor for web xml");
|
||||
|
||||
|
|
|
@ -62,8 +62,6 @@ public class Configuration extends AbstractConfiguration
|
|||
EnvEntry ee = (EnvEntry)ne;
|
||||
bound = ee.isOverrideWebXml();
|
||||
}
|
||||
|
||||
System.err.println("Checked for envEntry already bound for "+name+" and got: "+ne+", bound="+bound);
|
||||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
|
@ -75,7 +73,6 @@ public class Configuration extends AbstractConfiguration
|
|||
//either nothing was bound or the value from web.xml should override
|
||||
Context envCtx = (Context)ic.lookup("java:comp/env");
|
||||
NamingUtil.bind(envCtx, name, value);
|
||||
System.err.println("Bound "+name+"to "+value+" for java:comp/env");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +183,8 @@ public class Configuration extends AbstractConfiguration
|
|||
*/
|
||||
public void parseAnnotations(WebAppContext context) throws Exception
|
||||
{
|
||||
//see org.eclipse.jetty.annotations.Configuration instead
|
||||
//Noop unless you want to do annotation discovery.
|
||||
//Use org.eclipse.jetty.annotations.Configuration instead.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,32 +218,26 @@ public class Configuration extends AbstractConfiguration
|
|||
//if we found a mapping, get out name it is mapped to in the environment
|
||||
nameInEnvironment = (String)((Link)ne).getObjectToBind();
|
||||
Link l = (Link)ne;
|
||||
System.err.println("Link, with nameInEnvironment="+nameInEnvironment);
|
||||
}
|
||||
|
||||
//try finding that mapped name in the webapp's environment first
|
||||
System.err.println("Trying to find "+nameInEnvironment+" in webapp scope");
|
||||
scope = context;
|
||||
bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
|
||||
|
||||
if (bound)
|
||||
return;
|
||||
|
||||
System.err.println("Trying to find "+nameInEnvironment+" in server scope");
|
||||
//try the server's environment
|
||||
scope = context.getServer();
|
||||
bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
|
||||
if (bound)
|
||||
return;
|
||||
|
||||
System.err.println("Trying to find "+nameInEnvironment+" in jvm scope");
|
||||
//try the jvm environment
|
||||
bound = NamingEntryUtil.bindToENC(null, name, nameInEnvironment);
|
||||
if (bound)
|
||||
return;
|
||||
|
||||
|
||||
System.err.println("Didn't find "+nameInEnvironment+" anywhere - looking for "+typeClass.getName()+"/default in server or jvm scope");
|
||||
//There is no matching resource so try a default name.
|
||||
//The default name syntax is: the [res-type]/default
|
||||
//eg javax.sql.DataSource/default
|
||||
|
|
|
@ -40,9 +40,6 @@ import org.eclipse.jetty.xml.XmlConfiguration;
|
|||
*/
|
||||
public class EnvConfiguration implements Configuration
|
||||
{
|
||||
|
||||
private Context compCtx;
|
||||
private Context envCtx;
|
||||
private URL jettyEnvXmlUrl;
|
||||
|
||||
|
||||
|
@ -96,7 +93,6 @@ public class EnvConfiguration implements Configuration
|
|||
//apply the jetty-env.xml file
|
||||
if (jettyEnvXmlUrl != null)
|
||||
{
|
||||
System.err.println("Applying "+jettyEnvXmlUrl);
|
||||
XmlConfiguration configuration = new XmlConfiguration(jettyEnvXmlUrl);
|
||||
configuration.configure(context);
|
||||
}
|
||||
|
@ -122,8 +118,17 @@ public class EnvConfiguration implements Configuration
|
|||
//get rid of any bindings for comp/env for webapp
|
||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||
compCtx.destroySubcontext("env");
|
||||
|
||||
try
|
||||
{
|
||||
Context ic = new InitialContext();
|
||||
Context compCtx = (Context)ic.lookup ("java:comp");
|
||||
compCtx.destroySubcontext("env");
|
||||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
Log.warn(e);
|
||||
}
|
||||
|
||||
//unbind any NamingEntries that were configured in this webapp's name space
|
||||
try
|
||||
{
|
||||
|
@ -149,6 +154,8 @@ public class EnvConfiguration implements Configuration
|
|||
throws NamingException
|
||||
{
|
||||
Log.debug("Binding env entries from the jvm scope");
|
||||
InitialContext ic = new InitialContext();
|
||||
Context envCtx = (Context)ic.lookup("java:comp/env");
|
||||
Object scope = null;
|
||||
List list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
||||
Iterator itor = list.iterator();
|
||||
|
@ -190,9 +197,7 @@ public class EnvConfiguration implements Configuration
|
|||
throws NamingException
|
||||
{
|
||||
Context context = new InitialContext();
|
||||
compCtx = (Context)context.lookup ("java:comp");
|
||||
envCtx = compCtx.createSubcontext("env");
|
||||
|
||||
System.err.println("Created comp/env");
|
||||
Context compCtx = (Context)context.lookup ("java:comp");
|
||||
compCtx.createSubcontext("env");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,10 @@
|
|||
<Set name="contexts"><Ref id="Contexts"/></Set>
|
||||
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
|
||||
<Set name="scanInterval">5</Set>
|
||||
<Call name="setAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
@ -136,6 +140,10 @@
|
|||
<Set name="extract">true</Set>
|
||||
<Set name="allowDuplicates">false</Set>
|
||||
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
||||
<Call name="setAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -41,6 +41,11 @@ public class AttributesMap implements Attributes
|
|||
_map=map;
|
||||
}
|
||||
|
||||
public AttributesMap(AttributesMap map)
|
||||
{
|
||||
_map=new HashMap(map._map);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see org.eclipse.jetty.util.Attributes#removeAttribute(java.lang.String)
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class PatternMatcher
|
||||
{
|
||||
public abstract void matched (URI uri) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Find jar names from the provided list matching a pattern.
|
||||
*
|
||||
* If the pattern is null and isNullInclusive is true, then
|
||||
* all jar names will match.
|
||||
*
|
||||
* A pattern is a set of acceptable jar names. Each acceptable
|
||||
* jar name is a regex. Each regex can be separated by either a
|
||||
* "," or a "|". If you use a "|" this or's together the jar
|
||||
* name patterns. This means that ordering of the matches is
|
||||
* unimportant to you. If instead, you want to match particular
|
||||
* jar names, and you want to match them in order, you should
|
||||
* separate the regexs with "," instead.
|
||||
*
|
||||
* Eg "aaa-.*\\.jar|bbb-.*\\.jar"
|
||||
* Will iterate over the jar names and match
|
||||
* in any order.
|
||||
*
|
||||
* Eg "aaa-*\\.jar,bbb-.*\\.jar"
|
||||
* Will iterate over the jar names, matching
|
||||
* all those starting with "aaa-" first, then "bbb-".
|
||||
*
|
||||
* @param pattern
|
||||
* @param loader
|
||||
* @param isNullInclusive if true, an empty pattern means all names match, if false, none match
|
||||
* @throws Exception
|
||||
*/
|
||||
public void match (Pattern pattern, URI[] uris, boolean isNullInclusive)
|
||||
throws Exception
|
||||
{
|
||||
if (uris!=null)
|
||||
{
|
||||
String[] patterns = (pattern==null?null:pattern.pattern().split(","));
|
||||
|
||||
List<Pattern> subPatterns = new ArrayList<Pattern>();
|
||||
for (int i=0; patterns!=null && i<patterns.length;i++)
|
||||
{
|
||||
subPatterns.add(Pattern.compile(patterns[i]));
|
||||
}
|
||||
if (subPatterns.isEmpty())
|
||||
subPatterns.add(pattern);
|
||||
|
||||
if (subPatterns.isEmpty())
|
||||
{
|
||||
matchPatterns(null, uris, isNullInclusive);
|
||||
}
|
||||
else
|
||||
{
|
||||
//for each subpattern, iterate over all the urls, processing those that match
|
||||
for (Pattern p : subPatterns)
|
||||
{
|
||||
matchPatterns(p, uris, isNullInclusive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void matchPatterns (Pattern pattern, URI[] uris, boolean isNullInclusive)
|
||||
throws Exception
|
||||
{
|
||||
for (int i=0; i<uris.length;i++)
|
||||
{
|
||||
URI uri = uris[i];
|
||||
String s = uri.toString();
|
||||
if ((pattern == null && isNullInclusive)
|
||||
||
|
||||
(pattern!=null && pattern.matcher(s).matches()))
|
||||
{
|
||||
matched(uris[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,6 +51,7 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
{
|
||||
if (_state == __STARTED || _state == __STARTING)
|
||||
return;
|
||||
Log.debug("Starting {}",this);
|
||||
setStarting();
|
||||
doStart();
|
||||
Log.debug(STARTED+" {}",this);
|
||||
|
|
|
@ -50,24 +50,6 @@
|
|||
</context-param>
|
||||
-->
|
||||
|
||||
<!-- control which jars from the container's classpath will be scanned for .tlds -->
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.server.webapp.ContainerIncludeTLDJarPattern</param-name>
|
||||
<param-value>jsp-api-.*\.jar|jsp-.*\.jar</param-value>
|
||||
</context-param>
|
||||
|
||||
<!-- control which jars from the container's classpath will be scanned for -->
|
||||
<!-- annotations. If this property is empty, NO JARS from the container -->
|
||||
<!-- classpath will be scanned. This can be overridden by a webapp by -->
|
||||
<!-- defining this context-param in their web.xml file. Individual webapps -->
|
||||
<!-- can also control which jars in their WEB-INF/lib will be scanned by -->
|
||||
<!-- setting a context-param in web.xml called: -->
|
||||
<!-- org.eclipse.jetty.server.webapp.WebInfIncludeAnnotationPattern -->
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.server.webapp.ContainerIncludeAnnotationJarPattern</param-name>
|
||||
<param-value></param-value>
|
||||
</context-param>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- The default servlet. -->
|
||||
|
|
|
@ -35,33 +35,36 @@ public class FragmentConfiguration implements Configuration
|
|||
if (!context.isConfigurationDiscovered())
|
||||
return;
|
||||
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
|
||||
if (processor == null)
|
||||
{
|
||||
processor = new WebXmlProcessor (context);
|
||||
context.setAttribute(WebXmlProcessor.__web_processor, processor);
|
||||
context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
|
||||
}
|
||||
|
||||
|
||||
//parse web-fragment.xmls
|
||||
parseWebFragments(context, processor);
|
||||
|
||||
|
||||
//TODO for jetty-8/servletspec 3 we will need to merge the parsed web fragments into the
|
||||
//effective pom in this preConfigure step
|
||||
}
|
||||
|
||||
public void configure(WebAppContext context) throws Exception
|
||||
{
|
||||
{
|
||||
if (!context.isConfigurationDiscovered())
|
||||
return;
|
||||
|
||||
//TODO for jetty-8/servletspec3 the fragments will not be separately processed here, but
|
||||
//will be done by webXmlConfiguration when it processes the effective merged web.xml
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
|
||||
if (processor == null)
|
||||
{
|
||||
processor = new WebXmlProcessor (context);
|
||||
context.setAttribute(WebXmlProcessor.__web_processor, processor);
|
||||
context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
|
||||
}
|
||||
processor.processFragments();
|
||||
|
||||
processor.processFragments();
|
||||
}
|
||||
|
||||
public void deconfigure(WebAppContext context) throws Exception
|
||||
|
@ -83,11 +86,7 @@ public class FragmentConfiguration implements Configuration
|
|||
*/
|
||||
public void parseWebFragments (final WebAppContext context, final WebXmlProcessor processor) throws Exception
|
||||
{
|
||||
// Check to see if a specific search pattern has been set.
|
||||
String tmp = (String) context.getInitParameter("org.eclipse.jetty.webapp.WebXmlFragmentPattern");
|
||||
Pattern webFragPattern = (tmp == null ? null : Pattern.compile(tmp));
|
||||
|
||||
List<Resource> frags = (List<Resource>)context.getAttribute(MetaInfConfiguration.METAINF_FRAGMENTS);
|
||||
List<Resource> frags = (List<Resource>)context.getAttribute(FRAGMENT_RESOURCES);
|
||||
if (frags!=null)
|
||||
{
|
||||
for (Resource frag : frags)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package org.eclipse.jetty.webapp;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
|
@ -38,10 +39,10 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
* method to handle entries in jar files whose names match the supplied
|
||||
* pattern.
|
||||
*/
|
||||
public abstract class JarScanner
|
||||
public abstract class JarScanner extends org.eclipse.jetty.util.PatternMatcher
|
||||
{
|
||||
|
||||
public abstract void processEntry (URL jarUrl, JarEntry entry);
|
||||
public abstract void processEntry (URI jarUri, JarEntry entry);
|
||||
|
||||
/**
|
||||
* Find jar names from the provided list matching a pattern.
|
||||
|
@ -70,32 +71,10 @@ public abstract class JarScanner
|
|||
* @param isNullInclusive if true, an empty pattern means all names match, if false, none match
|
||||
* @throws Exception
|
||||
*/
|
||||
public void scan (Pattern pattern, URL[] urls, boolean isNullInclusive)
|
||||
public void scan (Pattern pattern, URI[] uris, boolean isNullInclusive)
|
||||
throws Exception
|
||||
{
|
||||
if (urls!=null)
|
||||
{
|
||||
String[] patterns = (pattern==null?null:pattern.pattern().split(","));
|
||||
|
||||
List<Pattern> subPatterns = new ArrayList<Pattern>();
|
||||
for (int i=0; patterns!=null && i<patterns.length;i++)
|
||||
subPatterns.add(Pattern.compile(patterns[i]));
|
||||
if (subPatterns.isEmpty())
|
||||
subPatterns.add(pattern);
|
||||
|
||||
if (subPatterns.isEmpty())
|
||||
{
|
||||
processJars(null, urls, isNullInclusive);
|
||||
}
|
||||
else
|
||||
{
|
||||
//for each subpattern, iterate over all the urls, processing those that match
|
||||
for (Pattern p : subPatterns)
|
||||
{
|
||||
processJars(p, urls, isNullInclusive);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.match(pattern, uris, isNullInclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,35 +112,18 @@ public abstract class JarScanner
|
|||
public void scan (Pattern pattern, ClassLoader loader, boolean isNullInclusive, boolean visitParent)
|
||||
throws Exception
|
||||
{
|
||||
String[] patterns = (pattern==null?null:pattern.pattern().split(","));
|
||||
|
||||
List<Pattern> subPatterns = new ArrayList<Pattern>();
|
||||
for (int i=0; patterns!=null && i<patterns.length;i++)
|
||||
subPatterns.add(Pattern.compile(patterns[i]));
|
||||
if (subPatterns.isEmpty())
|
||||
subPatterns.add(pattern);
|
||||
|
||||
|
||||
while (loader!=null)
|
||||
{
|
||||
if (loader instanceof URLClassLoader)
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
|
||||
if (urls!=null)
|
||||
if (urls != null)
|
||||
{
|
||||
if (subPatterns.isEmpty())
|
||||
{
|
||||
processJars(null, urls, isNullInclusive);
|
||||
}
|
||||
else
|
||||
{
|
||||
//for each subpattern, iterate over all the urls, processing those that match
|
||||
for (Pattern p : subPatterns)
|
||||
{
|
||||
processJars(p, urls, isNullInclusive);
|
||||
}
|
||||
}
|
||||
URI[] uris = new URI[urls.length];
|
||||
int i=0;
|
||||
for (URL u : urls)
|
||||
uris[i++] = u.toURI();
|
||||
scan (pattern, uris, isNullInclusive);
|
||||
}
|
||||
}
|
||||
if (visitParent)
|
||||
|
@ -172,50 +134,31 @@ public abstract class JarScanner
|
|||
}
|
||||
|
||||
|
||||
|
||||
public void processJars (Pattern pattern, URL[] urls, boolean isNullInclusive)
|
||||
public void matched (URI uri)
|
||||
throws Exception
|
||||
{
|
||||
for (int i=0; i<urls.length;i++)
|
||||
Log.debug("Search of {}",uri);
|
||||
if (uri.toString().toLowerCase().endsWith(".jar"))
|
||||
{
|
||||
if (urls[i].toString().toLowerCase().endsWith(".jar"))
|
||||
{
|
||||
String jar = urls[i].toString();
|
||||
int slash=jar.lastIndexOf('/');
|
||||
jar=jar.substring(slash+1);
|
||||
|
||||
if ((pattern == null && isNullInclusive)
|
||||
||
|
||||
(pattern!=null && pattern.matcher(jar).matches()))
|
||||
|
||||
InputStream in = Resource.newResource(uri).getInputStream();
|
||||
if (in==null)
|
||||
return;
|
||||
|
||||
JarInputStream jar_in = new JarInputStream(in);
|
||||
try
|
||||
{
|
||||
JarEntry entry = jar_in.getNextJarEntry();
|
||||
while (entry!=null)
|
||||
{
|
||||
processJar(urls[i]);
|
||||
processEntry(uri, entry);
|
||||
entry = jar_in.getNextJarEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void processJar (URL url)
|
||||
throws Exception
|
||||
{
|
||||
Log.debug("Search of {}",url);
|
||||
|
||||
InputStream in = Resource.newResource(url).getInputStream();
|
||||
if (in==null)
|
||||
return;
|
||||
|
||||
JarInputStream jar_in = new JarInputStream(in);
|
||||
try
|
||||
{
|
||||
JarEntry entry = jar_in.getNextJarEntry();
|
||||
while (entry!=null)
|
||||
finally
|
||||
{
|
||||
processEntry(url, entry);
|
||||
entry = jar_in.getNextJarEntry();
|
||||
}
|
||||
jar_in.close();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
jar_in.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
package org.eclipse.jetty.webapp;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
@ -37,19 +39,19 @@ public class MetaInfConfiguration implements Configuration
|
|||
public static final String METAINF_TLDS = TagLibConfiguration.TLD_RESOURCES;
|
||||
public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES;
|
||||
public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_URLS;
|
||||
public static final String JAR_RESOURCES = WebInfConfiguration.JAR_RESOURCES;
|
||||
|
||||
public void preConfigure(final WebAppContext context) throws Exception
|
||||
{
|
||||
//Find all jars in WEB-INF
|
||||
List<URL> urls = findJars(context);
|
||||
|
||||
|
||||
JarScanner fragScanner = new JarScanner()
|
||||
JarScanner scanner = new JarScanner()
|
||||
{
|
||||
public void processEntry(URL jarUrl, JarEntry entry)
|
||||
public void processEntry(URI jarUri, JarEntry entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
MetaInfConfiguration.this.processEntry(context,jarUrl,entry);
|
||||
MetaInfConfiguration.this.processEntry(context,jarUri,entry);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -57,26 +59,36 @@ public class MetaInfConfiguration implements Configuration
|
|||
}
|
||||
}
|
||||
};
|
||||
fragScanner.scan(null, urls.toArray(new URL[urls.size()]), true);
|
||||
|
||||
List<Resource> jarResources = (List<Resource>)context.getAttribute(JAR_RESOURCES);
|
||||
|
||||
//Scan jars for META-INF information
|
||||
if (jarResources != null)
|
||||
{
|
||||
URI[] uris = new URI[jarResources.size()];
|
||||
int i=0;
|
||||
for (Resource r : jarResources)
|
||||
{
|
||||
uris[i++] = r.getURI();
|
||||
}
|
||||
scanner.scan(null, uris, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void configure(WebAppContext context) throws Exception
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void deconfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void postConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addResource (WebAppContext context, String attribute, Resource jar)
|
||||
|
@ -92,74 +104,35 @@ public class MetaInfConfiguration implements Configuration
|
|||
}
|
||||
|
||||
|
||||
protected void processEntry(WebAppContext context, URL jarUrl, JarEntry entry)
|
||||
protected void processEntry(WebAppContext context, URI jarUri, JarEntry entry)
|
||||
{
|
||||
String name = entry.getName();
|
||||
|
||||
if (!name.startsWith("META-INF/"))
|
||||
return;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (name.equals("META-INF/web-fragment.xml") && context.isConfigurationDiscovered())
|
||||
{
|
||||
addResource(context,METAINF_FRAGMENTS,Resource.newResource(jarUrl));
|
||||
addResource(context,METAINF_FRAGMENTS,Resource.newResource(jarUri));
|
||||
}
|
||||
else if (name.equals("META-INF/resources/") && context.isConfigurationDiscovered())
|
||||
{
|
||||
addResource(context,METAINF_RESOURCES,Resource.newResource("jar:"+jarUrl+"!/META-INF/resources"));
|
||||
addResource(context,METAINF_RESOURCES,Resource.newResource("jar:"+jarUri+"!/META-INF/resources"));
|
||||
}
|
||||
else
|
||||
{
|
||||
String lcname = name.toLowerCase();
|
||||
if (lcname.endsWith(".tld"))
|
||||
{
|
||||
addResource(context,METAINF_TLDS,Resource.newResource("jar:"+jarUrl+"!/"+name));
|
||||
addResource(context,METAINF_TLDS,Resource.newResource("jar:"+jarUri+"!/"+name));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
context.getServletContext().log(jarUrl+"!/"+name,e);
|
||||
context.getServletContext().log(jarUri+"!/"+name,e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for jars in WEB-INF/lib
|
||||
* @param context
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected List<URL> findJars (WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
List<URL> urls = new ArrayList<URL>();
|
||||
|
||||
Resource web_inf = context.getWebInf();
|
||||
Resource web_inf_lib = web_inf.addPath("/lib");
|
||||
|
||||
|
||||
if (web_inf_lib.exists() && web_inf_lib.isDirectory())
|
||||
{
|
||||
String[] files=web_inf_lib.list();
|
||||
for (int f=0;files!=null && f<files.length;f++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Resource file = web_inf_lib.addPath(files[f]);
|
||||
String fnlc = file.getName().toLowerCase();
|
||||
int dot = fnlc.lastIndexOf('.');
|
||||
String extension = (dot < 0 ? null : fnlc.substring(dot));
|
||||
if (extension != null && (extension.equals(".jar") || extension.equals(".zip")))
|
||||
{
|
||||
urls.add(file.getURL());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.warn(Log.EXCEPTION,ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ import org.eclipse.jetty.xml.XmlParser;
|
|||
/** TagLibConfiguration.
|
||||
*
|
||||
* The class searches for TLD descriptors found in web.xml, in WEB-INF/*.tld files of the web app
|
||||
* or *.tld files withing jars found in WEB-INF/lib of the webapp. Any listeners defined in these
|
||||
* or *.tld files within jars found in WEB-INF/lib of the webapp. Any listeners defined in these
|
||||
* tld's are added to the context.
|
||||
*
|
||||
* <bile>This is total rubbish special case for JSPs! If there was a general use-case for web app
|
||||
* frameworks to register listeners directly, then a generic mechanism could have been added to the servlet
|
||||
* spec. Instead some special purpose JSP support is required that breaks all sorts of encapsualtion rules as
|
||||
* spec. Instead some special purpose JSP support is required that breaks all sorts of encapsulation rules as
|
||||
* the servlet container must go searching for and then parsing the descriptors for one particular framework.
|
||||
* It only appears to be used by JSF, which is being developed by the same developer who implemented this
|
||||
* feature in the first place!
|
||||
|
@ -242,26 +242,8 @@ public class TagLibConfiguration implements Configuration
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Look for tlds in any jars
|
||||
//Use an opt-in style:
|
||||
//
|
||||
//org.eclipse.jetty.server.server.webapp.WebInfIncludeTLDJarPattern and
|
||||
//org.eclipse.jetty.server.server.webapp.ContainerIncludeTLDJarPattern
|
||||
//
|
||||
//When examining jars in WEB-INF/lib:
|
||||
// if WebInfIncludeTLDJarPattern is null
|
||||
// examine ALL for tlds
|
||||
// else
|
||||
// examine only files matching pattern
|
||||
//
|
||||
//When examining jars in parent loaders:
|
||||
// If IncludeTLDJarPattern is null
|
||||
// examine none
|
||||
// else
|
||||
// examine only files matching pattern
|
||||
//
|
||||
|
||||
|
||||
// Add in tlds found in META-INF of jars
|
||||
Collection<Resource> tld_resources=(Collection<Resource>)context.getAttribute(TLD_RESOURCES);
|
||||
if (tld_resources!=null)
|
||||
tlds.addAll(tld_resources);
|
||||
|
|
|
@ -2,11 +2,16 @@ package org.eclipse.jetty.webapp;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.resource.JarResource;
|
||||
|
@ -16,6 +21,9 @@ import org.eclipse.jetty.util.resource.ResourceCollection;
|
|||
public class WebInfConfiguration implements Configuration
|
||||
{
|
||||
public static final String TEMPDIR_CREATED = "org.eclipse.jetty.tmpdirCreated";
|
||||
public static final String JAR_RESOURCES = "org.eclipse.jetty.jarList";
|
||||
public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern";
|
||||
public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern";
|
||||
|
||||
/**
|
||||
* If set, to a list of URLs, these resources are added to the context
|
||||
|
@ -23,7 +31,10 @@ public class WebInfConfiguration implements Configuration
|
|||
*/
|
||||
public static final String RESOURCE_URLS = "org.eclipse.jetty.resources";
|
||||
|
||||
public void preConfigure(WebAppContext context) throws Exception
|
||||
|
||||
|
||||
|
||||
public void preConfigure(final WebAppContext context) throws Exception
|
||||
{
|
||||
//Make a temp directory for the webapp if one is not already set
|
||||
resolveTempDirectory(context);
|
||||
|
@ -34,6 +45,59 @@ public class WebInfConfiguration implements Configuration
|
|||
File work = findWorkDirectory(context);
|
||||
if (work != null)
|
||||
makeTempDirectory(work, context, false);
|
||||
|
||||
//Apply an initial ordering to the jars which governs which will be scanned for META-INF
|
||||
//info and annotations. The ordering is based on inclusion patterns.
|
||||
String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN);
|
||||
Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
|
||||
tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
|
||||
Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp));
|
||||
|
||||
final ArrayList jarResources = new ArrayList<Resource>();
|
||||
context.setAttribute(JAR_RESOURCES, jarResources);
|
||||
|
||||
PatternMatcher jarNameMatcher = new PatternMatcher ()
|
||||
{
|
||||
public void matched(URI uri) throws Exception
|
||||
{
|
||||
jarResources.add(Resource.newResource(uri));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//Apply ordering to container jars
|
||||
ClassLoader loader = context.getClassLoader();
|
||||
while (loader != null && (loader instanceof URLClassLoader))
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
{
|
||||
URI[] containerUris = new URI[urls.length];
|
||||
int i=0;
|
||||
for (URL u : urls)
|
||||
{
|
||||
containerUris[i++] = u.toURI();
|
||||
}
|
||||
jarNameMatcher.match(containerPattern, containerUris, false);
|
||||
}
|
||||
loader = loader.getParent();
|
||||
}
|
||||
|
||||
//Apply ordering to WEB-INF/lib jars
|
||||
//Find all jars in WEB-INF
|
||||
List<Resource> jars = findJars(context);
|
||||
//Convert to uris for matching
|
||||
URI[] uris = null;
|
||||
if (jars != null)
|
||||
{
|
||||
uris = new URI[jars.size()];
|
||||
int i=0;
|
||||
for (Resource r: jars)
|
||||
{
|
||||
uris[i++] = r.getURI();
|
||||
}
|
||||
}
|
||||
jarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match
|
||||
}
|
||||
|
||||
|
||||
|
@ -501,4 +565,43 @@ public class WebInfConfiguration implements Configuration
|
|||
return canonicalName.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for jars in WEB-INF/lib
|
||||
* @param context
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected List<Resource> findJars (WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> jarResources = new ArrayList<Resource>();
|
||||
|
||||
Resource web_inf = context.getWebInf();
|
||||
Resource web_inf_lib = web_inf.addPath("/lib");
|
||||
|
||||
|
||||
if (web_inf_lib.exists() && web_inf_lib.isDirectory())
|
||||
{
|
||||
String[] files=web_inf_lib.list();
|
||||
for (int f=0;files!=null && f<files.length;f++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Resource file = web_inf_lib.addPath(files[f]);
|
||||
String fnlc = file.getName().toLowerCase();
|
||||
int dot = fnlc.lastIndexOf('.');
|
||||
String extension = (dot < 0 ? null : fnlc.substring(dot));
|
||||
if (extension != null && (extension.equals(".jar") || extension.equals(".zip")))
|
||||
{
|
||||
jarResources.add(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.warn(Log.EXCEPTION,ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jarResources;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,11 +57,11 @@ public class WebXmlConfiguration implements Configuration
|
|||
}
|
||||
|
||||
//Get or create a processor to handle webdefaults, web.xml and the fragments
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
|
||||
if (processor == null)
|
||||
{
|
||||
processor = new WebXmlProcessor (context);
|
||||
context.setAttribute(WebXmlProcessor.__web_processor, processor);
|
||||
context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
|
||||
}
|
||||
|
||||
//handle webdefault.xml
|
||||
|
@ -74,8 +74,6 @@ public class WebXmlConfiguration implements Configuration
|
|||
processor.parseDefaults (dftResource.getURL());
|
||||
processor.processDefaults();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
@ -93,11 +91,11 @@ public class WebXmlConfiguration implements Configuration
|
|||
return;
|
||||
}
|
||||
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
|
||||
if (processor == null)
|
||||
{
|
||||
processor = new WebXmlProcessor (context);
|
||||
context.setAttribute(WebXmlProcessor.__web_processor, processor);
|
||||
context.setAttribute(WebXmlProcessor.WEB_PROCESSOR, processor);
|
||||
}
|
||||
|
||||
//process web.xml
|
||||
|
@ -118,7 +116,6 @@ public class WebXmlConfiguration implements Configuration
|
|||
processor.parseOverride(orideResource.getURL());
|
||||
processor.processOverride();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ import org.eclipse.jetty.xml.XmlParser;
|
|||
*/
|
||||
public class WebXmlProcessor
|
||||
{
|
||||
public static final String __web_processor = "org.eclipse.jetty.webProcessor";
|
||||
public static final String WEB_PROCESSOR = "org.eclipse.jetty.webProcessor";
|
||||
|
||||
protected WebAppContext _context;
|
||||
protected XmlParser _xmlParser;
|
||||
|
@ -297,6 +297,7 @@ public class WebXmlProcessor
|
|||
public void process (XmlParser.Node config)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
//Get the current objects from the context
|
||||
_servletHandler = _context.getServletHandler();
|
||||
_securityHandler = (SecurityHandler)_context.getSecurityHandler();
|
||||
|
@ -315,8 +316,8 @@ public class WebXmlProcessor
|
|||
_roles.addAll(((ConstraintAware) _securityHandler).getRoles());
|
||||
}
|
||||
}
|
||||
_errorPages = _context.getErrorHandler() instanceof ErrorPageErrorHandler ? ((ErrorPageErrorHandler)_context.getErrorHandler()).getErrorPages() : null;
|
||||
|
||||
_errorPages = _context.getErrorHandler() instanceof ErrorPageErrorHandler ? ((ErrorPageErrorHandler)_context.getErrorHandler()).getErrorPages() : null;
|
||||
|
||||
Iterator iter = config.iterator();
|
||||
XmlParser.Node node = null;
|
||||
while (iter.hasNext())
|
||||
|
|
Loading…
Reference in New Issue