merged quickstart changes

This commit is contained in:
Greg Wilkins 2014-03-14 13:07:00 +11:00
parent d76c786803
commit b3be247423
12 changed files with 395 additions and 131 deletions

View File

@ -72,11 +72,6 @@
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty.toolchain</groupId> <groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId> <artifactId>jetty-test-helper</artifactId>

View File

@ -447,7 +447,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
{ {
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP); Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
if (map == null) if (map == null)
throw new IllegalStateException ("No class hierarchy"); LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
for (ContainerInitializer i : initializers) for (ContainerInitializer i : initializers)
i.resolveClasses(context,map); i.resolveClasses(context,map);
} }
@ -562,7 +562,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
LOG.debug("Scanned {} in {}ms", p.getResource(), TimeUnit.MILLISECONDS.convert(p.getStatistic().getElapsed(), TimeUnit.NANOSECONDS)); LOG.debug("Scanned {} in {}ms", p.getResource(), TimeUnit.MILLISECONDS.convert(p.getStatistic().getElapsed(), TimeUnit.NANOSECONDS));
} }
LOG.info("Scanned {} container path jars, {} WEB-INF/lib jars, {} WEB-INF/classes dirs in {}ms for context {}", LOG.debug("Scanned {} container path jars, {} WEB-INF/lib jars, {} WEB-INF/classes dirs in {}ms for context {}",
_containerPathStats.getTotal(), _webInfLibStats.getTotal(), _webInfClassesStats.getTotal(), _containerPathStats.getTotal(), _webInfLibStats.getTotal(), _webInfClassesStats.getTotal(),
(TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)), (TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)),
context); context);

View File

@ -6,6 +6,7 @@
server server
security security
jndi jndi
webapp
[lib] [lib]
lib/jetty-plus-${jetty.version}.jar lib/jetty-plus-${jetty.version}.jar

View File

@ -56,26 +56,26 @@ public class ContainerInitializer
public ContainerInitializer (ClassLoader loader, String toString) public ContainerInitializer (ClassLoader loader, String toString)
{ {
Matcher m = Pattern.compile("ContainerInitializer\\{(.*),interested=(.*),applicable=(.*),annotated=(.*)\\}").matcher(toString); Matcher m = Pattern.compile("ContainerInitializer\\{(.*),interested=(.*),applicable=(.*),annotated=(.*)\\}").matcher(toString);
if (!m.matches()) if (!m.matches())
throw new IllegalArgumentException(toString); throw new IllegalArgumentException(toString);
try try
{ {
_target = (ServletContainerInitializer)loader.loadClass(m.group(1)).newInstance(); _target = (ServletContainerInitializer)loader.loadClass(m.group(1)).newInstance();
String[] interested = StringUtil.arrayFromString(m.group(2)); String[] interested = StringUtil.arrayFromString(m.group(2));
_interestedTypes = new Class<?>[interested.length]; _interestedTypes = new Class<?>[interested.length];
for (int i=0;i<interested.length;i++) for (int i=0;i<interested.length;i++)
_interestedTypes[i]=loader.loadClass(interested[i]); _interestedTypes[i]=loader.loadClass(interested[i]);
for (String s:StringUtil.arrayFromString(m.group(3))) for (String s:StringUtil.arrayFromString(m.group(3)))
_applicableTypeNames.add(s); _applicableTypeNames.add(s);
for (String s:StringUtil.arrayFromString(m.group(4))) for (String s:StringUtil.arrayFromString(m.group(4)))
_annotatedTypeNames.add(s); _annotatedTypeNames.add(s);
} }
catch(Exception e) catch(Exception e)
{ {
throw new IllegalArgumentException(toString, e); throw new IllegalArgumentException(toString, e);
} }
} }
public ServletContainerInitializer getTarget () public ServletContainerInitializer getTarget ()

View File

@ -21,7 +21,6 @@ package org.eclipse.jetty.servlet;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;

View File

@ -277,10 +277,37 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
public void doStart() public void doStart()
throws Exception throws Exception
{ {
_unavailable=0; _unavailable=0;
if (!_enabled) if (!_enabled)
return; return;
// Handle JSP file forced paths
if (_forcedPath != null)
{
// Look for a precompiled JSP Servlet
String precompiled="org.apache.jsp"+_forcedPath.replace('.','_').replace('/','.');
ServletHolder jsp=getServletHandler().getServlet(precompiled);
if (jsp!=null)
{
LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
// set the className for this servlet to the precompiled one
setClassName(jsp.getClassName());
}
else
{
// Look for normal JSP servlet
jsp=getServletHandler().getServlet("jsp");
if (jsp!=null)
{
LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
setClassName(jsp.getClassName());
}
}
}
//check servlet has a class (ie is not a preliminary registration). If preliminary, fail startup. //check servlet has a class (ie is not a preliminary registration). If preliminary, fail startup.
try try

View File

@ -27,23 +27,6 @@
</resource> </resource>
</resources> </resources>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>

View File

@ -20,76 +20,293 @@ package org.eclipse.jetty.webapp;
import java.net.URI; import java.net.URI;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.EmptyResource;
import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.Resource;
/** /**
* MetaInfConfiguration * MetaInfConfiguration
* *
* Scan META-INF of all jars in WEB-INF/lib to find: * Scan META-INF of jars to find:
* <ul> * <ul>
* <li>tlds * <li>tlds
* <li>web-fragment.xml * <li>web-fragment.xml
* <li>resources * <li>resources
* </ul> * </ul>
*
* The jars which are scanned are:
* <ol>
* <li>those from the container classpath whose pattern matched the WebInfConfiguration.CONTAINER_JAR_PATTERN</li>
* <li>those from WEB-INF/lib</li>
* </ol>
*/ */
public class MetaInfConfiguration extends AbstractConfiguration public class MetaInfConfiguration extends AbstractConfiguration
{ {
private static final Logger LOG = Log.getLogger(MetaInfConfiguration.class); private static final Logger LOG = Log.getLogger(MetaInfConfiguration.class);
public static final String METAINF_TLDS = TagLibConfiguration.TLD_RESOURCES; public static final String USE_CONTAINER_METAINF_CACHE = "org.eclipse.jetty.metainf.useCache";
public static final boolean DEFAULT_USE_CONTAINER_METAINF_CACHE = true;
public static final String CACHED_CONTAINER_TLDS = "org.eclipse.jetty.tlds.cache";
public static final String CACHED_CONTAINER_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES+".cache";
public static final String CACHED_CONTAINER_RESOURCES = WebInfConfiguration.RESOURCE_DIRS+".cache";
public static final String METAINF_TLDS = "org.eclipse.jetty.tlds";
public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES; public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES;
public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_DIRS; public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_DIRS;
@Override @Override
public void preConfigure(final WebAppContext context) throws Exception public void preConfigure(final WebAppContext context) throws Exception
{
boolean useContainerCache = DEFAULT_USE_CONTAINER_METAINF_CACHE;
Boolean attr = (Boolean)context.getServer().getAttribute(USE_CONTAINER_METAINF_CACHE);
if (attr != null)
useContainerCache = attr.booleanValue();
if (LOG.isDebugEnabled()) LOG.debug("{} = {}", USE_CONTAINER_METAINF_CACHE, useContainerCache);
scanJars(context, context.getMetaData().getContainerResources(), useContainerCache);
scanJars(context, context.getMetaData().getWebInfJars(), false);
}
/**
* Look into the jars to discover info in META-INF. If useCaches == true, then we will
* cache the info discovered indexed by the jar in which it was discovered: this speeds
* up subsequent context deployments.
*
* @param context
* @param jars
* @param useCaches
* @throws Exception
*/
public void scanJars (final WebAppContext context, Collection<Resource> jars, boolean useCaches)
throws Exception
{ {
//Merge all container and webinf lib jars to look for META-INF resources ConcurrentHashMap<Resource, Resource> metaInfResourceCache = null;
ArrayList<Resource> jars = new ArrayList<Resource>(); ConcurrentHashMap<Resource, Resource> metaInfFragmentCache = null;
jars.addAll(context.getMetaData().getContainerResources()); ConcurrentHashMap<Resource, Collection<URL>> metaInfTldCache = null;
jars.addAll(context.getMetaData().getWebInfJars()); if (useCaches)
{
metaInfResourceCache = (ConcurrentHashMap<Resource, Resource>)context.getServer().getAttribute(CACHED_CONTAINER_RESOURCES);
if (metaInfResourceCache == null)
{
metaInfResourceCache = new ConcurrentHashMap<Resource,Resource>();
context.getServer().setAttribute(CACHED_CONTAINER_RESOURCES, metaInfResourceCache);
}
metaInfFragmentCache = (ConcurrentHashMap<Resource, Resource>)context.getServer().getAttribute(CACHED_CONTAINER_FRAGMENTS);
if (metaInfFragmentCache == null)
{
metaInfFragmentCache = new ConcurrentHashMap<Resource,Resource>();
context.getServer().setAttribute(CACHED_CONTAINER_FRAGMENTS, metaInfFragmentCache);
}
metaInfTldCache = (ConcurrentHashMap<Resource, Collection<URL>>)context.getServer().getAttribute(CACHED_CONTAINER_TLDS);
if (metaInfTldCache == null)
{
metaInfTldCache = new ConcurrentHashMap<Resource,Collection<URL>>();
context.getServer().setAttribute(CACHED_CONTAINER_TLDS, metaInfTldCache);
}
}
//Scan jars for META-INF information //Scan jars for META-INF information
if (jars != null) if (jars != null)
{ {
for (Resource r : jars) for (Resource r : jars)
{ {
URI uri = r.getURI();
Resource fragXml = Resource.newResource("jar:"+uri+"!/META-INF/web-fragment.xml");
if (fragXml.exists())
{
//add mapping for resource->fragment
Map<Resource, Resource> fragments = (Map<Resource,Resource>)context.getAttribute(METAINF_FRAGMENTS);
if (fragments == null)
{
fragments = new HashMap<Resource, Resource>();
context.setAttribute(METAINF_FRAGMENTS, fragments);
}
fragments.put(r, fragXml);
}
Resource resourcesDir = Resource.newResource("jar:"+uri+"!/META-INF/resources"); scanForResources(context, r, metaInfResourceCache);
if (resourcesDir.exists()) scanForFragment(context, r, metaInfFragmentCache);
{ scanForTlds(context, r, metaInfTldCache);
//add resources dir
Set<Resource> dirs = (Set<Resource>)context.getAttribute(METAINF_RESOURCES);
if (dirs == null)
{
dirs = new HashSet<Resource>();
context.setAttribute(METAINF_RESOURCES, dirs);
}
dirs.add(resourcesDir);
}
} }
} }
} }
/**
* Scan for META-INF/resources dir in the given jar.
*
* @param context
* @param jar
* @param cache
* @throws Exception
*/
public void scanForResources (WebAppContext context, Resource jar, ConcurrentHashMap<Resource,Resource> cache)
throws Exception
{
Resource resourcesDir = null;
if (cache != null && cache.containsKey(jar))
{
resourcesDir = cache.get(jar);
if (resourcesDir == EmptyResource.INSTANCE)
{
if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no META-INF/resources");
return;
}
else
if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/resources found in cache ");
}
else
{
//not using caches or not in the cache so check for the resources dir
if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/resources checked");
URI uri = jar.getURI();
resourcesDir = Resource.newResource("jar:"+uri+"!/META-INF/resources");
if (!resourcesDir.exists() || !resourcesDir.isDirectory())
resourcesDir = EmptyResource.INSTANCE;
if (cache != null)
{
Resource old = cache.putIfAbsent(jar, resourcesDir);
if (old != null)
resourcesDir = old;
else
if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/resources cache updated");
}
if (resourcesDir == EmptyResource.INSTANCE)
return;
}
//add it to the meta inf resources for this context
Set<Resource> dirs = (Set<Resource>)context.getAttribute(METAINF_RESOURCES);
if (dirs == null)
{
dirs = new HashSet<Resource>();
context.setAttribute(METAINF_RESOURCES, dirs);
}
if (LOG.isDebugEnabled()) LOG.debug(resourcesDir+" added to context");
dirs.add(resourcesDir);
}
/**
* Scan for META-INF/web-fragment.xml file in the given jar.
*
* @param context
* @param jar
* @param cache
* @throws Exception
*/
public void scanForFragment (WebAppContext context, Resource jar, ConcurrentHashMap<Resource,Resource> cache)
throws Exception
{
Resource webFrag = null;
if (cache != null && cache.containsKey(jar))
{
webFrag = cache.get(jar);
if (webFrag == EmptyResource.INSTANCE)
{
if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no META-INF/web-fragment.xml");
return;
}
else
if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml found in cache ");
}
else
{
//not using caches or not in the cache so check for the web-fragment.xml
if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml checked");
URI uri = jar.getURI();
webFrag = Resource.newResource("jar:"+uri+"!/META-INF/web-fragment.xml");
if (!webFrag.exists() || webFrag.isDirectory())
webFrag = EmptyResource.INSTANCE;
if (cache != null)
{
//web-fragment.xml doesn't exist: put token in cache to signal we've seen the jar
Resource old = cache.putIfAbsent(jar, webFrag);
if (old != null)
webFrag = old;
else
if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml cache updated");
}
if (webFrag == EmptyResource.INSTANCE)
return;
}
Map<Resource, Resource> fragments = (Map<Resource,Resource>)context.getAttribute(METAINF_FRAGMENTS);
if (fragments == null)
{
fragments = new HashMap<Resource, Resource>();
context.setAttribute(METAINF_FRAGMENTS, fragments);
}
fragments.put(jar, webFrag);
if (LOG.isDebugEnabled()) LOG.debug(webFrag+" added to context");
}
/**
* Discover META-INF/*.tld files in the given jar
*
* @param context
* @param jar
* @param cache
* @throws Exception
*/
public void scanForTlds (WebAppContext context, Resource jar, ConcurrentHashMap<Resource, Collection<URL>> cache)
throws Exception
{
Collection<URL> tlds = null;
if (cache != null && cache.containsKey(jar))
{
Collection<URL> tmp = cache.get(jar);
if (tmp.isEmpty())
{
if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no tlds");
return;
}
else
{
tlds = tmp;
if (LOG.isDebugEnabled()) LOG.debug(jar+" tlds found in cache ");
}
}
else
{
//not using caches or not in the cache so find all tlds
URI uri = jar.getURI();
Resource metaInfDir = Resource.newResource("jar:"+uri+"!/META-INF/");
//find any *.tld files inside META-INF or subdirs
tlds = new HashSet<URL>();
Collection<Resource> resources = metaInfDir.getAllResources();
for (Resource t:resources)
{
String name = t.toString();
if (name.endsWith(".tld"))
{
if (LOG.isDebugEnabled()) LOG.debug(t+" tld discovered");
tlds.add(t.getURL());
}
}
if (cache != null)
{
if (LOG.isDebugEnabled()) LOG.debug(jar+" tld cache updated");
Collection<URL> old = (Collection<URL>)cache.putIfAbsent(jar, tlds);
if (old != null)
tlds = old;
}
if (tlds.isEmpty())
return;
}
Collection<URL> tld_resources=(Collection<URL>)context.getAttribute(METAINF_TLDS);
if (tld_resources == null)
{
tld_resources = new HashSet<URL>();
context.setAttribute(METAINF_TLDS, tld_resources);
}
tld_resources.addAll(tlds);
if (LOG.isDebugEnabled()) LOG.debug("tlds added to context");
}
@Override @Override
public void postConfigure(WebAppContext context) throws Exception public void postConfigure(WebAppContext context) throws Exception

View File

@ -20,12 +20,15 @@ package org.eclipse.jetty.webapp;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.EventListener; import java.util.EventListener;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
@ -67,11 +70,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor"; public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor";
final Map<String,FilterHolder> _filterHolders = new HashMap<>();
final List<FilterMapping> _filterMappings = new ArrayList<>();
final Map<String,ServletHolder> _servletHolders = new HashMap<>();
final List<ServletMapping> _servletMappings = new ArrayList<>();
public StandardDescriptorProcessor () public StandardDescriptorProcessor ()
{ {
try try
{ {
registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature)); registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature));
@ -107,15 +112,32 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
*/ */
public void start(WebAppContext context, Descriptor descriptor) public void start(WebAppContext context, Descriptor descriptor)
{ {
for (FilterHolder h : context.getServletHandler().getFilters())
_filterHolders.put(h.getName(),h);
if (context.getServletHandler().getFilterMappings()!=null)
_filterMappings.addAll(Arrays.asList(context.getServletHandler().getFilterMappings()));
for (ServletHolder h : context.getServletHandler().getServlets())
_servletHolders.put(h.getName(),h);
if (context.getServletHandler().getServletMappings()!=null)
_servletMappings.addAll(Arrays.asList(context.getServletHandler().getServletMappings()));
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void end(WebAppContext context, Descriptor descriptor) public void end(WebAppContext context, Descriptor descriptor)
{ {
context.getServletHandler().setFilters(_filterHolders.values().toArray(new FilterHolder[_filterHolders.size()]));
context.getServletHandler().setServlets(_servletHolders.values().toArray(new ServletHolder[_servletHolders.size()]));
context.getServletHandler().setFilterMappings(_filterMappings.toArray(new FilterMapping[_filterMappings.size()]));
context.getServletHandler().setServletMappings(_servletMappings.toArray(new ServletMapping[_servletMappings.size()]));
_filterHolders.clear();
_filterMappings.clear();
_servletHolders.clear();
_servletMappings.clear();
} }
/** /**
@ -194,17 +216,15 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String id = node.getAttribute("id"); String id = node.getAttribute("id");
// initialize holder // initialize holder
String servlet_name = node.getString("servlet-name", false, true); String name = node.getString("servlet-name", false, true);
ServletHolder holder = context.getServletHandler().getServlet(servlet_name); ServletHolder holder = _servletHolders.get(name);
/* //If servlet of that name does not already exist, create it.
* If servlet of that name does not already exist, create it.
*/
if (holder == null) if (holder == null)
{ {
holder = context.getServletHandler().newServletHolder(Source.DESCRIPTOR); holder = context.getServletHandler().newServletHolder(Source.DESCRIPTOR);
holder.setName(servlet_name); holder.setName(name);
context.getServletHandler().addServlet(holder); _servletHolders.put(name,holder);
} }
// init params // init params
@ -214,7 +234,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next(); XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
String pname = paramNode.getString("param-name", false, true); String pname = paramNode.getString("param-name", false, true);
String pvalue = paramNode.getString("param-value", false, true); String pvalue = paramNode.getString("param-value", false, true);
String originName = servlet_name+".servlet.init-param."+pname; String originName = name+".servlet.init-param."+pname;
Descriptor originDescriptor = context.getMetaData().getOriginDescriptor(originName); Descriptor originDescriptor = context.getMetaData().getOriginDescriptor(originName);
switch (context.getMetaData().getOrigin(originName)) switch (context.getMetaData().getOrigin(originName))
@ -283,13 +303,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (servlet_class != null) if (servlet_class != null)
{ {
((WebDescriptor)descriptor).addClassName(servlet_class); ((WebDescriptor)descriptor).addClassName(servlet_class);
switch (context.getMetaData().getOrigin(servlet_name+".servlet.servlet-class")) switch (context.getMetaData().getOrigin(name+".servlet.servlet-class"))
{ {
case NotSet: case NotSet:
{ {
//the class of the servlet has not previously been set, so set it //the class of the servlet has not previously been set, so set it
holder.setClassName(servlet_class); holder.setClassName(servlet_class);
context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor); context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -300,7 +320,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.setClassName(servlet_class); holder.setClassName(servlet_class);
context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor); context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor);
} }
break; break;
} }
@ -319,12 +339,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
// Handle JSP file // Handle JSP file
String jsp_file = node.getString("jsp-file", false, true); String jsp_file = node.getString("jsp-file", false, true);
if (jsp_file != null) if (jsp_file != null)
{
holder.setForcedPath(jsp_file); holder.setForcedPath(jsp_file);
ServletHolder jsp=context.getServletHandler().getServlet("jsp");
if (jsp!=null)
holder.setClassName(jsp.getClassName());
}
// handle load-on-startup // handle load-on-startup
XmlParser.Node startup = node.get("load-on-startup"); XmlParser.Node startup = node.get("load-on-startup");
@ -350,13 +365,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
} }
} }
switch (context.getMetaData().getOrigin(servlet_name+".servlet.load-on-startup")) switch (context.getMetaData().getOrigin(name+".servlet.load-on-startup"))
{ {
case NotSet: case NotSet:
{ {
//not already set, so set it now //not already set, so set it now
holder.setInitOrder(order); holder.setInitOrder(order);
context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor); context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -367,7 +382,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.setInitOrder(order); holder.setInitOrder(order);
context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor); context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor);
} }
break; break;
} }
@ -392,13 +407,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0) if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
{ {
if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this); if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this);
switch (context.getMetaData().getOrigin(servlet_name+".servlet.role-name."+roleName)) switch (context.getMetaData().getOrigin(name+".servlet.role-name."+roleName))
{ {
case NotSet: case NotSet:
{ {
//set it //set it
holder.setUserRoleLink(roleName, roleLink); holder.setUserRoleLink(roleName, roleLink);
context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor); context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -409,14 +424,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.setUserRoleLink(roleName, roleLink); holder.setUserRoleLink(roleName, roleLink);
context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor); context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor);
} }
break; break;
} }
case WebFragment: case WebFragment:
{ {
if (!holder.getUserRoleLink(roleName).equals(roleLink)) if (!holder.getUserRoleLink(roleName).equals(roleLink))
throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+name+" in "+descriptor.getResource());
break; break;
} }
default: default:
@ -437,13 +452,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (roleName != null) if (roleName != null)
{ {
switch (context.getMetaData().getOrigin(servlet_name+".servlet.run-as")) switch (context.getMetaData().getOrigin(name+".servlet.run-as"))
{ {
case NotSet: case NotSet:
{ {
//run-as not set, so set it //run-as not set, so set it
holder.setRunAsRole(roleName); holder.setRunAsRole(roleName);
context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor); context.getMetaData().setOrigin(name+".servlet.run-as", descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -454,7 +469,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.setRunAsRole(roleName); holder.setRunAsRole(roleName);
context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor); context.getMetaData().setOrigin(name+".servlet.run-as", descriptor);
} }
break; break;
} }
@ -462,7 +477,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{ {
//run-as was set by another fragment, this fragment must show the same value //run-as was set by another fragment, this fragment must show the same value
if (!holder.getRunAsRole().equals(roleName)) if (!holder.getRunAsRole().equals(roleName))
throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+name+" in "+descriptor.getResource());
break; break;
} }
default: default:
@ -475,13 +490,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (async!=null) if (async!=null)
{ {
boolean val = async.length()==0||Boolean.valueOf(async); boolean val = async.length()==0||Boolean.valueOf(async);
switch (context.getMetaData().getOrigin(servlet_name+".servlet.async-supported")) switch (context.getMetaData().getOrigin(name+".servlet.async-supported"))
{ {
case NotSet: case NotSet:
{ {
//set it //set it
holder.setAsyncSupported(val); holder.setAsyncSupported(val);
context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor); context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -492,7 +507,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.setAsyncSupported(val); holder.setAsyncSupported(val);
context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor); context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor);
} }
break; break;
} }
@ -500,7 +515,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{ {
//async-supported set by another fragment, this fragment's value must match //async-supported set by another fragment, this fragment's value must match
if (holder.isAsyncSupported() != val) if (holder.isAsyncSupported() != val)
throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+name+" in "+descriptor.getResource());
break; break;
} }
default: default:
@ -512,13 +527,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (enabled!=null) if (enabled!=null)
{ {
boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled); boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled);
switch (context.getMetaData().getOrigin(servlet_name+".servlet.enabled")) switch (context.getMetaData().getOrigin(name+".servlet.enabled"))
{ {
case NotSet: case NotSet:
{ {
//hasn't been set yet, so set it //hasn't been set yet, so set it
holder.setEnabled(is_enabled); holder.setEnabled(is_enabled);
context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor); context.getMetaData().setOrigin(name+".servlet.enabled", descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -529,7 +544,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.setEnabled(is_enabled); holder.setEnabled(is_enabled);
context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor); context.getMetaData().setOrigin(name+".servlet.enabled", descriptor);
} }
break; break;
} }
@ -537,7 +552,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{ {
//was set by another fragment, this fragment's value must match //was set by another fragment, this fragment's value must match
if (holder.isEnabled() != is_enabled) if (holder.isEnabled() != is_enabled)
throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+name+" in "+descriptor.getResource());
break; break;
} }
default: default:
@ -562,13 +577,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
(maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)), (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
(threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold))); (threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
switch (context.getMetaData().getOrigin(servlet_name+".servlet.multipart-config")) switch (context.getMetaData().getOrigin(name+".servlet.multipart-config"))
{ {
case NotSet: case NotSet:
{ {
//hasn't been set, so set it //hasn't been set, so set it
holder.getRegistration().setMultipartConfig(element); holder.getRegistration().setMultipartConfig(element);
context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor); context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor);
break; break;
} }
case WebXml: case WebXml:
@ -579,7 +594,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (!(descriptor instanceof FragmentDescriptor)) if (!(descriptor instanceof FragmentDescriptor))
{ {
holder.getRegistration().setMultipartConfig(element); holder.getRegistration().setMultipartConfig(element);
context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor); context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor);
} }
break; break;
} }
@ -589,14 +604,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig(); MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig();
if (cfg.getMaxFileSize() != element.getMaxFileSize()) if (cfg.getMaxFileSize() != element.getMaxFileSize())
throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+name+" in "+descriptor.getResource());
if (cfg.getMaxRequestSize() != element.getMaxRequestSize()) if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+name+" in "+descriptor.getResource());
if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold()) if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+name+" in "+descriptor.getResource());
if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0)) if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0))
|| (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0))) || (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0)))
throw new IllegalStateException("Conflicting multipart-config location for servlet "+servlet_name+" in "+descriptor.getResource()); throw new IllegalStateException("Conflicting multipart-config location for servlet "+name+" in "+descriptor.getResource());
break; break;
} }
default: default:
@ -1236,7 +1251,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor); context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor);
} }
mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()])); mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
context.getServletHandler().addServletMapping(mapping); _servletMappings.add(mapping);
return mapping; return mapping;
} }
@ -1282,7 +1297,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (dispatches.size()>0) if (dispatches.size()>0)
mapping.setDispatcherTypes(EnumSet.copyOf(dispatches)); mapping.setDispatcherTypes(EnumSet.copyOf(dispatches));
context.getServletHandler().addFilterMapping(mapping); _filterMappings.add(mapping);
} }
@ -1386,11 +1401,11 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
if (paths.size() > 0) if (paths.size() > 0)
{ {
ServletHandler handler = context.getServletHandler(); ServletHandler handler = context.getServletHandler();
ServletHolder jsp_pg_servlet = handler.getServlet(JspPropertyGroupServlet.NAME); ServletHolder jsp_pg_servlet = _servletHolders.get(JspPropertyGroupServlet.NAME);
if (jsp_pg_servlet==null) if (jsp_pg_servlet==null)
{ {
jsp_pg_servlet=new ServletHolder(JspPropertyGroupServlet.NAME,new JspPropertyGroupServlet(context,handler)); jsp_pg_servlet=new ServletHolder(JspPropertyGroupServlet.NAME,new JspPropertyGroupServlet(context,handler));
handler.addServlet(jsp_pg_servlet); _servletHolders.put(JspPropertyGroupServlet.NAME,jsp_pg_servlet);
} }
ServletMapping mapping = new ServletMapping(); ServletMapping mapping = new ServletMapping();
@ -1706,12 +1721,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
protected void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node) protected void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
{ {
String name = node.getString("filter-name", false, true); String name = node.getString("filter-name", false, true);
FilterHolder holder = context.getServletHandler().getFilter(name); FilterHolder holder = _filterHolders.get(name);
if (holder == null) if (holder == null)
{ {
holder = context.getServletHandler().newFilterHolder(Source.DESCRIPTOR); holder = context.getServletHandler().newFilterHolder(Source.DESCRIPTOR);
holder.setName(name); holder.setName(name);
context.getServletHandler().addFilter(holder); _filterHolders.put(name,holder);
} }
String filter_class = node.getString("filter-class", false, true); String filter_class = node.getString("filter-class", false, true);

View File

@ -132,6 +132,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
"-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet "-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet
"-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners "-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners
"-org.eclipse.jetty.websocket.", // don't hide websocket classes from webapps (allow webapp to use ones from system classloader) "-org.eclipse.jetty.websocket.", // don't hide websocket classes from webapps (allow webapp to use ones from system classloader)
"-org.eclipse.jetty.apache.", // don't jetty apache impls
"org.eclipse.jetty." // hide other jetty classes "org.eclipse.jetty." // hide other jetty classes
} ; } ;

View File

@ -20,27 +20,45 @@ package org.eclipse.jetty.xml;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
public class XmlAppendable public class XmlAppendable
{ {
private final String SPACES=" "; private final String SPACES=" ";
private final Appendable _out; private final Appendable _out;
private final int _indent; private final int _indent;
private final Stack<String> _tags = new Stack<>(); private final Stack<String> _tags = new Stack<>();
private String _space=""; private String _space="";
public XmlAppendable(OutputStream out,String encoding) throws IOException
{
this(new OutputStreamWriter(out,encoding),encoding);
}
public XmlAppendable(Appendable out) throws IOException public XmlAppendable(Appendable out) throws IOException
{ {
this(out,2); this(out,2);
} }
public XmlAppendable(Appendable out,String encoding) throws IOException
{
this(out,2,encoding);
}
public XmlAppendable(Appendable out, int indent) throws IOException public XmlAppendable(Appendable out, int indent) throws IOException
{
this(out,indent,"UTF-8");
}
public XmlAppendable(Appendable out, int indent, String encoding) throws IOException
{ {
_out=out; _out=out;
_indent=indent; _indent=indent;
_out.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); _out.append("<?xml version=\"1.0\" encoding=\""+encoding+"\"?>\n");
} }
public XmlAppendable open(String tag, Map<String,String> attributes) throws IOException public XmlAppendable open(String tag, Map<String,String> attributes) throws IOException
@ -123,6 +141,14 @@ public class XmlAppendable
return this; return this;
} }
public XmlAppendable tagCDATA(String tag,String data) throws IOException
{
_out.append(_space).append('<').append(tag).append('>');
cdata(data);
_out.append("</").append(tag).append(">\n");
return this;
}
public XmlAppendable tag(String tag, Map<String,String> attributes,String content) throws IOException public XmlAppendable tag(String tag, Map<String,String> attributes,String content) throws IOException
{ {
_out.append(_space).append('<').append(tag); _out.append(_space).append('<').append(tag);

View File

@ -49,6 +49,6 @@ public class XmlAppendableTest
out.close(); out.close();
String s = b.toString(); String s = b.toString();
Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n <tag/>\n <tag quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\"/>\n <tag quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\">content</tag>\n <level1>\n <tag>content</tag>\n <tag>content</tag>\n </level1>\n <level1 quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\">\n <level2>\n <tag>content</tag>\n <tag>content</tag>\n </level2>\n </level1>\n</test>\n",s); Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n <tag/>\n <tag quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\"/>\n <tag quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\">content</tag>\n <level1>\n <tag>content</tag>\n <tag>content</tag>\n </level1>\n <level1 quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\">\n <level2>\n <tag>content</tag>\n <tag>content</tag>\n </level2>\n </level1>\n</test>\n",s);
} }
} }