From 96fe2d6c3fc1337d359a9900f176363d8c775b6c Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 4 Jul 2012 17:11:11 +0200 Subject: [PATCH] JETTY-1523 It is imposible to map servlet to "/" using WebApplicationInitializer --- .../annotations/WebServletAnnotation.java | 54 +++++++++++++++---- .../eclipse/jetty/servlet/ServletHandler.java | 5 +- .../eclipse/jetty/servlet/ServletHolder.java | 15 ++++-- .../eclipse/jetty/servlet/ServletMapping.java | 21 ++++++++ .../webapp/StandardDescriptorProcessor.java | 6 ++- 5 files changed, 84 insertions(+), 17 deletions(-) diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java index b3cd7acd4dc..d42b6f747a0 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebServletAnnotation.java @@ -154,17 +154,53 @@ public class WebServletAnnotation extends DiscoveredAnnotation } } - //check the url-patterns, if there annotation has a new one, add it - ServletMapping[] mappings = _context.getServletHandler().getServletMappings(); - + //check the url-patterns //ServletSpec 3.0 p81 If a servlet already has url mappings from a - //descriptor the annotation is ignored - if (mappings == null && metaData.getOriginDescriptor(servletName+".servlet.mappings") != null) + //webxml or fragment descriptor the annotation is ignored. However, we want to be able to + //replace mappings that were given in webdefault.xml + boolean mappingsExist = false; + boolean anyNonDefaults = false; + ServletMapping[] allMappings = _context.getServletHandler().getServletMappings(); + if (allMappings != null) { - ServletMapping mapping = new ServletMapping(); - mapping.setServletName(servletName); - mapping.setPathSpecs(LazyList.toStringArray(urlPatternList)); - _context.getServletHandler().addServletMapping(mapping); + for (ServletMapping m:allMappings) + { + if (m.getServletName() != null && servletName.equals(m.getServletName())) + { + mappingsExist = true; + if (!m.isDefault()) + { + anyNonDefaults = true; + break; + } + } + } + } + + if (anyNonDefaults) + return; //if any mappings already set by a descriptor that is not webdefault.xml, we're done + + boolean clash = false; + if (mappingsExist) + { + for (String p:urlPatternList) + { + ServletMapping m = _context.getServletHandler().getServletMapping(p); + if (m != null && !m.isDefault()) + { + //trying to override a servlet-mapping that was added not by webdefault.xml + clash = true; + break; + } + } + } + + if (!mappingsExist || !clash) + { + ServletMapping m = new ServletMapping(); + m.setServletName(servletName); + m.setPathSpecs(LazyList.toStringArray(urlPatternList)); + _context.getServletHandler().addServletMapping(m); } } } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index 7f26612c1c2..8084896bb03 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -281,6 +281,7 @@ public class ServletHandler extends ScopedHandler */ public ServletMapping getServletMapping(String pattern) { + ServletMapping theMapping = null; if (_servletMappings!=null) { for (ServletMapping m:_servletMappings) @@ -291,12 +292,12 @@ public class ServletHandler extends ScopedHandler for (String path:paths) { if (pattern.equals(path)) - return m; + theMapping = m; } } } } - return null; + return theMapping; } /* ------------------------------------------------------------ */ diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index de3f797e167..6137600fe1d 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -705,17 +705,24 @@ public class ServletHolder extends Holder implements UserIdentity.Scope Set clash=null; for (String pattern : urlPatterns) { - if (_servletHandler.getServletMapping(pattern)!=null) + ServletMapping mapping = _servletHandler.getServletMapping(pattern); + if (mapping!=null) { - if (clash==null) - clash=new HashSet(); - clash.add(pattern); + //if the servlet mapping was from a default descriptor, then allow it to be overridden + if (!mapping.isDefault()) + { + if (clash==null) + clash=new HashSet(); + clash.add(pattern); + } } } + //if there were any clashes amongst the urls, return them if (clash!=null) return clash; + //otherwise apply all of them ServletMapping mapping = new ServletMapping(); mapping.setServletName(ServletHolder.this.getName()); mapping.setPathSpecs(urlPatterns); diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java index e8e133d541d..27af5fa4001 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletMapping.java @@ -21,6 +21,8 @@ public class ServletMapping { private String[] _pathSpecs; private String _servletName; + private boolean _default; + /* ------------------------------------------------------------ */ public ServletMapping() @@ -72,6 +74,25 @@ public class ServletMapping _servletName = servletName; } + + /* ------------------------------------------------------------ */ + /** + * @return + */ + public boolean isDefault() + { + return _default; + } + + + /* ------------------------------------------------------------ */ + /** + * @param default1 + */ + public void setDefault(boolean fromDefault) + { + _default = fromDefault; + } /* ------------------------------------------------------------ */ public String toString() 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 cd2a3c54e48..5d9630f056c 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 @@ -621,7 +621,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor { //no servlet mappings context.getMetaData().setOrigin(servlet_name+".servlet.mappings", descriptor); - addServletMapping(servlet_name, node, context); + ServletMapping mapping = addServletMapping(servlet_name, node, context); + mapping.setDefault(context.getMetaData().getOrigin(servlet_name+".servlet.mappings") == Origin.WebDefaults); break; } case WebXml: @@ -1164,7 +1165,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor * @param node * @param context */ - protected void addServletMapping (String servletName, XmlParser.Node node, WebAppContext context) + protected ServletMapping addServletMapping (String servletName, XmlParser.Node node, WebAppContext context) { ServletMapping mapping = new ServletMapping(); mapping.setServletName(servletName); @@ -1179,6 +1180,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor } mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()])); context.getServletHandler().addServletMapping(mapping); + return mapping; } /**