320073 ensure Decorators get called in reverse order of addition; refactor TagLibConfiguration and Descriptor classes

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2187 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Jan Bartel 2010-07-27 23:59:16 +00:00
parent de2e13a9e3
commit bd272143e2
17 changed files with 513 additions and 350 deletions

View File

@ -14,7 +14,6 @@
package org.eclipse.jetty.annotations;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
/**

View File

@ -67,7 +67,13 @@ public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnota
PostConstructCallback callback = new PostConstructCallback();
callback.setTarget(clazz.getName(), m.getName());
((LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION)).add(callback);
LifeCycleCallbackCollection lifecycles = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
if (lifecycles == null)
{
lifecycles = new LifeCycleCallbackCollection();
_context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION,lifecycles);
}
lifecycles.add(callback);
}
}
}

View File

@ -66,7 +66,15 @@ public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotatio
PreDestroyCallback callback = new PreDestroyCallback();
callback.setTarget(clazz.getName(), m.getName());
((LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION)).add(callback);
LifeCycleCallbackCollection lifecycles = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
if (lifecycles == null)
{
lifecycles = new LifeCycleCallbackCollection();
_context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, lifecycles);
}
lifecycles.add(callback);
}
}
}

View File

@ -128,11 +128,16 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
//it overrides this annotation
return;
}
//No injections for this resource in any descriptors, so we can add it
//Does the injection already exist?
Injection injection = ((InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION)).getInjection(name, clazz, field);
InjectionCollection injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
if (injections == null)
{
injections = new InjectionCollection();
_context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
}
Injection injection = injections.getInjection(name, clazz, field);
if (injection == null)
{
//No injection has been specified, add it
@ -167,7 +172,7 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
injection.setTarget(clazz, field, type);
injection.setJndiName(name);
injection.setMappingName(mappedName);
((InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION)).add(injection);
injections.add(injection);
//TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
metaData.setOrigin("resource-ref."+name+".injection");
@ -275,6 +280,11 @@ public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationH
//check if an injection has already been setup for this target by web.xml
InjectionCollection injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
if (injections == null)
{
injections = new InjectionCollection();
_context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
}
Injection injection = injections.getInjection(name, clazz, method, paramType);
if (injection == null)
{

View File

@ -26,6 +26,7 @@ import org.eclipse.jetty.webapp.Descriptor;
import org.eclipse.jetty.webapp.MetaData;
import org.eclipse.jetty.webapp.WebAppContext;
public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
protected WebAppContext _context;
@ -62,7 +63,13 @@ public class RunAsAnnotationHandler extends AbstractIntrospectableAnnotationHand
org.eclipse.jetty.plus.annotation.RunAs ra = new org.eclipse.jetty.plus.annotation.RunAs();
ra.setTargetClassName(clazz.getCanonicalName());
ra.setRoleName(role);
((RunAsCollection)_context.getAttribute(RunAsCollection.RUNAS_COLLECTION)).add(ra);
RunAsCollection raCollection = (RunAsCollection)_context.getAttribute(RunAsCollection.RUNAS_COLLECTION);
if (raCollection == null)
{
raCollection = new RunAsCollection();
_context.setAttribute(RunAsCollection.RUNAS_COLLECTION, raCollection);
}
raCollection.add(ra);
}
}
}

View File

@ -71,14 +71,29 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
*/
public void start(WebAppContext context, Descriptor descriptor)
{
InjectionCollection injections = new InjectionCollection();
context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, callbacks);
RunAsCollection runAsCollection = new RunAsCollection();
context.setAttribute(RunAsCollection.RUNAS_COLLECTION, runAsCollection);
InjectionCollection injections = (InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
if (injections == null)
{
injections = new InjectionCollection();
context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
}
LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
if (callbacks == null)
{
callbacks = new LifeCycleCallbackCollection();
context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, callbacks);
}
RunAsCollection runAsCollection = (RunAsCollection)context.getAttribute(RunAsCollection.RUNAS_COLLECTION);
if (runAsCollection == null)
{
runAsCollection = new RunAsCollection();
context.setAttribute(RunAsCollection.RUNAS_COLLECTION, runAsCollection);
}
}
/**
* @see org.eclipse.jetty.webapp.IterativeDescriptorProcessor#end(org.eclipse.jetty.webapp.Descriptor, WebAppContext)
@ -611,6 +626,12 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
continue;
}
InjectionCollection injections = (InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
if (injections == null)
{
injections = new InjectionCollection();
context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
}
// comments in the javaee_5.xsd file specify that the targetName is looked
// for first as a java bean property, then if that fails, as a field
try
@ -619,7 +640,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
Injection injection = new Injection();
injection.setJndiName(jndiName);
injection.setTarget(clazz, targetName, valueClass);
((InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION)).add(injection);
injections.add(injection);
//Record which was the first descriptor to declare an injection for this name
if (context.getMetaData().getOriginDescriptor(node.getTag()+"."+jndiName+".injection") == null)

View File

@ -230,8 +230,9 @@ public class ServletContextHandler extends ContextHandler
// OK to Initialize servlet handler now
if (_servletHandler != null && _servletHandler.isStarted())
{
for (Decorator decorator : _decorators)
for (int i=_decorators.size()-1;i>=0; i--)
{
Decorator decorator = _decorators.get(i);
if (_servletHandler.getFilters()!=null)
for (FilterHolder holder:_servletHandler.getFilters())
decorator.decorateFilterHolder(holder);
@ -576,8 +577,11 @@ public class ServletContextHandler extends ContextHandler
try
{
T f = c.newInstance();
for (Decorator decorator : _decorators)
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
f=decorator.decorateFilterInstance(f);
}
return f;
}
catch (InstantiationException e)
@ -596,8 +600,11 @@ public class ServletContextHandler extends ContextHandler
try
{
T s = c.newInstance();
for (Decorator decorator : _decorators)
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
s=decorator.decorateServletInstance(s);
}
return s;
}
catch (InstantiationException e)
@ -713,8 +720,11 @@ public class ServletContextHandler extends ContextHandler
throw new ServletException(e);
}
for (Decorator decorator : _decorators)
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
l=decorator.decorateListenerInstance(l);
}
return l;
}
catch(ServletException e)

View File

@ -19,7 +19,7 @@ import org.eclipse.jetty.util.resource.Resource;
* DefaultsDescriptor
*
*/
public class DefaultsDescriptor extends Descriptor
public class DefaultsDescriptor extends WebDescriptor
{
public DefaultsDescriptor(Resource xml)
{

View File

@ -1,5 +1,5 @@
// ========================================================================
// Copyright (c) 2006-2010 Mort Bay Consulting Pty. Ltd.
// Copyright (c) 2010 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
@ -14,270 +14,61 @@
package org.eclipse.jetty.webapp;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.Servlet;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlParser;
/**
* Descriptor
*
* A web descriptor (web.xml/web-defaults.xml/web-overrides.xml).
*/
public class Descriptor
{
protected static XmlParser _parser;
public enum MetaDataComplete {NotSet, True, False};
public abstract class Descriptor
{
protected Resource _xml;
protected XmlParser.Node _root;
protected MetaDataComplete _metaDataComplete;
protected int _majorVersion = 3; //default to container version
protected int _minorVersion = 0;
protected ArrayList<String> _classNames = new ArrayList<String>();
protected boolean _distributable;
protected XmlParser _parser;
protected boolean _validating;
protected boolean _isOrdered = false;
protected List<String> _ordering = new ArrayList<String>();
public static 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",true);
URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
URL jsp20xsd = null;
URL jsp21xsd = null;
try
{
Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
}
catch (Exception e)
{
Log.ignore(e);
}
finally
{
if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
}
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,"j2ee_1_4.xsd",j2ee14xsd);
redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
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,"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);
return xmlParser;
}
protected static void redirect(XmlParser parser, String resource, URL source)
{
if (source != null) parser.redirectEntity(resource, source);
}
public Descriptor (Resource xml)
{
_xml = xml;
}
public abstract XmlParser newParser()
throws ClassNotFoundException;
public abstract void ensureParser()
throws ClassNotFoundException;
protected void redirect(XmlParser parser, String resource, URL source)
{
if (source != null) parser.redirectEntity(resource, source);
}
public void setValidating (boolean validating)
{
_validating = validating;
}
public void parse ()
throws Exception
{
if (_parser == null)
_parser = newParser();
ensureParser();
if (_root == null)
{
//boolean oldValidating = _processor.getParser().getValidating();
//_processor.getParser().setValidating(_validating);
_root = _parser.parse(_xml.getURL().toString());
processVersion();
processOrdering();
//_processor.getParser().setValidating(oldValidating);
}
}
public MetaDataComplete getMetaDataComplete()
{
return _metaDataComplete;
}
public XmlParser.Node getRoot ()
{
return _root;
}
public int getMajorVersion ()
{
return _majorVersion;
}
public int getMinorVersion()
{
return _minorVersion;
}
public Resource getResource ()
{
return _xml;
}
public void processVersion ()
public XmlParser.Node getRoot ()
{
String version = _root.getAttribute("version", "DTD");
if ("DTD".equals(version))
{
_majorVersion = 2;
_minorVersion = 3;
String dtd = _parser.getDTD();
if (dtd != null && dtd.indexOf("web-app_2_2") >= 0)
{
_majorVersion = 2;
_minorVersion = 2;
}
}
else
{
int dot = version.indexOf(".");
if (dot > 0)
{
_majorVersion = Integer.parseInt(version.substring(0,dot));
_minorVersion = Integer.parseInt(version.substring(dot+1));
}
}
if (_majorVersion < 2 && _minorVersion < 5)
_metaDataComplete = MetaDataComplete.True; // does not apply before 2.5
else
{
String s = (String)_root.getAttribute("metadata-complete");
if (s == null)
_metaDataComplete = MetaDataComplete.NotSet;
else
_metaDataComplete = Boolean.valueOf(s).booleanValue()?MetaDataComplete.True:MetaDataComplete.False;
}
Log.debug(_xml.toString()+": Calculated metadatacomplete = " + _metaDataComplete + " with version=" + version);
}
public void processOrdering ()
{
//Process the web.xml's optional <absolute-ordering> element
XmlParser.Node ordering = _root.get("absolute-ordering");
if (ordering == null)
return;
_isOrdered = true;
//If an absolute-ordering was already set, then ignore it in favour of this new one
// _processor.setOrdering(new AbsoluteOrdering());
Iterator iter = ordering.iterator();
XmlParser.Node node = null;
while (iter.hasNext())
{
Object o = iter.next();
if (!(o instanceof XmlParser.Node)) continue;
node = (XmlParser.Node) o;
if (node.getTag().equalsIgnoreCase("others"))
//((AbsoluteOrdering)_processor.getOrdering()).addOthers();
_ordering.add("others");
else if (node.getTag().equalsIgnoreCase("name"))
//((AbsoluteOrdering)_processor.getOrdering()).add(node.toString(false,true));
_ordering.add(node.toString(false,true));
}
}
public void addClassName (String className)
{
if (!_classNames.contains(className))
_classNames.add(className);
}
public ArrayList<String> getClassNames ()
{
return _classNames;
}
public void setDistributable (boolean distributable)
{
_distributable = distributable;
}
public boolean isDistributable()
{
return _distributable;
}
public void setValidating (boolean validating)
{
_validating = validating;
}
public boolean isOrdered()
{
return _isOrdered;
}
public List<String> getOrdering()
{
return _ordering;
return _root;
}
}

View File

@ -27,7 +27,7 @@ import org.eclipse.jetty.xml.XmlParser;
*
* A web-fragment.xml descriptor.
*/
public class FragmentDescriptor extends Descriptor
public class FragmentDescriptor extends WebDescriptor
{
public static final String NAMELESS = "@@-NAMELESS-@@"; //prefix for nameless Fragments
public enum OtherType {None, Before, After};

View File

@ -14,10 +14,8 @@
package org.eclipse.jetty.webapp;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.xml.XmlParser;

View File

@ -38,9 +38,9 @@ public class MetaData
public enum Origin {NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation};
protected Map<String, OriginInfo> _origins =new HashMap<String,OriginInfo>();
protected Descriptor _webDefaultsRoot;
protected Descriptor _webXmlRoot;
protected Descriptor _webOverrideRoot;
protected WebDescriptor _webDefaultsRoot;
protected WebDescriptor _webXmlRoot;
protected WebDescriptor _webOverrideRoot;
protected boolean _metaDataComplete;
protected final List<DiscoveredAnnotation> _annotations = new ArrayList<DiscoveredAnnotation>();
protected final List<DescriptorProcessor> _descriptorProcessors = new ArrayList<DescriptorProcessor>();
@ -52,7 +52,7 @@ public class MetaData
protected final List<Resource> _orderedWebInfJars = new ArrayList<Resource>();
protected final List<Resource> _orderedContainerJars = new ArrayList<Resource>();
protected Ordering _ordering;//can be set to RelativeOrdering by web-default.xml, web.xml, web-override.xml
protected StandardDescriptorProcessor _standardDescriptorProcessor;
public static class OriginInfo
@ -132,9 +132,9 @@ public class MetaData
public void setWebXml (Resource webXml)
throws Exception
{
_webXmlRoot = new Descriptor(webXml);
_webXmlRoot = new WebDescriptor(webXml);
_webXmlRoot.parse();
_metaDataComplete=_webXmlRoot.getMetaDataComplete() == Descriptor.MetaDataComplete.True;
_metaDataComplete=_webXmlRoot.getMetaDataComplete() == WebDescriptor.MetaDataComplete.True;
if (_webXmlRoot.isOrdered())
{
@ -325,17 +325,17 @@ public class MetaData
}
public Descriptor getWebXml ()
public WebDescriptor getWebXml ()
{
return _webXmlRoot;
}
public Descriptor getOverrideWeb ()
public WebDescriptor getOverrideWeb ()
{
return _webOverrideRoot;
}
public Descriptor getWebDefault ()
public WebDescriptor getWebDefault ()
{
return _webDefaultsRoot;
}

View File

@ -20,7 +20,7 @@ import org.eclipse.jetty.util.resource.Resource;
*
*
*/
public class OverrideDescriptor extends Descriptor
public class OverrideDescriptor extends WebDescriptor
{
public OverrideDescriptor(Resource xml)
{

View File

@ -270,7 +270,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
//Set the servlet-class
if (servlet_class != null)
{
descriptor.addClassName(servlet_class);
((WebDescriptor)descriptor).addClassName(servlet_class);
Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.servlet-class");
switch (o)
@ -1006,7 +1006,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
String filter_class = node.getString("filter-class", false, true);
if (filter_class != null)
{
descriptor.addClassName(filter_class);
((WebDescriptor)descriptor).addClassName(filter_class);
Origin o = context.getMetaData().getOrigin(name+".filter.filter-class");
switch (o)
@ -1187,7 +1187,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
}
}
descriptor.addClassName(className);
((WebDescriptor)descriptor).addClassName(className);
context.addEventListener(listener);
Class<? extends EventListener> listenerClass = (Class<? extends EventListener>)context.loadClass(className);
@ -1214,7 +1214,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
// the element has no content, so its simple presence
// indicates that the webapp is distributable...
//Servlet Spec 3.0 p.74 distributable only if all fragments are distributable
descriptor.setDistributable(true);
((WebDescriptor)descriptor).setDistributable(true);
}
protected EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws ServletException, InstantiationException, IllegalAccessException

View File

@ -51,28 +51,32 @@ import org.eclipse.jetty.xml.XmlParser;
public class TagLibConfiguration extends AbstractConfiguration
{
public static final String TLD_RESOURCES = "org.eclipse.jetty.tlds";
private TldProcessor _processor;
private List<TldDescriptor> _descriptors = new ArrayList<TldDescriptor>();
public class TldProcessor
public static class TldDescriptor extends Descriptor
{
public static final String TAGLIB_PROCESSOR = "org.eclipse.jetty.tagLibProcessor";
XmlParser _parser;
WebAppContext _context;
List<XmlParser.Node> _roots = new ArrayList<XmlParser.Node>();
public TldProcessor (WebAppContext context)
throws Exception
protected static XmlParser __parserSingleton;
public TldDescriptor(Resource xml)
{
_context = context;
createParser();
super(xml);
}
private void createParser ()
throws Exception
@Override
public void ensureParser() throws ClassNotFoundException
{
if (__parserSingleton == null)
__parserSingleton = newParser();
_parser = __parserSingleton;
}
@Override
public XmlParser newParser() throws ClassNotFoundException
{
// Create a TLD parser
_parser = new XmlParser(false);
XmlParser parser = new XmlParser(false);
URL taglib11=null;
URL taglib12=null;
@ -106,95 +110,110 @@ public class TagLibConfiguration extends AbstractConfiguration
if(taglib11!=null)
{
_parser.redirectEntity("web-jsptaglib_1_1.dtd",taglib11);
_parser.redirectEntity("web-jsptaglibrary_1_1.dtd",taglib11);
redirect(parser, "web-jsptaglib_1_1.dtd",taglib11);
redirect(parser, "web-jsptaglibrary_1_1.dtd",taglib11);
}
if(taglib12!=null)
{
_parser.redirectEntity("web-jsptaglib_1_2.dtd",taglib12);
_parser.redirectEntity("web-jsptaglibrary_1_2.dtd",taglib12);
redirect(parser, "web-jsptaglib_1_2.dtd",taglib12);
redirect(parser, "web-jsptaglibrary_1_2.dtd",taglib12);
}
if(taglib20!=null)
{
_parser.redirectEntity("web-jsptaglib_2_0.xsd",taglib20);
_parser.redirectEntity("web-jsptaglibrary_2_0.xsd",taglib20);
redirect(parser, "web-jsptaglib_2_0.xsd",taglib20);
redirect(parser, "web-jsptaglibrary_2_0.xsd",taglib20);
}
if(taglib21!=null)
{
_parser.redirectEntity("web-jsptaglib_2_1.xsd",taglib21);
_parser.redirectEntity("web-jsptaglibrary_2_1.xsd",taglib21);
redirect(parser, "web-jsptaglib_2_1.xsd",taglib21);
redirect(parser, "web-jsptaglibrary_2_1.xsd",taglib21);
}
_parser.setXpath("/taglib/listener/listener-class");
parser.setXpath("/taglib/listener/listener-class");
return parser;
}
public XmlParser.Node parse (Resource tld)
public void parse ()
throws Exception
{
ensureParser();
XmlParser.Node root;
try
{
//xerces on apple appears to sometimes close the zip file instead
//of the inputstream, so try opening the input stream, but if
//that doesn't work, fallback to opening a new url
root = _parser.parse(tld.getInputStream());
_root = _parser.parse(_xml.getInputStream());
}
catch (Exception e)
{
root = _parser.parse(tld.getURL().toString());
_root = _parser.parse(_xml.getURL().toString());
}
if (root==null)
if (_root==null)
{
Log.warn("No TLD root in {}",tld);
Log.warn("No TLD root in {}",_xml);
}
else
_roots.add(root);
return root;
}
}
/**
* TldProcessor
*
* Process TldDescriptors representing tag libs to find listeners.
*/
public class TldProcessor extends IterativeDescriptorProcessor
{
public static final String TAGLIB_PROCESSOR = "org.eclipse.jetty.tagLibProcessor";
XmlParser _parser;
List<XmlParser.Node> _roots = new ArrayList<XmlParser.Node>();
public void processRoots ()
{
for (XmlParser.Node root: _roots)
process(root);
public TldProcessor ()
throws Exception
{
registerVisitor("listener", this.getClass().getDeclaredMethod("visitListener", __signature));
}
public void process (XmlParser.Node root)
public void visitListener (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
{
for (int i=0;i<root.size();i++)
String className=node.getString("listener-class",false,true);
if (Log.isDebugEnabled()) Log.debug("listener="+className);
try
{
Object o=root.get(i);
if (o instanceof XmlParser.Node)
{
XmlParser.Node node = (XmlParser.Node)o;
if ("listener".equals(node.getTag()))
{
String className=node.getString("listener-class",false,true);
if (Log.isDebugEnabled()) Log.debug("listener="+className);
try
{
Class listenerClass = _context.loadClass(className);
EventListener l = (EventListener)listenerClass.newInstance();
_context.addEventListener(l);
}
catch(Exception e)
{
Log.warn("Could not instantiate listener "+className+": "+e);
Log.debug(e);
}
catch(Error e)
{
Log.warn("Could not instantiate listener "+className+": "+e);
Log.debug(e);
}
}
}
Class listenerClass = context.loadClass(className);
EventListener l = (EventListener)listenerClass.newInstance();
context.addEventListener(l);
}
catch(Exception e)
{
Log.warn("Could not instantiate listener "+className+": "+e);
Log.debug(e);
}
catch(Error e)
{
Log.warn("Could not instantiate listener "+className+": "+e);
Log.debug(e);
}
}
@Override
public void end(WebAppContext context, Descriptor descriptor)
{
// TODO Auto-generated method stub
}
@Override
public void start(WebAppContext context, Descriptor descriptor)
{
// TODO Auto-generated method stub
}
}
@ -247,11 +266,9 @@ public class TagLibConfiguration extends AbstractConfiguration
if (tld_resources!=null)
tlds.addAll(tld_resources);
// Create a processor for the tlds and save it
TldProcessor processor = new TldProcessor (context);
context.setAttribute(TldProcessor.TAGLIB_PROCESSOR, processor);
// Parse the tlds into memory
_descriptors.clear();
Resource tld = null;
Iterator iter = tlds.iterator();
while (iter.hasNext())
@ -260,34 +277,62 @@ public class TagLibConfiguration extends AbstractConfiguration
{
tld = (Resource)iter.next();
if (Log.isDebugEnabled()) Log.debug("TLD="+tld);
processor.parse(tld);
TldDescriptor d = new TldDescriptor(tld);
d.parse();
_descriptors.add(d);
}
catch(Exception e)
{
Log.warn("Unable to parse TLD: " + tld,e);
}
}
// Create a processor for the tlds and save it
_processor = new TldProcessor ();
}
@Override
public void configure (WebAppContext context) throws Exception
{
TldProcessor processor = (TldProcessor)context.getAttribute(TldProcessor.TAGLIB_PROCESSOR);
if (processor == null)
if (_processor == null)
{
Log.warn("No TldProcessor configured, skipping tld processing");
return;
}
//Create listeners from the parsed tld trees
processor.processRoots();
for (TldDescriptor d:_descriptors)
_processor.process(context, d);
}
@Override
public void postConfigure(WebAppContext context) throws Exception
{
context.setAttribute(TldProcessor.TAGLIB_PROCESSOR, null);
}
@Override
public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception
{
if (_processor == null)
{
Log.warn("No TldProcessor for cloneConfigure");
return;
}
for (TldDescriptor d:_descriptors)
{
_processor.process(context, d);
}
}
@Override
public void deconfigure(WebAppContext context) throws Exception
{
_descriptors.clear();
_processor = null;
}
}

View File

@ -0,0 +1,269 @@
// ========================================================================
// Copyright (c) 2006-2010 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.webapp;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.Servlet;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlParser;
/**
* Descriptor
*
* A web descriptor (web.xml/web-defaults.xml/web-overrides.xml).
*/
public class WebDescriptor extends Descriptor
{
protected static XmlParser _parserSingleton;
public enum MetaDataComplete {NotSet, True, False};
protected MetaDataComplete _metaDataComplete;
protected int _majorVersion = 3; //default to container version
protected int _minorVersion = 0;
protected ArrayList<String> _classNames = new ArrayList<String>();
protected boolean _distributable;
protected boolean _isOrdered = false;
protected List<String> _ordering = new ArrayList<String>();
@Override
public void ensureParser()
throws ClassNotFoundException
{
if (_parserSingleton == null)
{
_parserSingleton = newParser();
}
_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",true);
URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
URL jsp20xsd = null;
URL jsp21xsd = null;
try
{
Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
}
catch (Exception e)
{
Log.ignore(e);
}
finally
{
if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
}
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,"j2ee_1_4.xsd",j2ee14xsd);
redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
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,"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);
return xmlParser;
}
public WebDescriptor (Resource xml)
{
super(xml);
}
public void parse ()
throws Exception
{
super.parse();
processVersion();
processOrdering();
}
public MetaDataComplete getMetaDataComplete()
{
return _metaDataComplete;
}
public int getMajorVersion ()
{
return _majorVersion;
}
public int getMinorVersion()
{
return _minorVersion;
}
public void processVersion ()
{
String version = _root.getAttribute("version", "DTD");
if ("DTD".equals(version))
{
_majorVersion = 2;
_minorVersion = 3;
String dtd = _parser.getDTD();
if (dtd != null && dtd.indexOf("web-app_2_2") >= 0)
{
_majorVersion = 2;
_minorVersion = 2;
}
}
else
{
int dot = version.indexOf(".");
if (dot > 0)
{
_majorVersion = Integer.parseInt(version.substring(0,dot));
_minorVersion = Integer.parseInt(version.substring(dot+1));
}
}
if (_majorVersion < 2 && _minorVersion < 5)
_metaDataComplete = MetaDataComplete.True; // does not apply before 2.5
else
{
String s = (String)_root.getAttribute("metadata-complete");
if (s == null)
_metaDataComplete = MetaDataComplete.NotSet;
else
_metaDataComplete = Boolean.valueOf(s).booleanValue()?MetaDataComplete.True:MetaDataComplete.False;
}
Log.debug(_xml.toString()+": Calculated metadatacomplete = " + _metaDataComplete + " with version=" + version);
}
public void processOrdering ()
{
//Process the web.xml's optional <absolute-ordering> element
XmlParser.Node ordering = _root.get("absolute-ordering");
if (ordering == null)
return;
_isOrdered = true;
//If an absolute-ordering was already set, then ignore it in favour of this new one
// _processor.setOrdering(new AbsoluteOrdering());
Iterator iter = ordering.iterator();
XmlParser.Node node = null;
while (iter.hasNext())
{
Object o = iter.next();
if (!(o instanceof XmlParser.Node)) continue;
node = (XmlParser.Node) o;
if (node.getTag().equalsIgnoreCase("others"))
//((AbsoluteOrdering)_processor.getOrdering()).addOthers();
_ordering.add("others");
else if (node.getTag().equalsIgnoreCase("name"))
//((AbsoluteOrdering)_processor.getOrdering()).add(node.toString(false,true));
_ordering.add(node.toString(false,true));
}
}
public void addClassName (String className)
{
if (!_classNames.contains(className))
_classNames.add(className);
}
public ArrayList<String> getClassNames ()
{
return _classNames;
}
public void setDistributable (boolean distributable)
{
_distributable = distributable;
}
public boolean isDistributable()
{
return _distributable;
}
public void setValidating (boolean validating)
{
_validating = validating;
}
public boolean isOrdered()
{
return _isOrdered;
}
public List<String> getOrdering()
{
return _ordering;
}
}

View File

@ -15,7 +15,6 @@ package org.eclipse.jetty.webapp;
import java.io.IOException;
import java.net.MalformedURLException;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.util.log.Log;