diff options
author | Greg Wilkins | 2014-02-13 01:31:14 +0000 |
---|---|---|
committer | Greg Wilkins | 2014-02-13 01:31:14 +0000 |
commit | 18e19260ff2a0f99b7c935177287c77aa2c5588d (patch) | |
tree | 90a7a84a11880a876999ba038ee4156063050e3c | |
parent | 1eb87fdddc1a7b68b9609b61b91ae5255dcba55b (diff) | |
download | org.eclipse.jetty.project-18e19260ff2a0f99b7c935177287c77aa2c5588d.tar.gz org.eclipse.jetty.project-18e19260ff2a0f99b7c935177287c77aa2c5588d.tar.xz org.eclipse.jetty.project-18e19260ff2a0f99b7c935177287c77aa2c5588d.zip |
Apply changes resulting from the quickstart project
28 files changed, 783 insertions, 305 deletions
diff --git a/.gitignore b/.gitignore index 7966828f43..ff5ed7e2d1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .classpath .project .settings +.gitignore # maven target/ 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 87459b3fe3..541ac475ba 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 @@ -438,18 +438,29 @@ public class AnnotationConfiguration extends AbstractConfiguration createServletContainerInitializerAnnotationHandlers(context, getNonExcludedInitializers(context)); if (!_discoverableAnnotationHandlers.isEmpty() || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty()) - scanForAnnotations(context); + scanForAnnotations(context); + + // Resolve container initializers + List<ContainerInitializer> initializers = + (List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS); + if (initializers != null && initializers.size()>0) + { + Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP); + if (map == null) + throw new IllegalStateException ("No class hierarchy"); + for (ContainerInitializer i : initializers) + i.resolveClasses(context,map); + } } - /** * @see org.eclipse.jetty.webapp.AbstractConfiguration#postConfigure(org.eclipse.jetty.webapp.WebAppContext) */ @Override public void postConfigure(WebAppContext context) throws Exception { - ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap = (ConcurrentHashMap<String, ConcurrentHashSet<String>>)context.getAttribute(CLASS_INHERITANCE_MAP); + ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap = (ClassInheritanceMap)context.getAttribute(CLASS_INHERITANCE_MAP); List<ContainerInitializer> initializers = (List<ContainerInitializer>)context.getAttribute(CONTAINER_INITIALIZERS); context.removeAttribute(CLASS_INHERITANCE_MAP); @@ -655,7 +666,7 @@ public class AnnotationConfiguration extends AbstractConfiguration if (annotation != null) { //There is a HandlesTypes annotation on the on the ServletContainerInitializer - Class[] classes = annotation.value(); + Class<?>[] classes = annotation.value(); if (classes != null) { initializer = new ContainerInitializer(service, classes); @@ -665,12 +676,12 @@ public class AnnotationConfiguration extends AbstractConfiguration if (context.getAttribute(CLASS_INHERITANCE_MAP) == null) { //MultiMap<String> map = new MultiMap<>(); - ConcurrentHashMap<String, ConcurrentHashSet<String>> map = new ConcurrentHashMap<String, ConcurrentHashSet<String>>(); + ConcurrentHashMap<String, ConcurrentHashSet<String>> map = new ClassInheritanceMap(); context.setAttribute(CLASS_INHERITANCE_MAP, map); _classInheritanceHandler = new ClassInheritanceHandler(map); } - for (Class c: classes) + for (Class<?> c: classes) { //The value of one of the HandlesTypes classes is actually an Annotation itself so //register a handler for it @@ -1044,4 +1055,16 @@ public class AnnotationConfiguration extends AbstractConfiguration { return (d!=null && d.getMetaDataComplete() == MetaDataComplete.True); } + + public static class ClassInheritanceMap extends ConcurrentHashMap<String, ConcurrentHashSet<String>> + { + + @Override + public String toString() + { + return String.format("ClassInheritanceMap@%x{size=%d}",hashCode(),size()); + } + } } + + diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java index eb49af7c6c..5e789126e9 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/MultiPartConfigAnnotationHandler.java @@ -70,7 +70,7 @@ public class MultiPartConfigAnnotationHandler extends AbstractIntrospectableAnno //let the annotation override it if (d == null) { - metaData.setOrigin(holder.getName()+".servlet.multipart-config"); + metaData.setOrigin(holder.getName()+".servlet.multipart-config",multi,clazz); holder.getRegistration().setMultipartConfig(new MultipartConfigElement(multi)); } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java index 8c637f69a4..b37a4dab52 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ResourceAnnotationHandler.java @@ -180,7 +180,7 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH injections.add(injection); //TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination - metaData.setOrigin("resource-ref."+name+".injection"); + metaData.setOrigin("resource-ref."+name+".injection",resource,clazz); } else if (!Util.isEnvEntryType(type)) { @@ -334,7 +334,7 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH injection.setMappingName(mappedName); injections.add(injection); //TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination - metaData.setOrigin("resource-ref."+name+".injection"); + metaData.setOrigin("resource-ref."+name+".injection",resource,clazz); } else if (!Util.isEnvEntryType(paramType)) { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java index 37589b8dd1..a2db0a7f5d 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/RunAsAnnotationHandler.java @@ -64,7 +64,7 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand //let the annotation override it if (d == null) { - metaData.setOrigin(holder.getName()+".servlet.run-as"); + metaData.setOrigin(holder.getName()+".servlet.run-as",runAs,clazz); org.eclipse.jetty.plus.annotation.RunAs ra = new org.eclipse.jetty.plus.annotation.RunAs(); ra.setTargetClassName(clazz.getCanonicalName()); ra.setRoleName(role); diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java index f38b3792e5..2ebaa9623a 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializersStarter.java @@ -59,14 +59,9 @@ public class ServletContainerInitializersStarter extends AbstractLifeCycle imple List<ContainerInitializer> initializers = (List<ContainerInitializer>)_context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS); if (initializers == null) return; - - ConcurrentHashMap<String, ConcurrentHashSet<String>> map = ( ConcurrentHashMap<String, ConcurrentHashSet<String>>)_context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP); for (ContainerInitializer i : initializers) { - configureHandlesTypes(_context, i, map); - - //instantiate ServletContainerInitializers, call doStart try { if (LOG.isDebugEnabled()) @@ -80,82 +75,6 @@ public class ServletContainerInitializersStarter extends AbstractLifeCycle imple } } } - - - private void configureHandlesTypes (WebAppContext context, ContainerInitializer initializer, ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap) - { - doHandlesTypesAnnotations(context, initializer, classMap); - doHandlesTypesClasses(context, initializer, classMap); - } - - private void doHandlesTypesAnnotations(WebAppContext context, ContainerInitializer initializer, ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap) - { - if (initializer == null) - return; - if (context == null) - throw new IllegalArgumentException("WebAppContext null"); - - //We have already found the classes that directly have an annotation that was in the HandlesTypes - //annotation of the ServletContainerInitializer. For each of those classes, walk the inheritance - //hierarchy to find classes that extend or implement them. - Set<String> annotatedClassNames = initializer.getAnnotatedTypeNames(); - if (annotatedClassNames != null && !annotatedClassNames.isEmpty()) - { - if (classMap == null) - throw new IllegalStateException ("No class hierarchy"); - - for (String name : annotatedClassNames) - { - //add the class that has the annotation - initializer.addApplicableTypeName(name); - - //find and add the classes that inherit the annotation - addInheritedTypes(classMap, initializer, (ConcurrentHashSet<String>)classMap.get(name)); - } - } - } - - - - private void doHandlesTypesClasses (WebAppContext context, ContainerInitializer initializer, ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap) - { - if (initializer == null) - return; - if (context == null) - throw new IllegalArgumentException("WebAppContext null"); - - //Now we need to look at the HandlesTypes classes that were not annotations. We need to - //find all classes that extend or implement them. - if (initializer.getInterestedTypes() != null) - { - if (classMap == null) - throw new IllegalStateException ("No class hierarchy"); - - for (Class c : initializer.getInterestedTypes()) - { - if (!c.isAnnotation()) - { - //find and add the classes that implement or extend the class. - //but not including the class itself - addInheritedTypes(classMap, initializer, (ConcurrentHashSet<String>)classMap.get(c.getName())); - } - } - } - } - private void addInheritedTypes (ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap, ContainerInitializer initializer, ConcurrentHashSet<String> names) - { - if (names == null || names.isEmpty()) - return; - - for (String s : names) - { - //add the name of the class - initializer.addApplicableTypeName(s); - - //walk the hierarchy and find all types that extend or implement the class - addInheritedTypes(classMap, initializer, (ConcurrentHashSet<String>)classMap.get(s)); - } - } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java index 8c198a63ae..743826793a 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletSecurityAnnotationHandler.java @@ -102,7 +102,7 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno { for (String url : sm.getPathSpecs()) { - _context.getMetaData().setOrigin("constraint.url."+url, Origin.Annotation); + _context.getMetaData().setOrigin("constraint.url."+url,servletSecurity,clazz); constraintMappings.addAll(ConstraintSecurityHandler.createConstraintsWithMappingsForPath(clazz.getName(), url, securityElement)); } } diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java index 25dd8ee3f7..9b312d2751 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebFilterAnnotation.java @@ -104,15 +104,15 @@ public class WebFilterAnnotation extends DiscoveredAnnotation holder.setName(name); holder.setHeldClass(clazz); - metaData.setOrigin(name+".filter.filter-class"); + metaData.setOrigin(name+".filter.filter-class",filterAnnotation,clazz); holder.setDisplayName(filterAnnotation.displayName()); - metaData.setOrigin(name+".filter.display-name"); + metaData.setOrigin(name+".filter.display-name",filterAnnotation,clazz); for (WebInitParam ip: filterAnnotation.initParams()) { holder.setInitParameter(ip.name(), ip.value()); - metaData.setOrigin(name+".filter.init-param."+ip.name()); + metaData.setOrigin(name+".filter.init-param."+ip.name(),ip,clazz); } FilterMapping mapping = new FilterMapping(); @@ -120,12 +120,12 @@ public class WebFilterAnnotation extends DiscoveredAnnotation if (urlPatterns.length > 0) { - ArrayList paths = new ArrayList(); + ArrayList<String> paths = new ArrayList<String>(); for (String s:urlPatterns) { paths.add(Util.normalizePattern(s)); } - mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()])); + mapping.setPathSpecs(paths.toArray(new String[paths.size()])); } if (filterAnnotation.servletNames().length > 0) @@ -135,7 +135,7 @@ public class WebFilterAnnotation extends DiscoveredAnnotation { names.add(s); } - mapping.setServletNames((String[])names.toArray(new String[names.size()])); + mapping.setServletNames(names.toArray(new String[names.size()])); } EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class); @@ -144,10 +144,10 @@ public class WebFilterAnnotation extends DiscoveredAnnotation dispatcherSet.add(d); } mapping.setDispatcherTypes(dispatcherSet); - metaData.setOrigin(name+".filter.mappings"); + metaData.setOrigin(name+".filter.mappings",filterAnnotation,clazz); holder.setAsyncSupported(filterAnnotation.asyncSupported()); - metaData.setOrigin(name+".filter.async-supported"); + metaData.setOrigin(name+".filter.async-supported",filterAnnotation,clazz); _context.getServletHandler().addFilter(holder); _context.getServletHandler().addFilterMapping(mapping); @@ -165,7 +165,7 @@ public class WebFilterAnnotation extends DiscoveredAnnotation if (metaData.getOrigin(name+".filter.init-param."+ip.name())==Origin.NotSet) { holder.setInitParameter(ip.name(), ip.value()); - metaData.setOrigin(name+".filter.init-param."+ip.name()); + metaData.setOrigin(name+".filter.init-param."+ip.name(),ip,clazz); } } @@ -191,12 +191,12 @@ public class WebFilterAnnotation extends DiscoveredAnnotation if (urlPatterns.length > 0) { - ArrayList paths = new ArrayList(); + ArrayList<String> paths = new ArrayList<String>(); for (String s:urlPatterns) { paths.add(Util.normalizePattern(s)); } - mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()])); + mapping.setPathSpecs(paths.toArray(new String[paths.size()])); } if (filterAnnotation.servletNames().length > 0) { @@ -205,7 +205,7 @@ public class WebFilterAnnotation extends DiscoveredAnnotation { names.add(s); } - mapping.setServletNames((String[])names.toArray(new String[names.size()])); + mapping.setServletNames(names.toArray(new String[names.size()])); } EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class); @@ -215,7 +215,7 @@ public class WebFilterAnnotation extends DiscoveredAnnotation } mapping.setDispatcherTypes(dispatcherSet); _context.getServletHandler().addFilterMapping(mapping); - metaData.setOrigin(name+".filter.mappings"); + metaData.setOrigin(name+".filter.mappings",filterAnnotation,clazz); } } } 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 71d24369ba..b259419a03 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 @@ -20,6 +20,7 @@ package org.eclipse.jetty.annotations; import java.util.ArrayList; +import javax.servlet.Servlet; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @@ -62,7 +63,7 @@ public class WebServletAnnotation extends DiscoveredAnnotation public void apply() { //TODO check this algorithm with new rules for applying descriptors and annotations in order - Class clazz = getTargetClass(); + Class<? extends Servlet> clazz = (Class<? extends Servlet>)getTargetClass(); if (clazz == null) { @@ -127,22 +128,22 @@ public class WebServletAnnotation extends DiscoveredAnnotation //or another annotation (which would be impossible). holder = _context.getServletHandler().newServletHolder(Holder.Source.ANNOTATION); holder.setHeldClass(clazz); - metaData.setOrigin(servletName+".servlet.servlet-class"); + metaData.setOrigin(servletName+".servlet.servlet-class",annotation,clazz); holder.setName(servletName); holder.setDisplayName(annotation.displayName()); - metaData.setOrigin(servletName+".servlet.display-name"); + metaData.setOrigin(servletName+".servlet.display-name",annotation,clazz); holder.setInitOrder(annotation.loadOnStartup()); - metaData.setOrigin(servletName+".servlet.load-on-startup"); + metaData.setOrigin(servletName+".servlet.load-on-startup",annotation,clazz); holder.setAsyncSupported(annotation.asyncSupported()); - metaData.setOrigin(servletName+".servlet.async-supported"); + metaData.setOrigin(servletName+".servlet.async-supported",annotation,clazz); for (WebInitParam ip:annotation.initParams()) { holder.setInitParameter(ip.name(), ip.value()); - metaData.setOrigin(servletName+".servlet.init-param."+ip.name()); + metaData.setOrigin(servletName+".servlet.init-param."+ip.name(),ip,clazz); } _context.getServletHandler().addServlet(holder); @@ -150,7 +151,7 @@ public class WebServletAnnotation extends DiscoveredAnnotation mapping.setServletName(holder.getName()); mapping.setPathSpecs( LazyList.toStringArray(urlPatternList)); _context.getServletHandler().addServletMapping(mapping); - metaData.setOrigin(servletName+".servlet.mappings"); + metaData.setOrigin(servletName+".servlet.mappings",annotation,clazz); } else { @@ -170,7 +171,7 @@ public class WebServletAnnotation extends DiscoveredAnnotation if (metaData.getOrigin(servletName+".servlet.init-param."+ip.name())==Origin.NotSet) { holder.setInitParameter(ip.name(), ip.value()); - metaData.setOrigin(servletName+".servlet.init-param."+ip.name()); + metaData.setOrigin(servletName+".servlet.init-param."+ip.name(),ip,clazz); } } 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 bff329e155..5edb826a69 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 @@ -18,15 +18,22 @@ package org.eclipse.jetty.plus.annotation; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletContainerInitializer; import org.eclipse.jetty.util.ConcurrentHashSet; import org.eclipse.jetty.util.Loader; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.webapp.WebAppContext; @@ -36,17 +43,41 @@ public class ContainerInitializer private static final Logger LOG = Log.getLogger(ContainerInitializer.class); final protected ServletContainerInitializer _target; - final protected Class[] _interestedTypes; - protected Set<String> _applicableTypeNames = new ConcurrentHashSet<String>(); - protected Set<String> _annotatedTypeNames = new ConcurrentHashSet<String>(); + final protected Class<?>[] _interestedTypes; + final protected Set<String> _applicableTypeNames = new ConcurrentHashSet<String>(); + final protected Set<String> _annotatedTypeNames = new ConcurrentHashSet<String>(); - public ContainerInitializer (ServletContainerInitializer target, Class[] classes) + public ContainerInitializer (ServletContainerInitializer target, Class<?>[] classes) { _target = target; _interestedTypes = classes; } - + + 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;i++) + _interestedTypes[i]=loader.loadClass(interested[i]); + for (String s:StringUtil.arrayFromString(m.group(3))) + _applicableTypeNames.add(s); + for (String s:StringUtil.arrayFromString(m.group(4))) + _annotatedTypeNames.add(s); + } + catch(Exception e) + { + throw new IllegalArgumentException(toString, e); + } + } + public ServletContainerInitializer getTarget () { return _target; @@ -116,4 +147,62 @@ public class ContainerInitializer } } } + + public String toString() + { + List<String> interested = new ArrayList<>(_interestedTypes.length); + for (Class<?> c : _interestedTypes) + interested.add(c.getName()); + return String.format("ContainerInitializer{%s,interested=%s,applicable=%s,annotated=%s}",_target.getClass().getName(),interested,_applicableTypeNames,_annotatedTypeNames); + } + + public void resolveClasses(WebAppContext context, Map<String, Set<String>> classMap) + { + //We have already found the classes that directly have an annotation that was in the HandlesTypes + //annotation of the ServletContainerInitializer. For each of those classes, walk the inheritance + //hierarchy to find classes that extend or implement them. + Set<String> annotatedClassNames = getAnnotatedTypeNames(); + if (annotatedClassNames != null && !annotatedClassNames.isEmpty()) + { + for (String name : annotatedClassNames) + { + //add the class that has the annotation + addApplicableTypeName(name); + + //find and add the classes that inherit the annotation + addInheritedTypes(classMap, (Set<String>)classMap.get(name)); + } + } + + + //Now we need to look at the HandlesTypes classes that were not annotations. We need to + //find all classes that extend or implement them. + if (getInterestedTypes() != null) + { + for (Class<?> c : getInterestedTypes()) + { + if (!c.isAnnotation()) + { + //find and add the classes that implement or extend the class. + //but not including the class itself + addInheritedTypes(classMap, (Set<String>)classMap.get(c.getName())); + } + } + } + } + + private void addInheritedTypes(Map<String, Set<String>> classMap,Set<String> names) + { + if (names == null || names.isEmpty()) + return; + + for (String s : names) + { + //add the name of the class + addApplicableTypeName(s); + + //walk the hierarchy and find all types that extend or implement the class + addInheritedTypes(classMap, (Set<String>)classMap.get(s)); + } + } } diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java index 2ebd8a49de..27b88fe100 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/annotation/LifeCycleCallbackCollection.java @@ -19,6 +19,8 @@ package org.eclipse.jetty.plus.annotation; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -136,4 +138,51 @@ public class LifeCycleCallbackCollection for (int i=0;i<callbacks.size();i++) ((LifeCycleCallback)callbacks.get(i)).callback(o); } + + /** + * Generate a read-only view of the post-construct callbacks + * @return + */ + public Map<String, List<LifeCycleCallback>> getPostConstructCallbackMap() + { + return Collections.unmodifiableMap(postConstructCallbacksMap); + } + + /** + * Generate a read-only view of the pre-destroy callbacks + * @return + */ + public Map<String, List<LifeCycleCallback>> getPreDestroyCallbackMap() + { + return Collections.unmodifiableMap(preDestroyCallbacksMap); + } + + /** + * Amalgamate all post-construct callbacks and return a read only list + * @return + */ + public Collection<LifeCycleCallback> getPostConstructCallbacks() + { + List<LifeCycleCallback> list = new ArrayList<LifeCycleCallback>(); + for (String s:postConstructCallbacksMap.keySet()) + { + list.addAll(postConstructCallbacksMap.get(s)); + } + return Collections.unmodifiableCollection(list); + } + + /** + * Amalgamate all pre-destroy callbacks and return a read only list + * @return + */ + public Collection<LifeCycleCallback> getPreDestroyCallbacks() + { + List<LifeCycleCallback> list = new ArrayList<LifeCycleCallback>(); + for (String s:preDestroyCallbacksMap.keySet()) + { + list.addAll(preDestroyCallbacksMap.get(s)); + } + return Collections.unmodifiableCollection(list); + } + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 3aa3d62f32..09747622e0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.server; import java.io.IOException; +import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; @@ -345,6 +346,8 @@ public class Server extends HandlerWrapper implements Attributes dumpStdErr(); mex.ifExceptionThrow(); + + LOG.info(String.format("Started @%dms",ManagementFactory.getRuntimeMXBean().getUptime())); } @Override diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 3330ddabee..1f4e0e007b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -1604,6 +1604,19 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu encoding = _localeEncodingMap.get(locale.getLanguage()); return encoding; } + + /* ------------------------------------------------------------ */ + /** + * Get all of the locale encodings + * + * @return a map of all the locale encodings: key is name of the locale and value is the char encoding + */ + public Map<String,String> getLocaleEncodings() + { + if (_localeEncodingMap == null) + return null; + return Collections.unmodifiableMap(_localeEncodingMap); + } /* ------------------------------------------------------------ */ /* diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java index 4e09dc438e..1d5a9a4205 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java @@ -130,6 +130,18 @@ public class FilterMapping implements Dumpable } /* ------------------------------------------------------------ */ + public boolean appliesTo(DispatcherType t) + { + return appliesTo(dispatch(t)); + } + + /* ------------------------------------------------------------ */ + public boolean isDefaultDispatches() + { + return _dispatches==0; + } + + /* ------------------------------------------------------------ */ /** * @return Returns the filterName. */ 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 dbe5ed10e7..370979e9db 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 @@ -243,12 +243,6 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope } /* ------------------------------------------------------------ */ - public Map<String, String> getRoleMap() - { - return _roleMap == null? NO_MAPPED_ROLES : _roleMap; - } - - /* ------------------------------------------------------------ */ /** * @return Returns the forcedPath. */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java index a02bfe631a..55868ad5ed 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java @@ -719,4 +719,17 @@ public class StringUtil return str.substring(0,maxSize); } + public static String[] arrayFromString(String s) + { + if (s==null) + return new String[]{}; + + if (!s.startsWith("[") || !s.endsWith("]")) + throw new IllegalArgumentException(); + if (s.length()==2) + return new String[]{}; + + return s.substring(1,s.length()-1).split(" *, *"); + } + } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java index c9c6a62391..8f2d9dc7ab 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.util.component; +import java.lang.management.ManagementFactory; import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jetty.util.annotation.ManagedAttribute; @@ -27,14 +28,12 @@ import org.eclipse.jetty.util.log.Logger; /** * Basic implementation of the life cycle interface for components. - * - * */ @ManagedObject("Abstract Implementation of LifeCycle") public abstract class AbstractLifeCycle implements LifeCycle { private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class); - + public static final String STOPPED="STOPPED"; public static final String FAILED="FAILED"; public static final String STARTING="STARTING"; @@ -174,7 +173,9 @@ public abstract class AbstractLifeCycle implements LifeCycle private void setStarted() { _state = __STARTED; - LOG.debug(STARTED+" {}",this); + if (LOG.isDebugEnabled()) + + LOG.debug(STARTED+" @{}ms {}",ManagementFactory.getRuntimeMXBean().getUptime(),this); for (Listener listener : _listeners) listener.lifeCycleStarted(this); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java index a9c37d26d9..55966d7ab0 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.util.log; import java.io.IOException; import java.io.InputStream; +import java.lang.management.ManagementFactory; import java.lang.reflect.Method; import java.net.URL; import java.security.AccessController; @@ -178,6 +179,9 @@ public class Log // Unable to load specified Logger implementation, default to standard logging. initStandardLogging(e); } + + if (LOG!=null) + LOG.info(String.format("Logging initialized @%dms",ManagementFactory.getRuntimeMXBean().getUptime())); return LOG != null; } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java index 6d3cca1ef8..28c003b853 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java @@ -121,6 +121,12 @@ public class Constraint implements Cloneable, Serializable } /* ------------------------------------------------------------ */ + public String getName() + { + return _name; + } + + /* ------------------------------------------------------------ */ public void setRoles(String[] roles) { _roles = roles; diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java index 9fe18a2b87..413f68892a 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Descriptor.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.webapp; import java.net.URL; +import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlParser; @@ -43,7 +44,8 @@ public abstract class Descriptor protected void redirect(XmlParser parser, String resource, URL source) { - if (source != null) parser.redirectEntity(resource, source); + if (source != null) + parser.redirectEntity(resource, source); } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java index 237f0685b8..2d32f033e2 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaData.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.webapp; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -69,14 +70,27 @@ public class MetaData public static class OriginInfo { - protected String name; - protected Origin origin; - protected Descriptor descriptor; + private final String name; + private final Origin origin; + private final Descriptor descriptor; + private final Annotation annotation; + private final Class<?> annotated; + public OriginInfo (String n, Annotation a,Class<?> ac) + { + name=n; + origin=Origin.Annotation; + descriptor=null; + annotation=a; + annotated=ac; + } + public OriginInfo (String n, Descriptor d) { name = n; descriptor = d; + annotation=null; + annotated=null; if (d == null) throw new IllegalArgumentException("No descriptor"); if (d instanceof FragmentDescriptor) @@ -89,16 +103,13 @@ public class MetaData origin = Origin.WebXml; } - public OriginInfo (String n) + public OriginInfo(String n) { name = n; - origin = Origin.Annotation; - } - - public OriginInfo(String n, Origin o) - { - name = n; - origin = o; + origin = Origin.API; + annotation=null; + descriptor=null; + annotated=null; } public String getName() @@ -115,6 +126,15 @@ public class MetaData { return descriptor; } + + public String toString() + { + if (descriptor!=null) + return descriptor.toString(); + if (annotation!=null) + return "@"+annotation.annotationType().getSimpleName()+" on "+annotated.getName(); + return origin.toString(); + } } public MetaData () @@ -172,8 +192,6 @@ public class MetaData _webXmlRoot.parse(); _metaDataComplete=_webXmlRoot.getMetaDataComplete() == MetaDataComplete.True; - - if (_webXmlRoot.isOrdered()) { if (_ordering == null) @@ -526,6 +544,14 @@ public class MetaData return x.getOriginType(); } + public OriginInfo getOriginInfo (String name) + { + OriginInfo x = _origins.get(name); + if (x == null) + return null; + + return x; + } public Descriptor getOriginDescriptor (String name) { @@ -541,21 +567,21 @@ public class MetaData _origins.put(name, x); } - public void setOrigin (String name) + public void setOrigin (String name, Annotation annotation, Class<?> annotated) { if (name == null) return; - OriginInfo x = new OriginInfo (name, Origin.Annotation); + OriginInfo x = new OriginInfo (name, annotation, annotated); _origins.put(name, x); } - public void setOrigin(String name, Origin origin) + public void setOriginAPI(String name) { if (name == null) return; - OriginInfo x = new OriginInfo (name, origin); + OriginInfo x = new OriginInfo (name); _origins.put(name, x); } @@ -604,4 +630,9 @@ public class MetaData { this.allowDuplicateFragmentNames = allowDuplicateFragmentNames; } + + public Map<String,OriginInfo> getOrigins() + { + return Collections.unmodifiableMap(_origins); + } } 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 f938cd3cf8..15d9453512 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 @@ -54,6 +54,7 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.xml.XmlParser; +import org.eclipse.jetty.xml.XmlParser.Node; /** * StandardDescriptorProcessor @@ -157,6 +158,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor } break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } if (LOG.isDebugEnabled()) LOG.debug("ContextParam: " + name + "=" + value); @@ -244,18 +247,17 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } String servlet_class = node.getString("servlet-class", false, true); - // Handle JSP - String jspServletClass=null; //Handle the default jsp servlet instance if (id != null && id.equals("jsp")) { - jspServletClass = servlet_class; try { Loader.loadClass(this.getClass(), servlet_class); @@ -272,7 +274,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor catch (ClassNotFoundException e) { LOG.info("NO JSP Support for {}, did not find {}", context.getContextPath(), servlet_class); - jspServletClass = servlet_class = "org.eclipse.jetty.servlet.NoJspServlet"; + servlet_class = "org.eclipse.jetty.servlet.NoJspServlet"; } } @@ -309,6 +311,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting servlet-class "+servlet_class+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -374,10 +378,12 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting load-on-startup value in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } - Iterator sRefsIter = node.iterator("security-role-ref"); + Iterator<Node> sRefsIter = node.iterator("security-role-ref"); while (sRefsIter.hasNext()) { XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next(); @@ -413,6 +419,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } else @@ -457,6 +465,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } } @@ -493,6 +503,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+servlet_name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -528,6 +540,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+servlet_name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -585,6 +599,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting multipart-config location for servlet "+servlet_name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } } @@ -632,6 +648,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor addServletMapping(servlet_name, node, context, descriptor); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -653,7 +671,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor //Servlet Spec 3.0 // <tracking-mode> // this is additive across web-fragments - Iterator iter = node.iterator("tracking-mode"); + Iterator<Node> iter = node.iterator("tracking-mode"); if (iter.hasNext()) { Set<SessionTrackingMode> modes = null; @@ -679,7 +697,9 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor modes = new HashSet<SessionTrackingMode>(context.getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes()); context.getMetaData().setOrigin("session.tracking-mode", descriptor); break; - } + } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } while (iter.hasNext()) @@ -729,6 +749,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config name "+name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -764,6 +786,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config domain "+domain+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -799,6 +823,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config path "+path+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -834,6 +860,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config comment "+comment+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -870,6 +898,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config http-only "+httpOnly+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -906,6 +936,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config secure "+secure+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -942,6 +974,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting cookie-config max-age "+maxAge+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } } @@ -990,6 +1024,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting mime-type "+mimeType+" for extension "+extension+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } } @@ -1038,6 +1074,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor addWelcomeFiles(context,node); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -1085,6 +1123,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting loacle-encoding mapping for locale "+locale+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } } @@ -1150,6 +1190,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting error-code or exception-type "+error+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -1422,18 +1464,18 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor //remember origin so we can process ServletRegistration.Dynamic.setServletSecurityElement() correctly context.getMetaData().setOrigin("constraint.url."+url, descriptor); - Iterator<XmlParser.Node> iter3 = collection.iterator("http-method"); - Iterator<XmlParser.Node> iter4 = collection.iterator("http-method-omission"); + Iterator<XmlParser.Node> methods = collection.iterator("http-method"); + Iterator<XmlParser.Node> ommissions = collection.iterator("http-method-omission"); - if (iter3.hasNext()) + if (methods.hasNext()) { - if (iter4.hasNext()) + if (ommissions.hasNext()) throw new IllegalStateException ("web-resource-collection cannot contain both http-method and http-method-omission"); //configure all the http-method elements for each url - while (iter3.hasNext()) + while (methods.hasNext()) { - String method = ((XmlParser.Node) iter3.next()).toString(false, true); + String method = ((XmlParser.Node) methods.next()).toString(false, true); ConstraintMapping mapping = new ConstraintMapping(); mapping.setMethod(method); mapping.setPathSpec(url); @@ -1441,12 +1483,13 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping); } } - else if (iter4.hasNext()) + else if (ommissions.hasNext()) { //configure all the http-method-omission elements for each url - while (iter4.hasNext()) + // TODO use the array + while (ommissions.hasNext()) { - String method = ((XmlParser.Node)iter4.next()).toString(false, true); + String method = ((XmlParser.Node)ommissions.next()).toString(false, true); ConstraintMapping mapping = new ConstraintMapping(); mapping.setMethodOmissions(new String[]{method}); mapping.setPathSpec(url); @@ -1514,6 +1557,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting auth-method value in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } //handle realm-name merge @@ -1547,9 +1592,11 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting realm-name value in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } - if (Constraint.__FORM_AUTH.equals(context.getSecurityHandler().getAuthMethod())) + if (Constraint.__FORM_AUTH.equalsIgnoreCase(context.getSecurityHandler().getAuthMethod())) { XmlParser.Node formConfig = node.get("form-login-config"); if (formConfig != null) @@ -1592,6 +1639,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting form-login-page value in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } //handle form-error-page @@ -1623,6 +1672,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting form-error-page value in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } else @@ -1696,6 +1747,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting filter-class for filter "+name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -1735,6 +1788,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } @@ -1772,6 +1827,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor throw new IllegalStateException("Conflicting async-supported="+async+" for filter "+name+" in "+descriptor.getResource()); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } } @@ -1814,6 +1871,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor addFilterMapping(filter_name, node, context, descriptor); break; } + default: + LOG.warn(new Throwable()); // TODO throw ISE? } } 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 eff5a74194..2a54dcc90e 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 @@ -1386,7 +1386,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL for (ConstraintMapping m:mappings) ((ConstraintAware)getSecurityHandler()).addConstraintMapping(m); ((ConstraintAware)getSecurityHandler()).checkPathsWithUncoveredHttpMethods(); - getMetaData().setOrigin("constraint.url."+pathSpec, Origin.API); + getMetaData().setOriginAPI("constraint.url."+pathSpec); break; } case WebXml: diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java index 2e69d043e0..cef576a771 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java @@ -30,6 +30,7 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlParser; +import org.xml.sax.InputSource; @@ -63,108 +64,130 @@ public class WebDescriptor extends Descriptor _parser = _parserSingleton; } - public XmlParser newParser() throws ClassNotFoundException { - XmlParser xmlParser=new XmlParser(); - //set up cache of DTDs and schemas locally - URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd"); - URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd"); - URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd"); - URL javaee5=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_5.xsd"); - URL javaee6=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_6.xsd"); - URL javaee7=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_7.xsd"); - - URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd"); - URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd"); - URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd"); - URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd"); - URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd"); - URL webapp31xsd=Loader.getResource(Servlet.class, "javax/servlet/resources/web-app_3_1.xsd"); - URL webcommon31xsd=Loader.getResource(Servlet.class, "javax/servlet/resources/web-common_3_1.xsd"); - URL webfragment31xsd=Loader.getResource(Servlet.class, "javax/servlet/resources/web-fragment_3_1.xsd"); - URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd"); - URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd"); - URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd"); - URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd"); - URL webservice13xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_3.xsd"); - URL webservice14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_4.xsd"); - URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd"); - - URL jsp20xsd = null; - URL jsp21xsd = null; - URL jsp22xsd = null; - URL jsp23xsd = null; - - try - { - //try both javax/servlet/resources and javax/servlet/jsp/resources to load - jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd"); - jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd"); - jsp22xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_2.xsd"); - jsp23xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_3.xsd"); - } - catch (Exception e) + XmlParser xmlParser=new XmlParser() { - LOG.ignore(e); - } - finally - { - if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_0.xsd"); - if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_1.xsd"); - if (jsp22xsd == null) jsp22xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_2.xsd"); - if (jsp23xsd == null) jsp23xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_3.xsd"); - } - - redirect(xmlParser,"web-app_2_2.dtd",dtd22); - redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22); - redirect(xmlParser,"web.dtd",dtd23); - redirect(xmlParser,"web-app_2_3.dtd",dtd23); - redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23); - redirect(xmlParser,"XMLSchema.dtd",schemadtd); - redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd); - redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd); - redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd); - redirect(xmlParser,"jsp_2_2.xsd",jsp22xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_2.xsd",jsp22xsd); - redirect(xmlParser,"jsp_2_3.xsd",jsp23xsd); - redirect(xmlParser,"http://xmlns.jcp.org/xml/ns/javaee/jsp_2_3.xsd",jsp23xsd); - redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd); - redirect(xmlParser, "http://java.sun.com/xml/ns/javaee/javaee_5.xsd",javaee5); - redirect(xmlParser, "http://java.sun.com/xml/ns/javaee/javaee_6.xsd",javaee6); - redirect(xmlParser, "http://xmlns.jcp.org/xml/ns/javaee/javaee_7.xsd",javaee7); - redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd); - redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd); - redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd); - redirect(xmlParser,"web-common_3_0.xsd",webcommon30xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd); - redirect(xmlParser,"web-fragment_3_0.xsd",webfragment30xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd); - redirect(xmlParser,"web-app_3_1.xsd",webapp31xsd); - redirect(xmlParser,"http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd",webapp31xsd); - redirect(xmlParser,"web-common_3_1.xsd",webcommon30xsd); - redirect(xmlParser,"http://xmlns.jcp.org/xml/ns/javaee/web-common_3_1.xsd",webcommon31xsd); - redirect(xmlParser,"web-fragment_3_1.xsd",webfragment30xsd); - redirect(xmlParser,"http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd",webfragment31xsd); - redirect(xmlParser,"xml.xsd",xmlxsd); - redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd); - redirect(xmlParser,"datatypes.dtd",datatypesdtd); - redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd); - redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd); - redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd); - redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd); - redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd); - redirect(xmlParser,"javaee_web_services_client_1_3.xsd",webservice13xsd); - redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/javaee_web_services_client_1_3.xsd",webservice13xsd); - redirect(xmlParser,"javaee_web_services_client_1_4.xsd",webservice14xsd); - redirect(xmlParser,"http://xmlns.jcp.org/xml/ns/javaee/javaee_web_services_client_1_4.xsd",webservice14xsd); + boolean mapped=false; + + @Override + protected InputSource resolveEntity(String pid, String sid) + { + if (!mapped) + { + mapResources(); + mapped=true; + } + InputSource is = super.resolveEntity(pid,sid); + return is; + } + + void mapResources() + { + //set up cache of DTDs and schemas locally + URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd"); + URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd"); + URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd"); + URL javaee5=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_5.xsd"); + URL javaee6=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_6.xsd"); + URL javaee7=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_7.xsd"); + + URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd"); + URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd"); + URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd"); + URL webapp31xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_1.xsd"); + + URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd"); + URL webcommon31xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_1.xsd"); + + URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd"); + URL webfragment31xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_1.xsd"); + + URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd"); + URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd"); + URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd"); + URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd"); + URL webservice13xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_3.xsd"); + URL webservice14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_4.xsd"); + URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd"); + + URL jsp20xsd = null; + URL jsp21xsd = null; + URL jsp22xsd = null; + URL jsp23xsd = null; + + try + { + //try both javax/servlet/resources and javax/servlet/jsp/resources to load + jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd"); + jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd"); + jsp22xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_2.xsd"); + jsp23xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_3.xsd"); + } + catch (Exception e) + { + LOG.ignore(e); + } + finally + { + if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_0.xsd"); + if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_1.xsd"); + if (jsp22xsd == null) jsp22xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_2.xsd"); + if (jsp23xsd == null) jsp23xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_3.xsd"); + } + + redirect(this,"web-app_2_2.dtd",dtd22); + redirect(this,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22); + redirect(this,"web.dtd",dtd23); + redirect(this,"web-app_2_3.dtd",dtd23); + redirect(this,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23); + redirect(this,"XMLSchema.dtd",schemadtd); + redirect(this,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd); + redirect(this,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd); + redirect(this,"jsp_2_0.xsd",jsp20xsd); + redirect(this,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd); + redirect(this,"jsp_2_2.xsd",jsp22xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/jsp_2_2.xsd",jsp22xsd); + redirect(this,"jsp_2_3.xsd",jsp23xsd); + redirect(this,"http://xmlns.jcp.org/xml/ns/javaee/jsp_2_3.xsd",jsp23xsd); + redirect(this,"j2ee_1_4.xsd",j2ee14xsd); + redirect(this,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd); + redirect(this, "http://java.sun.com/xml/ns/javaee/javaee_5.xsd",javaee5); + redirect(this, "http://java.sun.com/xml/ns/javaee/javaee_6.xsd",javaee6); + redirect(this, "http://xmlns.jcp.org/xml/ns/javaee/javaee_7.xsd",javaee7); + redirect(this,"web-app_2_4.xsd",webapp24xsd); + redirect(this,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd); + redirect(this,"web-app_2_5.xsd",webapp25xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd); + redirect(this,"web-app_3_0.xsd",webapp30xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd); + redirect(this,"web-common_3_0.xsd",webcommon30xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd); + redirect(this,"web-fragment_3_0.xsd",webfragment30xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd); + redirect(this,"web-app_3_1.xsd",webapp31xsd); + redirect(this,"http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd",webapp31xsd); + + redirect(this,"web-common_3_1.xsd",webcommon30xsd); + redirect(this,"http://xmlns.jcp.org/xml/ns/javaee/web-common_3_1.xsd",webcommon31xsd); + redirect(this,"web-fragment_3_1.xsd",webfragment30xsd); + redirect(this,"http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd",webfragment31xsd); + redirect(this,"xml.xsd",xmlxsd); + redirect(this,"http://www.w3.org/2001/xml.xsd",xmlxsd); + redirect(this,"datatypes.dtd",datatypesdtd); + redirect(this,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd); + redirect(this,"j2ee_web_services_client_1_1.xsd",webservice11xsd); + redirect(this,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd); + redirect(this,"javaee_web_services_client_1_2.xsd",webservice12xsd); + redirect(this,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd); + redirect(this,"javaee_web_services_client_1_3.xsd",webservice13xsd); + redirect(this,"http://java.sun.com/xml/ns/javaee/javaee_web_services_client_1_3.xsd",webservice13xsd); + redirect(this,"javaee_web_services_client_1_4.xsd",webservice14xsd); + redirect(this,"http://xmlns.jcp.org/xml/ns/javaee/javaee_web_services_client_1_4.xsd",webservice14xsd); + } + }; return xmlParser; } 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 new file mode 100644 index 0000000000..0ab2401388 --- /dev/null +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java @@ -0,0 +1,163 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.xml; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Map; +import java.util.Stack; + +public class XmlAppendable +{ + private final String SPACES=" "; + private final Appendable _out; + private final int _indent; + private final Stack<String> _tags = new Stack<>(); + private String _space=""; + + public XmlAppendable(Appendable out) throws IOException + { + this(out,2); + } + + public XmlAppendable(Appendable out, int indent) throws IOException + { + _out=out; + _indent=indent; + _out.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); + } + + public XmlAppendable open(String tag, Map<String,String> attributes) throws IOException + { + _out.append(_space).append('<').append(tag); + attributes(attributes); + + _out.append(">\n"); + _space=_space+SPACES.substring(0,_indent); + _tags.push(tag); + return this; + } + + public XmlAppendable open(String tag) throws IOException + { + _out.append(_space).append('<').append(tag).append(">\n"); + _space=_space+SPACES.substring(0,_indent); + _tags.push(tag); + return this; + } + + public XmlAppendable content(String s) throws IOException + { + if (s!=null) + { + for (int i=0;i<s.length();i++) + { + char c = s.charAt(i); + switch(c) + { + case '<': + _out.append("<"); + break; + case '>': + _out.append(">"); + break; + case '&': + _out.append("&"); + break; + case '\'': + _out.append("'"); + break; + case '"': + _out.append("""); + break; + default: + _out.append(c); + } + } + } + + return this; + } + + public XmlAppendable cdata(String s) throws IOException + { + _out.append("<![CDATA[").append(s).append("]]>"); + return this; + } + + public XmlAppendable tag(String tag) throws IOException + { + _out.append(_space).append('<').append(tag).append("/>\n"); + return this; + } + + public XmlAppendable tag(String tag, Map<String,String> attributes) throws IOException + { + _out.append(_space).append('<').append(tag); + attributes(attributes); + _out.append("/>\n"); + return this; + } + + public XmlAppendable tag(String tag,String content) throws IOException + { + _out.append(_space).append('<').append(tag).append('>'); + content(content); + _out.append("</").append(tag).append(">\n"); + return this; + } + + public XmlAppendable tag(String tag, Map<String,String> attributes,String content) throws IOException + { + _out.append(_space).append('<').append(tag); + attributes(attributes); + _out.append('>'); + content(content); + _out.append("</").append(tag).append(">\n"); + return this; + } + + public XmlAppendable close() throws IOException + { + if (_tags.isEmpty()) + throw new IllegalStateException("Tags closed"); + String tag=_tags.pop(); + _space=_space.substring(0,_space.length()-_indent); + _out.append(_space).append("</").append(tag).append(">\n"); + if (_tags.isEmpty() && _out instanceof Closeable) + ((Closeable)_out).close(); + return this; + } + + private void attributes(Map<String,String> attributes) throws IOException + { + for (String k:attributes.keySet()) + { + String v = attributes.get(k); + _out.append(' ').append(k).append("=\""); + content(v); + _out.append('"'); + } + } + + public Stack<String> getOpenTags() + { + return (Stack<String>)_tags.clone(); + } +} diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java index d512dee023..31ef0afc39 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java @@ -186,7 +186,7 @@ public class XmlParser public synchronized void addContentHandler(String trigger, ContentHandler observer) { if (_observerMap == null) - _observerMap = new HashMap(); + _observerMap = new HashMap<>(); _observerMap.put(trigger, observer); } @@ -251,6 +251,51 @@ public class XmlParser return doc; } + + /* ------------------------------------------------------------ */ + protected InputSource resolveEntity(String pid, String sid) + { + if (LOG.isDebugEnabled()) + LOG.debug("resolveEntity(" + pid + ", " + sid + ")"); + + if (sid!=null && sid.endsWith(".dtd")) + _dtd=sid; + + URL entity = null; + if (pid != null) + entity = (URL) _redirectMap.get(pid); + if (entity == null) + entity = (URL) _redirectMap.get(sid); + if (entity == null) + { + String dtd = sid; + if (dtd.lastIndexOf('/') >= 0) + dtd = dtd.substring(dtd.lastIndexOf('/') + 1); + + if (LOG.isDebugEnabled()) + LOG.debug("Can't exact match entity in redirect map, trying " + dtd); + entity = (URL) _redirectMap.get(dtd); + } + + if (entity != null) + { + try + { + InputStream in = entity.openStream(); + if (LOG.isDebugEnabled()) + LOG.debug("Redirected entity " + sid + " --> " + entity); + InputSource is = new InputSource(in); + is.setSystemId(sid); + return is; + } + catch (IOException e) + { + LOG.ignore(e); + } + } + return null; + } + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ private class NoopHandler extends DefaultHandler @@ -414,45 +459,7 @@ public class XmlParser /* ------------------------------------------------------------ */ public InputSource resolveEntity(String pid, String sid) { - if (LOG.isDebugEnabled()) - LOG.debug("resolveEntity(" + pid + ", " + sid + ")"); - - if (sid!=null && sid.endsWith(".dtd")) - _dtd=sid; - - URL entity = null; - if (pid != null) - entity = (URL) _redirectMap.get(pid); - if (entity == null) - entity = (URL) _redirectMap.get(sid); - if (entity == null) - { - String dtd = sid; - if (dtd.lastIndexOf('/') >= 0) - dtd = dtd.substring(dtd.lastIndexOf('/') + 1); - - if (LOG.isDebugEnabled()) - LOG.debug("Can't exact match entity in redirect map, trying " + dtd); - entity = (URL) _redirectMap.get(dtd); - } - - if (entity != null) - { - try - { - InputStream in = entity.openStream(); - if (LOG.isDebugEnabled()) - LOG.debug("Redirected entity " + sid + " --> " + entity); - InputSource is = new InputSource(in); - is.setSystemId(sid); - return is; - } - catch (IOException e) - { - LOG.ignore(e); - } - } - return null; + return XmlParser.this.resolveEntity(pid,sid); } } 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 new file mode 100644 index 0000000000..dd8f3c355e --- /dev/null +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.xml; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +public class XmlAppendableTest +{ + @Test + public void test() throws Exception + { + StringBuilder b = new StringBuilder(); + XmlAppendable out = new XmlAppendable(b); + Map<String,String> attr = new HashMap<>(); + + out.open("test"); + + attr.put("name","attr value"); + attr.put("noval",null); + attr.put("quotes","'\""); + + out.tag("tag"); + out.tag("tag",attr); + out.tag("tag",attr,"content"); + + out.open("level1").tag("tag","content").tag("tag","content").close(); + out.open("level1",attr).open("level2").tag("tag","content").tag("tag","content").close().close(); + + out.close(); + + String s = b.toString(); + Assert.assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<test>\n <tag/>\n <tag quotes=\"'"\" name=\"attr value\" noval=\"\"/>\n <tag quotes=\"'"\" name=\"attr value\" noval=\"\">content</tag>\n <level1>\n <tag>content</tag>\n <tag>content</tag>\n </level1>\n <level1 quotes=\"'"\" name=\"attr value\" noval=\"\">\n <level2>\n <tag>content</tag>\n <tag>content</tag>\n </level2>\n </level1>\n</test>\n",s); + } +} diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java index aac989d82d..502e4b1c48 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java @@ -304,11 +304,22 @@ public class AnnotationTest extends HttpServlet out.println("@Resource(name=\"minAmount\")"); out.println("private Double minAmount;"); out.println("</pre>"); - out.println("<p><b>Result: "+envResult+": "+(maxAmount.compareTo(new Double(55))==0?" <span class=\"pass\">PASS":" <span class=\"fail\">FAIL")+"</span></b>"); + if (maxAmount==null) + out.println("<p><b>Result: "+envResult+": <span class=\"fail\">FAIL"); + else + out.println("<p><b>Result: "+envResult+": "+(maxAmount.compareTo(new Double(55))==0?" <span class=\"pass\">PASS":" <span class=\"fail\">FAIL")+"</span></b>"); out.println("<br/><b>JNDI Lookup Result: "+envLookupResult+"</b>"); - out.println("<br/><b>Result: "+envResult2+": "+(minAmount.compareTo(new Double("0.99"))==0?" <span class=\"pass\">PASS":" <span class=\"fail\">FAIL")+"</span></b>"); + + if (minAmount==null) + out.println("<p><b>Result: "+envResult2+": <span class=\"fail\">FAIL"); + else + out.println("<br/><b>Result: "+envResult2+": "+(minAmount.compareTo(new Double("0.99"))==0?" <span class=\"pass\">PASS":" <span class=\"fail\">FAIL")+"</span></b>"); out.println("<br/><b>JNDI Lookup Result: "+envLookupResult2+"</b>"); - out.println("<br/><b>Result: "+envResult3+": "+(avgAmount.compareTo(new Double("1.25"))==0?" <span class=\"pass\">PASS":" <span class=\"fail\">FAIL")+"</span></b>"); + + if (avgAmount==null) + out.println("<p><b>Result: "+envResult3+": <span class=\"fail\">FAIL"); + else + out.println("<br/><b>Result: "+envResult3+": "+(avgAmount.compareTo(new Double("1.25"))==0?" <span class=\"pass\">PASS":" <span class=\"fail\">FAIL")+"</span></b>"); out.println("<br/><b>JNDI Lookup Result: "+envLookupResult3+"</b></p>"); out.println("<h2>@Resource Injection for UserTransaction </h2>"); |