From b3be24742353f7b5880fa8229a20ed0b19058cac Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 14 Mar 2014 13:07:00 +1100 Subject: [PATCH] merged quickstart changes --- jetty-annotations/pom.xml | 5 - .../annotations/AnnotationConfiguration.java | 4 +- jetty-plus/src/main/config/modules/plus.mod | 1 + .../plus/annotation/ContainerInitializer.java | 40 +-- .../eclipse/jetty/servlet/ServletHandler.java | 1 - .../eclipse/jetty/servlet/ServletHolder.java | 27 ++ jetty-webapp/pom.xml | 17 -- .../jetty/webapp/MetaInfConfiguration.java | 281 ++++++++++++++++-- .../webapp/StandardDescriptorProcessor.java | 117 ++++---- .../eclipse/jetty/webapp/WebAppContext.java | 1 + .../org/eclipse/jetty/xml/XmlAppendable.java | 30 +- .../eclipse/jetty/xml/XmlAppendableTest.java | 2 +- 12 files changed, 395 insertions(+), 131 deletions(-) diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 34aefc907e7..23621354f30 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -72,11 +72,6 @@ - - org.eclipse.jetty.toolchain - jetty-test-helper - test - org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index 9eb87351e49..4845caaa591 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -447,7 +447,7 @@ public class AnnotationConfiguration extends AbstractConfiguration { Map> map = ( Map>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP); if (map == null) - throw new IllegalStateException ("No class hierarchy"); + LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty"); for (ContainerInitializer i : initializers) 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.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(), (TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)), context); diff --git a/jetty-plus/src/main/config/modules/plus.mod b/jetty-plus/src/main/config/modules/plus.mod index d8dee1e95ea..aac0f8f3ecb 100644 --- a/jetty-plus/src/main/config/modules/plus.mod +++ b/jetty-plus/src/main/config/modules/plus.mod @@ -6,6 +6,7 @@ server security jndi +webapp [lib] lib/jetty-plus-${jetty.version}.jar diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java index 66b4ddccc0a..321a9ab7f5f 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/ContainerInitializer.java @@ -56,26 +56,26 @@ public class ContainerInitializer public ContainerInitializer (ClassLoader loader, String toString) { - Matcher m = Pattern.compile("ContainerInitializer\\{(.*),interested=(.*),applicable=(.*),annotated=(.*)\\}").matcher(toString); - if (!m.matches()) - throw new IllegalArgumentException(toString); - - try - { - _target = (ServletContainerInitializer)loader.loadClass(m.group(1)).newInstance(); - String[] interested = StringUtil.arrayFromString(m.group(2)); - _interestedTypes = new Class[interested.length]; - for (int i=0;i[interested.length]; + for (int i=0;i implements UserIdentity.Scope public void doStart() throws Exception { + + _unavailable=0; if (!_enabled) 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. try diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 7d4fc4d7862..aee5c294082 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -27,23 +27,6 @@ - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - - config - - - - - org.apache.maven.plugins maven-assembly-plugin diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java index 4dc29462dd1..8013e2cd914 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java @@ -20,76 +20,293 @@ package org.eclipse.jetty.webapp; import java.net.URI; +import java.net.URL; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.EmptyResource; import org.eclipse.jetty.util.resource.Resource; /** * MetaInfConfiguration * - * Scan META-INF of all jars in WEB-INF/lib to find: + * Scan META-INF of jars to find: *
    *
  • tlds *
  • web-fragment.xml *
  • resources *
+ * + * The jars which are scanned are: + *
    + *
  1. those from the container classpath whose pattern matched the WebInfConfiguration.CONTAINER_JAR_PATTERN
  2. + *
  3. those from WEB-INF/lib
  4. + *
*/ public class MetaInfConfiguration extends AbstractConfiguration { 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_RESOURCES = WebInfConfiguration.RESOURCE_DIRS; - + @Override 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 jars, boolean useCaches) + throws Exception { - //Merge all container and webinf lib jars to look for META-INF resources - ArrayList jars = new ArrayList(); - jars.addAll(context.getMetaData().getContainerResources()); - jars.addAll(context.getMetaData().getWebInfJars()); + ConcurrentHashMap metaInfResourceCache = null; + ConcurrentHashMap metaInfFragmentCache = null; + ConcurrentHashMap> metaInfTldCache = null; + if (useCaches) + { + metaInfResourceCache = (ConcurrentHashMap)context.getServer().getAttribute(CACHED_CONTAINER_RESOURCES); + if (metaInfResourceCache == null) + { + metaInfResourceCache = new ConcurrentHashMap(); + context.getServer().setAttribute(CACHED_CONTAINER_RESOURCES, metaInfResourceCache); + } + metaInfFragmentCache = (ConcurrentHashMap)context.getServer().getAttribute(CACHED_CONTAINER_FRAGMENTS); + if (metaInfFragmentCache == null) + { + metaInfFragmentCache = new ConcurrentHashMap(); + context.getServer().setAttribute(CACHED_CONTAINER_FRAGMENTS, metaInfFragmentCache); + } + metaInfTldCache = (ConcurrentHashMap>)context.getServer().getAttribute(CACHED_CONTAINER_TLDS); + if (metaInfTldCache == null) + { + metaInfTldCache = new ConcurrentHashMap>(); + context.getServer().setAttribute(CACHED_CONTAINER_TLDS, metaInfTldCache); + } + } //Scan jars for META-INF information if (jars != null) { 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 fragments = (Map)context.getAttribute(METAINF_FRAGMENTS); - if (fragments == null) - { - fragments = new HashMap(); - context.setAttribute(METAINF_FRAGMENTS, fragments); - } - fragments.put(r, fragXml); - } - Resource resourcesDir = Resource.newResource("jar:"+uri+"!/META-INF/resources"); - if (resourcesDir.exists()) - { - //add resources dir - Set dirs = (Set)context.getAttribute(METAINF_RESOURCES); - if (dirs == null) - { - dirs = new HashSet(); - context.setAttribute(METAINF_RESOURCES, dirs); - } - dirs.add(resourcesDir); - } + scanForResources(context, r, metaInfResourceCache); + scanForFragment(context, r, metaInfFragmentCache); + scanForTlds(context, r, metaInfTldCache); } } } + + /** + * 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 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 dirs = (Set)context.getAttribute(METAINF_RESOURCES); + if (dirs == null) + { + dirs = new HashSet(); + 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 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 fragments = (Map)context.getAttribute(METAINF_FRAGMENTS); + if (fragments == null) + { + fragments = new HashMap(); + 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> cache) + throws Exception + { + Collection tlds = null; + + if (cache != null && cache.containsKey(jar)) + { + Collection 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(); + Collection 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 old = (Collection)cache.putIfAbsent(jar, tlds); + if (old != null) + tlds = old; + } + + if (tlds.isEmpty()) + return; + } + + Collection tld_resources=(Collection)context.getAttribute(METAINF_TLDS); + if (tld_resources == null) + { + tld_resources = new HashSet(); + context.setAttribute(METAINF_TLDS, tld_resources); + } + tld_resources.addAll(tlds); + if (LOG.isDebugEnabled()) LOG.debug("tlds added to context"); + } + @Override public void postConfigure(WebAppContext context) throws Exception diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java index 15d94535121..43c33480374 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java @@ -20,12 +20,15 @@ package org.eclipse.jetty.webapp; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.EnumSet; import java.util.EventListener; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import javax.servlet.DispatcherType; @@ -67,11 +70,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor"; - + final Map _filterHolders = new HashMap<>(); + final List _filterMappings = new ArrayList<>(); + final Map _servletHolders = new HashMap<>(); + final List _servletMappings = new ArrayList<>(); public StandardDescriptorProcessor () { - try { registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature)); @@ -107,15 +112,32 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor */ 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} */ 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"); // initialize holder - String servlet_name = node.getString("servlet-name", false, true); - ServletHolder holder = context.getServletHandler().getServlet(servlet_name); + String name = node.getString("servlet-name", false, true); + 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) { holder = context.getServletHandler().newServletHolder(Source.DESCRIPTOR); - holder.setName(servlet_name); - context.getServletHandler().addServlet(holder); + holder.setName(name); + _servletHolders.put(name,holder); } // init params @@ -214,7 +234,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next(); String pname = paramNode.getString("param-name", 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); switch (context.getMetaData().getOrigin(originName)) @@ -283,13 +303,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (servlet_class != null) { ((WebDescriptor)descriptor).addClassName(servlet_class); - switch (context.getMetaData().getOrigin(servlet_name+".servlet.servlet-class")) + switch (context.getMetaData().getOrigin(name+".servlet.servlet-class")) { case NotSet: { //the class of the servlet has not previously been set, so set it holder.setClassName(servlet_class); - context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor); + context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor); break; } case WebXml: @@ -300,7 +320,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.setClassName(servlet_class); - context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor); + context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor); } break; } @@ -319,12 +339,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor // Handle JSP file String jsp_file = node.getString("jsp-file", false, true); if (jsp_file != null) - { holder.setForcedPath(jsp_file); - ServletHolder jsp=context.getServletHandler().getServlet("jsp"); - if (jsp!=null) - holder.setClassName(jsp.getClassName()); - } // handle 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: { //not already set, so set it now holder.setInitOrder(order); - context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor); + context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor); break; } case WebXml: @@ -367,7 +382,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.setInitOrder(order); - context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor); + context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor); } break; } @@ -392,13 +407,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0) { 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: { //set it holder.setUserRoleLink(roleName, roleLink); - context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor); + context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor); break; } case WebXml: @@ -409,14 +424,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.setUserRoleLink(roleName, roleLink); - context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor); + context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor); } break; } case WebFragment: { 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; } default: @@ -437,13 +452,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (roleName != null) { - switch (context.getMetaData().getOrigin(servlet_name+".servlet.run-as")) + switch (context.getMetaData().getOrigin(name+".servlet.run-as")) { case NotSet: { //run-as not set, so set it holder.setRunAsRole(roleName); - context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor); + context.getMetaData().setOrigin(name+".servlet.run-as", descriptor); break; } case WebXml: @@ -454,7 +469,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.setRunAsRole(roleName); - context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor); + context.getMetaData().setOrigin(name+".servlet.run-as", descriptor); } break; } @@ -462,7 +477,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { //run-as was set by another fragment, this fragment must show the same value 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; } default: @@ -475,13 +490,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (async!=null) { 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: { //set it holder.setAsyncSupported(val); - context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor); + context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor); break; } case WebXml: @@ -492,7 +507,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.setAsyncSupported(val); - context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor); + context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor); } break; } @@ -500,7 +515,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { //async-supported set by another fragment, this fragment's value must match 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; } default: @@ -512,13 +527,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (enabled!=null) { 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: { //hasn't been set yet, so set it holder.setEnabled(is_enabled); - context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor); + context.getMetaData().setOrigin(name+".servlet.enabled", descriptor); break; } case WebXml: @@ -529,7 +544,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.setEnabled(is_enabled); - context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor); + context.getMetaData().setOrigin(name+".servlet.enabled", descriptor); } break; } @@ -537,7 +552,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { //was set by another fragment, this fragment's value must match 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; } default: @@ -562,13 +577,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)), (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: { //hasn't been set, so set it holder.getRegistration().setMultipartConfig(element); - context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor); + context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor); break; } case WebXml: @@ -579,7 +594,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (!(descriptor instanceof FragmentDescriptor)) { holder.getRegistration().setMultipartConfig(element); - context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor); + context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor); } break; } @@ -589,14 +604,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig(); 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()) - 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()) - 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)) || (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; } default: @@ -1236,7 +1251,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor); } mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()])); - context.getServletHandler().addServletMapping(mapping); + _servletMappings.add(mapping); return mapping; } @@ -1282,7 +1297,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor if (dispatches.size()>0) 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) { 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) { 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(); @@ -1706,12 +1721,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor protected void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node) { String name = node.getString("filter-name", false, true); - FilterHolder holder = context.getServletHandler().getFilter(name); + FilterHolder holder = _filterHolders.get(name); if (holder == null) { holder = context.getServletHandler().newFilterHolder(Source.DESCRIPTOR); holder.setName(name); - context.getServletHandler().addFilter(holder); + _filterHolders.put(name,holder); } String filter_class = node.getString("filter-class", false, true); diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 2a54dcc90e1..d0d65f2856a 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -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.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.apache.", // don't jetty apache impls "org.eclipse.jetty." // hide other jetty classes } ; diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java index 4ea400fb1cd..79711a66a0b 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java @@ -20,27 +20,45 @@ package org.eclipse.jetty.xml; import java.io.Closeable; import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.util.Map; import java.util.Stack; public class XmlAppendable { - private final String SPACES=" "; + private final String SPACES=" "; private final Appendable _out; private final int _indent; private final Stack _tags = new Stack<>(); private String _space=""; + + public XmlAppendable(OutputStream out,String encoding) throws IOException + { + this(new OutputStreamWriter(out,encoding),encoding); + } public XmlAppendable(Appendable out) throws IOException { this(out,2); } + public XmlAppendable(Appendable out,String encoding) throws IOException + { + this(out,2,encoding); + } + 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; _indent=indent; - _out.append("\n"); + _out.append("\n"); } public XmlAppendable open(String tag, Map attributes) throws IOException @@ -123,6 +141,14 @@ public class XmlAppendable return this; } + public XmlAppendable tagCDATA(String tag,String data) throws IOException + { + _out.append(_space).append('<').append(tag).append('>'); + cdata(data); + _out.append("\n"); + return this; + } + public XmlAppendable tag(String tag, Map attributes,String content) throws IOException { _out.append(_space).append('<').append(tag); diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java index d1f6867584f..2639b10deac 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java @@ -49,6 +49,6 @@ public class XmlAppendableTest out.close(); String s = b.toString(); - Assert.assertEquals("\n\n \n \n content\n \n content\n content\n \n \n \n content\n content\n \n \n\n",s); + Assert.assertEquals("\n\n \n \n content\n \n content\n content\n \n \n \n content\n content\n \n \n\n",s); } }