Apply changes resulting from the quickstart project

This commit is contained in:
Greg Wilkins 2014-02-13 12:31:14 +11:00
parent 1eb87fdddc
commit 18e19260ff
28 changed files with 782 additions and 304 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
.classpath
.project
.settings
.gitignore
# maven
target/

View File

@ -439,8 +439,19 @@ public class AnnotationConfiguration extends AbstractConfiguration
if (!_discoverableAnnotationHandlers.isEmpty() || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty())
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);
}
}
/**
@ -449,7 +460,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
@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());
}
}
}

View File

@ -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));
}
}

View File

@ -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))
{

View File

@ -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);

View File

@ -60,13 +60,8 @@ public class ServletContainerInitializersStarter extends AbstractLifeCycle imple
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())
@ -82,80 +77,4 @@ 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));
}
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -1605,6 +1605,19 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
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);
}
/* ------------------------------------------------------------ */
/*
*/

View File

@ -129,6 +129,18 @@ public class FilterMapping implements Dumpable
return (_dispatches&type)!=0;
}
/* ------------------------------------------------------------ */
public boolean appliesTo(DispatcherType t)
{
return appliesTo(dispatch(t));
}
/* ------------------------------------------------------------ */
public boolean isDefaultDispatches()
{
return _dispatches==0;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the filterName.

View File

@ -242,12 +242,6 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
return (link==null)?name:link;
}
/* ------------------------------------------------------------ */
public Map<String, String> getRoleMap()
{
return _roleMap == null? NO_MAPPED_ROLES : _roleMap;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the forcedPath.

View File

@ -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(" *, *");
}
}

View File

@ -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,8 +28,6 @@ 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
@ -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);
}

View File

@ -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;
@ -179,6 +180,9 @@ public class Log
initStandardLogging(e);
}
if (LOG!=null)
LOG.info(String.format("Logging initialized @%dms",ManagementFactory.getRuntimeMXBean().getUptime()));
return LOG != null;
}

View File

@ -120,6 +120,12 @@ public class Constraint implements Cloneable, Serializable
_name = name;
}
/* ------------------------------------------------------------ */
public String getName()
{
return _name;
}
/* ------------------------------------------------------------ */
public void setRoles(String[] roles)
{

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
@ -680,6 +698,8 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
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?
}
}

View File

@ -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:

View File

@ -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,11 +64,27 @@ public class WebDescriptor extends Descriptor
_parser = _parserSingleton;
}
public XmlParser newParser()
throws ClassNotFoundException
{
XmlParser xmlParser=new XmlParser();
XmlParser xmlParser=new XmlParser()
{
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");
@ -79,11 +96,14 @@ public class WebDescriptor extends Descriptor
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 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 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");
@ -117,54 +137,57 @@ public class WebDescriptor extends Descriptor
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);
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;
}

View File

@ -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("&lt;");
break;
case '>':
_out.append("&gt;");
break;
case '&':
_out.append("&amp;");
break;
case '\'':
_out.append("&apos;");
break;
case '"':
_out.append("&quot;");
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();
}
}

View File

@ -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);
}
}

View File

@ -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=\"&apos;&quot;\" name=\"attr value\" noval=\"\"/>\n <tag quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\">content</tag>\n <level1>\n <tag>content</tag>\n <tag>content</tag>\n </level1>\n <level1 quotes=\"&apos;&quot;\" name=\"attr value\" noval=\"\">\n <level2>\n <tag>content</tag>\n <tag>content</tag>\n </level2>\n </level1>\n</test>\n",s);
}
}

View File

@ -304,10 +304,21 @@ public class AnnotationTest extends HttpServlet
out.println("@Resource(name=\"minAmount\")");
out.println("private Double minAmount;");
out.println("</pre>");
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>");
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>");
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>");