423361 Make all listeners injectable irrespective of method of declaration (descriptor, api, annotation)

This commit is contained in:
Jan Bartel 2013-12-12 14:41:25 +11:00
parent 120e0e59ca
commit dfe5889bc4
13 changed files with 491 additions and 222 deletions

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.annotations;
import java.util.EventListener;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestAttributeListener;
@ -26,6 +28,8 @@ import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.eclipse.jetty.servlet.ListenerHolder;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@ -62,9 +66,7 @@ public class WebListenerAnnotation extends DiscoveredAnnotation
*/
public void apply()
{
// TODO check algorithm against ordering rules for descriptors v annotations
Class clazz = getTargetClass();
Class<? extends java.util.EventListener> clazz = (Class<? extends EventListener>)getTargetClass();
if (clazz == null)
{
@ -82,10 +84,15 @@ public class WebListenerAnnotation extends DiscoveredAnnotation
HttpSessionAttributeListener.class.isAssignableFrom(clazz) ||
HttpSessionIdListener.class.isAssignableFrom(clazz))
{
java.util.EventListener listener = (java.util.EventListener)_context.getServletContext().createListener(clazz);
java.util.EventListener listener = (java.util.EventListener)_context.getServletContext().createInstance(clazz);
MetaData metaData = _context.getMetaData();
if (metaData.getOrigin(clazz.getName()+".listener") == Origin.NotSet)
{
ListenerHolder h = _context.getServletHandler().newListenerHolder(Source.ANNOTATION);
h.setListener(listener);
_context.getServletHandler().addListener(h);
_context.addEventListener(listener);
}
}
else
LOG.warn(clazz.getName()+" does not implement one of the servlet listener interfaces");

View File

@ -2180,7 +2180,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
try
{
Class<? extends EventListener> clazz = _classLoader==null?Loader.loadClass(ContextHandler.class,className):_classLoader.loadClass(className);
checkListener(clazz);
addListener(clazz);
}
catch (ClassNotFoundException e)
@ -2207,13 +2206,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (!_enabled)
throw new UnsupportedOperationException();
checkListener(listenerClass);
try
{
EventListener e = createListener(listenerClass);
ContextHandler.this.addEventListener(e);
ContextHandler.this.addProgrammaticListener(e);
addListener(e);
}
catch (ServletException e)
{

View File

@ -0,0 +1,209 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.UnavailableException;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* AbstractHolder
*
* Base class for all servlet-related classes that may be lazily instantiated (eg servlet, filter,
* listener), and/or require metadata to be held regarding their origin
* (web.xml, annotation, programmatic api etc).
*
*/
public abstract class BaseHolder<T> extends AbstractLifeCycle implements Dumpable
{
private static final Logger LOG = Log.getLogger(BaseHolder.class);
public enum Source { EMBEDDED, JAVAX_API, DESCRIPTOR, ANNOTATION };
final protected Source _source;
protected transient Class<? extends T> _class;
protected String _className;
protected boolean _extInstance;
protected ServletHandler _servletHandler;
/* ---------------------------------------------------------------- */
protected BaseHolder(Source source)
{
_source=source;
}
/* ------------------------------------------------------------ */
public Source getSource()
{
return _source;
}
/* ------------------------------------------------------------ */
/**
* Do any setup necessary after starting
* @throws Exception
*/
public void initialize()
throws Exception
{
if (!isStarted())
throw new IllegalStateException("Not started: "+this);
}
/* ------------------------------------------------------------ */
@SuppressWarnings("unchecked")
@Override
public void doStart()
throws Exception
{
//if no class already loaded and no classname, make permanently unavailable
if (_class==null && (_className==null || _className.equals("")))
throw new UnavailableException("No class in holder");
//try to load class
if (_class==null)
{
try
{
_class=Loader.loadClass(Holder.class, _className);
if(LOG.isDebugEnabled())
LOG.debug("Holding {}",_class);
}
catch (Exception e)
{
LOG.warn(e);
throw new UnavailableException(e.getMessage());
}
}
}
/* ------------------------------------------------------------ */
@Override
public void doStop()
throws Exception
{
if (!_extInstance)
_class=null;
}
/* ------------------------------------------------------------ */
@ManagedAttribute(value="Class Name", readonly=true)
public String getClassName()
{
return _className;
}
/* ------------------------------------------------------------ */
public Class<? extends T> getHeldClass()
{
return _class;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the servletHandler.
*/
public ServletHandler getServletHandler()
{
return _servletHandler;
}
/* ------------------------------------------------------------ */
/**
* @param servletHandler The {@link ServletHandler} that will handle requests dispatched to this servlet.
*/
public void setServletHandler(ServletHandler servletHandler)
{
_servletHandler = servletHandler;
}
/* ------------------------------------------------------------ */
/**
* @param className The className to set.
*/
public void setClassName(String className)
{
_className = className;
_class=null;
}
/* ------------------------------------------------------------ */
/**
* @param held The class to hold
*/
public void setHeldClass(Class<? extends T> held)
{
_class=held;
if (held!=null)
{
_className=held.getName();
}
}
/* ------------------------------------------------------------ */
protected void illegalStateIfContextStarted()
{
if (_servletHandler!=null)
{
ServletContext context=_servletHandler.getServletContext();
if ((context instanceof ContextHandler.Context) && ((ContextHandler.Context)context).getContextHandler().isStarted())
throw new IllegalStateException("Started");
}
}
/* ------------------------------------------------------------ */
/**
* @return True if this holder was created for a specific instance.
*/
public boolean isInstance()
{
return _extInstance;
}
/* ------------------------------------------------------------ */
@Override
public void dump(Appendable out, String indent) throws IOException
{
out.append(toString())
.append(" - ").append(AbstractLifeCycle.getState(this)).append("\n");
}
/* ------------------------------------------------------------ */
@Override
public String dump()
{
return ContainerLifeCycle.dump(this);
}
}

View File

@ -28,45 +28,37 @@ import java.util.Set;
import javax.servlet.Registration;
import javax.servlet.ServletContext;
import javax.servlet.UnavailableException;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* --------------------------------------------------------------------- */
/**
*
* Holder
*
* Specialization of AbstractHolder for servlet-related classes that
* have init-params etc
*
*/
@ManagedObject("Holder - a container for servlets and the like")
public class Holder<T> extends AbstractLifeCycle implements Dumpable
public class Holder<T> extends BaseHolder<T>
{
public enum Source { EMBEDDED, JAVAX_API, DESCRIPTOR, ANNOTATION };
final private Source _source;
private static final Logger LOG = Log.getLogger(Holder.class);
protected transient Class<? extends T> _class;
protected final Map<String,String> _initParams=new HashMap<String,String>(3);
protected String _className;
protected String _displayName;
protected boolean _extInstance;
protected boolean _asyncSupported;
/* ---------------------------------------------------------------- */
protected String _name;
protected ServletHandler _servletHandler;
/* ---------------------------------------------------------------- */
protected Holder(Source source)
{
_source=source;
super(source);
switch(_source)
{
case JAVAX_API:
@ -79,82 +71,7 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
}
}
/* ------------------------------------------------------------ */
public Source getSource()
{
return _source;
}
/* ------------------------------------------------------------ */
/**
* @return True if this holder was created for a specific instance.
*/
public boolean isInstance()
{
return _extInstance;
}
/* ------------------------------------------------------------ */
/**
* Do any setup necessary after starting
* @throws Exception
*/
public void initialize()
throws Exception
{
if (!isStarted())
throw new IllegalStateException("Not started: "+this);
}
/* ------------------------------------------------------------ */
@SuppressWarnings("unchecked")
@Override
public void doStart()
throws Exception
{
//if no class already loaded and no classname, make servlet permanently unavailable
if (_class==null && (_className==null || _className.equals("")))
throw new UnavailableException("No class for Servlet or Filter for "+_name);
//try to load class
if (_class==null)
{
try
{
_class=Loader.loadClass(Holder.class, _className);
if(LOG.isDebugEnabled())
LOG.debug("Holding {}",_class);
}
catch (Exception e)
{
LOG.warn(e);
throw new UnavailableException(e.getMessage());
}
}
}
/* ------------------------------------------------------------ */
@Override
public void doStop()
throws Exception
{
if (!_extInstance)
_class=null;
}
/* ------------------------------------------------------------ */
@ManagedAttribute(value="Class Name", readonly=true)
public String getClassName()
{
return _className;
}
/* ------------------------------------------------------------ */
public Class<? extends T> getHeldClass()
{
return _class;
}
/* ------------------------------------------------------------ */
@ManagedAttribute(value="Display Name", readonly=true)
@ -193,29 +110,19 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
return _name;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the servletHandler.
*/
public ServletHandler getServletHandler()
{
return _servletHandler;
}
/* ------------------------------------------------------------ */
public void destroyInstance(Object instance)
throws Exception
{
}
/* ------------------------------------------------------------ */
/**
* @param className The className to set.
*/
public void setClassName(String className)
{
_className = className;
_class=null;
super.setClassName(className);
if (_name==null)
_name=className+"-"+Integer.toHexString(this.hashCode());
}
@ -226,10 +133,9 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
*/
public void setHeldClass(Class<? extends T> held)
{
_class=held;
super.setHeldClass(held);
if (held!=null)
{
_className=held.getName();
if (_name==null)
_name=held.getName()+"-"+Integer.toHexString(this.hashCode());
}
@ -266,14 +172,6 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
_name = name;
}
/* ------------------------------------------------------------ */
/**
* @param servletHandler The {@link ServletHandler} that will handle requests dispatched to this servlet.
*/
public void setServletHandler(ServletHandler servletHandler)
{
_servletHandler = servletHandler;
}
/* ------------------------------------------------------------ */
public void setAsyncSupported(boolean suspendable)
@ -287,23 +185,12 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
return _asyncSupported;
}
/* ------------------------------------------------------------ */
protected void illegalStateIfContextStarted()
{
if (_servletHandler!=null)
{
ServletContext context=_servletHandler.getServletContext();
if ((context instanceof ContextHandler.Context) && ((ContextHandler.Context)context).getContextHandler().isStarted())
throw new IllegalStateException("Started");
}
}
/* ------------------------------------------------------------ */
@Override
public void dump(Appendable out, String indent) throws IOException
{
out.append(toString())
.append(" - ").append(AbstractLifeCycle.getState(this)).append("\n");
super.dump(out,indent);
ContainerLifeCycle.dump(out,indent,_initParams.entrySet());
}
@ -311,7 +198,7 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
@Override
public String dump()
{
return ContainerLifeCycle.dump(this);
return super.dump();
}
/* ------------------------------------------------------------ */
@ -422,8 +309,6 @@ public class Holder<T> extends AbstractLifeCycle implements Dumpable
Holder.this.getInitParameters().putAll(initParameters);
return Collections.emptySet();
}
}
}

View File

@ -0,0 +1,65 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.servlet;
import java.util.EventListener;
/**
* ListenerHolder
*
* Specialization of AbstractHolder for servlet listeners. This
* allows us to record where the listener originated - web.xml,
* annotation, api etc.
*/
public class ListenerHolder extends BaseHolder<EventListener>
{
private EventListener _listener;
public ListenerHolder(Source source)
{
super(source);
}
public void setListener(EventListener listener)
{
_listener = listener;
setClassName(listener.getClass().getName());
setHeldClass(listener.getClass());
_extInstance=true;
}
public EventListener getListener()
{
return _listener;
}
@Override
public void doStart() throws Exception
{
//Listeners always have an instance eagerly created, it cannot be deferred to the doStart method
if (_listener == null)
throw new IllegalStateException("No listener instance");
super.doStart();
}
}

View File

@ -59,6 +59,7 @@ import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ -266,18 +267,22 @@ public class ServletContextHandler extends ContextHandler
@Override
protected void startContext() throws Exception
{
if (_servletHandler != null)
{
for (int i=_decorators.size()-1;i>=0; i--)
{
Decorator decorator = _decorators.get(i);
if (_servletHandler.getFilters()!=null)
for (FilterHolder holder:_servletHandler.getFilters())
decorator.decorate(holder);
if(_servletHandler.getServlets()!=null)
for (ServletHolder holder:_servletHandler.getServlets())
decorator.decorate(holder);
if (_servletHandler != null)
{
//Call decorators on all holders, and also on any EventListeners before
//decorators are called on any other classes (like servlets and filters)
for (int i=_decorators.size()-1;i>=0; i--)
{
Decorator decorator = _decorators.get(i);
//Do any decorations on the ListenerHolders AND the listener instances first up
if (_servletHandler.getListeners()!=null)
{
for (ListenerHolder holder:_servletHandler.getListeners())
{
decorator.decorate(holder.getListener());
}
}
}
}
@ -908,7 +913,7 @@ public class ServletContextHandler extends ContextHandler
if (holder == null)
{
//new filter
holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
holder = handler.newFilterHolder(Source.JAVAX_API);
holder.setName(filterName);
holder.setHeldClass(filterClass);
handler.addFilter(holder);
@ -945,7 +950,7 @@ public class ServletContextHandler extends ContextHandler
if (holder == null)
{
//new filter
holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
holder = handler.newFilterHolder(Source.JAVAX_API);
holder.setName(filterName);
holder.setClassName(className);
handler.addFilter(holder);
@ -983,7 +988,7 @@ public class ServletContextHandler extends ContextHandler
if (holder == null)
{
//new filter
holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
holder = handler.newFilterHolder(Source.JAVAX_API);
holder.setName(filterName);
holder.setFilter(filter);
handler.addFilter(holder);
@ -1021,7 +1026,7 @@ public class ServletContextHandler extends ContextHandler
if (holder == null)
{
//new servlet
holder = handler.newServletHolder(Holder.Source.JAVAX_API);
holder = handler.newServletHolder(Source.JAVAX_API);
holder.setName(servletName);
holder.setHeldClass(servletClass);
handler.addServlet(holder);
@ -1060,7 +1065,7 @@ public class ServletContextHandler extends ContextHandler
if (holder == null)
{
//new servlet
holder = handler.newServletHolder(Holder.Source.JAVAX_API);
holder = handler.newServletHolder(Source.JAVAX_API);
holder.setName(servletName);
holder.setClassName(className);
handler.addServlet(holder);
@ -1097,7 +1102,7 @@ public class ServletContextHandler extends ContextHandler
ServletHolder holder = handler.getServlet(servletName);
if (holder == null)
{
holder = handler.newServletHolder(Holder.Source.JAVAX_API);
holder = handler.newServletHolder(Source.JAVAX_API);
holder.setName(servletName);
holder.setServlet(servlet);
handler.addServlet(holder);
@ -1134,6 +1139,11 @@ public class ServletContextHandler extends ContextHandler
try
{
T f = createInstance(c);
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
f=decorator.decorate(f);
}
return f;
}
catch (Exception e)
@ -1149,6 +1159,11 @@ public class ServletContextHandler extends ContextHandler
try
{
T s = createInstance(c);
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
s=decorator.decorate(s);
}
return s;
}
catch (Exception e)
@ -1157,20 +1172,6 @@ public class ServletContextHandler extends ContextHandler
}
}
public <T> T createInstance (Class<T> c) throws Exception
{
T o = super.createInstance(c);
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
o=decorator.decorate(o);
}
return o;
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
@ -1284,6 +1285,9 @@ public class ServletContextHandler extends ContextHandler
if (!_enabled)
throw new UnsupportedOperationException();
super.addListener(t);
ListenerHolder holder = getServletHandler().newListenerHolder(Source.JAVAX_API);
holder.setListener(t);
getServletHandler().addListener(holder);
}
@Override
@ -1302,6 +1306,11 @@ public class ServletContextHandler extends ContextHandler
try
{
T l = createInstance(clazz);
for (int i=_decorators.size()-1; i>=0; i--)
{
Decorator decorator = _decorators.get(i);
l=decorator.decorate(l);
}
return l;
}
catch (Exception e)

View File

@ -65,7 +65,7 @@ import org.eclipse.jetty.server.ServletResponseHttpWrapper;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ScopedHandler;
import org.eclipse.jetty.servlet.Holder.Source;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.eclipse.jetty.util.ArrayUtil;
import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.MultiException;
@ -119,9 +119,12 @@ public class ServletHandler extends ScopedHandler
private final Map<String,ServletHolder> _servletNameMap=new HashMap<>();
private PathMap<ServletHolder> _servletPathMap;
private ListenerHolder[] _listeners=new ListenerHolder[0];
protected final ConcurrentMap<?, ?> _chainCache[] = new ConcurrentMap[FilterMapping.ALL];
protected final Queue<?>[] _chainLRU = new Queue[FilterMapping.ALL];
/* ------------------------------------------------------------ */
@ -285,6 +288,28 @@ public class ServletHandler extends ScopedHandler
updateBeans(_servletMappings, sms);
_servletMappings = sms;
//Retain only Listeners added via jetty apis (is Source.EMBEDDED)
List<ListenerHolder> listenerHolders = new ArrayList<ListenerHolder>();
if (_listeners != null)
{
for (int i=_listeners.length; i-->0;)
{
try
{
_listeners[i].stop();
}
catch(Exception e)
{
LOG.warn(Log.EXCEPTION,e);
}
if (_listeners[i].getSource() == Source.EMBEDDED)
listenerHolders.add(_listeners[i]);
}
}
ListenerHolder[] listeners = (ListenerHolder[])LazyList.toArray(listenerHolders, ListenerHolder.class);
updateBeans(_listeners, listeners);
_listeners = listeners;
//will be regenerated on next start
_filterPathMappings=null;
_filterNameMappings=null;
@ -826,6 +851,40 @@ public class ServletHandler extends ScopedHandler
{
return _filterChainsCached;
}
/* ------------------------------------------------------------ */
/** Add a holder for a listener
* @param filter
*/
public void addListener (ListenerHolder listener)
{
if (listener != null)
setListeners(ArrayUtil.addToArray(getListeners(), listener, ListenerHolder.class));
}
/* ------------------------------------------------------------ */
public ListenerHolder[] getListeners()
{
return _listeners;
}
/* ------------------------------------------------------------ */
public void setListeners(ListenerHolder[] listeners)
{
if (listeners!=null)
for (ListenerHolder holder:listeners)
holder.setServletHandler(this);
updateBeans(_listeners,listeners);
_listeners = listeners;
}
/* ------------------------------------------------------------ */
public ListenerHolder newListenerHolder(Holder.Source source)
{
return new ListenerHolder(source);
}
/* ------------------------------------------------------------ */
/**
@ -836,20 +895,13 @@ public class ServletHandler extends ScopedHandler
return new ServletHolder(source);
}
/* ------------------------------------------------------------ */
/** Convenience method to add a servlet Holder.
public ServletHolder newServletHolder(Class<? extends Servlet> servlet)
{
return new ServletHolder(servlet);
}
/* ------------------------------------------------------------ */
/** Convenience method to add a servlet.
* @return The servlet holder.
*/
public ServletHolder addServletWithMapping (String className,String pathSpec)
{
ServletHolder holder = newServletHolder(Holder.Source.EMBEDDED);
ServletHolder holder = newServletHolder(Source.EMBEDDED);
holder.setClassName(className);
addServletWithMapping(holder,pathSpec);
return holder;
@ -861,7 +913,7 @@ public class ServletHandler extends ScopedHandler
*/
public ServletHolder addServletWithMapping (Class<? extends Servlet> servlet,String pathSpec)
{
ServletHolder holder = newServletHolder(Holder.Source.EMBEDDED);
ServletHolder holder = newServletHolder(Source.EMBEDDED);
holder.setHeldClass(servlet);
addServletWithMapping(holder,pathSpec);
@ -948,7 +1000,7 @@ public class ServletHandler extends ScopedHandler
*/
public FilterHolder addFilterWithMapping (Class<? extends Filter> filter,String pathSpec,EnumSet<DispatcherType> dispatches)
{
FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
FilterHolder holder = newFilterHolder(Source.EMBEDDED);
holder.setHeldClass(filter);
addFilterWithMapping(holder,pathSpec,dispatches);
@ -964,7 +1016,7 @@ public class ServletHandler extends ScopedHandler
*/
public FilterHolder addFilterWithMapping (String className,String pathSpec,EnumSet<DispatcherType> dispatches)
{
FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
FilterHolder holder = newFilterHolder(Source.EMBEDDED);
holder.setClassName(className);
addFilterWithMapping(holder,pathSpec,dispatches);
@ -1016,7 +1068,7 @@ public class ServletHandler extends ScopedHandler
*/
public FilterHolder addFilterWithMapping (Class<? extends Filter> filter,String pathSpec,int dispatches)
{
FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
FilterHolder holder = newFilterHolder(Source.EMBEDDED);
holder.setHeldClass(filter);
addFilterWithMapping(holder,pathSpec,dispatches);
@ -1032,7 +1084,7 @@ public class ServletHandler extends ScopedHandler
*/
public FilterHolder addFilterWithMapping (String className,String pathSpec,int dispatches)
{
FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
FilterHolder holder = newFilterHolder(Source.EMBEDDED);
holder.setClassName(className);
addFilterWithMapping(holder,pathSpec,dispatches);

View File

@ -521,6 +521,8 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
_servlet=newInstance();
if (_config==null)
_config=new Config();
// Handle run as
if (_identityService!=null)

View File

@ -48,26 +48,35 @@ import java.util.Set;
import javax.servlet.ServletRegistration;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.junit.Test;
/**
* @version $Rev$ $Date$
*/
public class HolderTest {
public class HolderTest
{
@Test
public void testInitParams() throws Exception {
ServletHolder holder = new ServletHolder(Holder.Source.JAVAX_API);
public void testInitParams() throws Exception
{
ServletHolder holder = new ServletHolder(Source.JAVAX_API);
ServletRegistration reg = holder.getRegistration();
try {
try
{
reg.setInitParameter(null, "foo");
fail("null name accepted");
} catch (IllegalArgumentException e) {
}
try {
catch (IllegalArgumentException e)
{
}
try
{
reg.setInitParameter("foo", null);
fail("null value accepted");
} catch (IllegalArgumentException e) {
}
catch (IllegalArgumentException e)
{
}
reg.setInitParameter("foo", "bar");
assertFalse(reg.setInitParameter("foo", "foo"));
@ -75,15 +84,21 @@ public class HolderTest {
Set<String> clash = reg.setInitParameters(Collections.singletonMap("foo", "bax"));
assertTrue("should be one clash", clash != null && clash.size() == 1);
try {
reg.setInitParameters(Collections.singletonMap((String)null, "bax"));
try
{
reg.setInitParameters(Collections.singletonMap((String) null, "bax"));
fail("null name in map accepted");
} catch (IllegalArgumentException e) {
}
try {
reg.setInitParameters(Collections.singletonMap("foo", (String)null));
catch (IllegalArgumentException e)
{
}
try
{
reg.setInitParameters(Collections.singletonMap("foo", (String) null));
fail("null value in map accepted");
} catch (IllegalArgumentException e) {
}
catch (IllegalArgumentException e)
{
}
Set<String> clash2 = reg.setInitParameters(Collections.singletonMap("FOO", "bax"));

View File

@ -26,25 +26,25 @@ import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.servlet.Holder.Source;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.junit.Before;
import org.junit.Test;
public class ServletHandlerTest
{
FilterHolder fh1 = new FilterHolder(Holder.Source.DESCRIPTOR);
FilterHolder fh1 = new FilterHolder(Source.DESCRIPTOR);
FilterMapping fm1 = new FilterMapping();
FilterHolder fh2 = new FilterHolder(Holder.Source.DESCRIPTOR);
FilterHolder fh2 = new FilterHolder(Source.DESCRIPTOR);
FilterMapping fm2 = new FilterMapping();
FilterHolder fh3 = new FilterHolder(Holder.Source.JAVAX_API);
FilterHolder fh3 = new FilterHolder(Source.JAVAX_API);
FilterMapping fm3 = new FilterMapping();
FilterHolder fh4 = new FilterHolder(Holder.Source.JAVAX_API);
FilterHolder fh4 = new FilterHolder(Source.JAVAX_API);
FilterMapping fm4 = new FilterMapping();
FilterHolder fh5 = new FilterHolder(Holder.Source.JAVAX_API);
FilterHolder fh5 = new FilterHolder(Source.JAVAX_API);
FilterMapping fm5 = new FilterMapping();

View File

@ -39,8 +39,9 @@ import org.eclipse.jetty.security.authentication.FormAuthenticator;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.eclipse.jetty.servlet.JspPropertyGroupServlet;
import org.eclipse.jetty.servlet.ListenerHolder;
import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
import org.eclipse.jetty.servlet.ServletContextHandler.JspPropertyGroup;
import org.eclipse.jetty.servlet.ServletContextHandler.TagLib;
@ -198,7 +199,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
*/
if (holder == null)
{
holder = context.getServletHandler().newServletHolder(Holder.Source.DESCRIPTOR);
holder = context.getServletHandler().newServletHolder(Source.DESCRIPTOR);
holder.setName(servlet_name);
context.getServletHandler().addServlet(holder);
}
@ -1657,7 +1658,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
FilterHolder holder = context.getServletHandler().getFilter(name);
if (holder == null)
{
holder = context.getServletHandler().newFilterHolder(Holder.Source.DESCRIPTOR);
holder = context.getServletHandler().newFilterHolder(Source.DESCRIPTOR);
holder.setName(name);
context.getServletHandler().addFilter(holder);
}
@ -1899,21 +1900,14 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
* @throws InstantiationException
* @throws IllegalAccessException
*/
protected EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws ServletException, InstantiationException, IllegalAccessException
protected EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws Exception
{
try
{
return context.getServletContext().createListener(clazz);
}
catch (ServletException se)
{
Throwable cause = se.getRootCause();
if (cause instanceof InstantiationException)
throw (InstantiationException)cause;
if (cause instanceof IllegalAccessException)
throw (IllegalAccessException)cause;
throw se;
}
ListenerHolder h = context.getServletHandler().newListenerHolder(Source.DESCRIPTOR);
EventListener l = context.getServletContext().createInstance(clazz);
h.setListener(l);
context.getServletHandler().addListener(h);
return l;
}
/**

View File

@ -267,6 +267,10 @@ public class AnnotationTest extends HttpServlet
Boolean annotatedListenerInject = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.sclInjectWebListenerTest");
out.println("<p><b>Result: "+(annotatedListenerInject.booleanValue()?"<span class=\"pass\">PASS":"<span class=\"fail\">FAIL")+"</span></b></p>");
out.println("<h2>Programmatic Listener Injected</h2>");
Boolean programListenerInject = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.programListenerInjectTest");
out.println("<p><b>Result: "+(programListenerInject.booleanValue()?"<span class=\"pass\">PASS":"<span class=\"fail\">FAIL")+"</span></b></p>");
out.println("<h2>Invalid Type for Listener Detection</h2>");
Boolean badListener = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.invalidListenerRegoTest");
out.println("<p><b>Result: "+(badListener.booleanValue()?"<span class=\"pass\">PASS":"<span class=\"fail\">FAIL")+"</span></b></p>");

View File

@ -34,6 +34,7 @@ import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
@ -41,7 +42,7 @@ import javax.servlet.http.HttpSessionListener;
@WebListener
public class TestListener implements HttpSessionListener, HttpSessionAttributeListener, HttpSessionActivationListener, ServletContextListener, ServletContextAttributeListener, ServletRequestListener, ServletRequestAttributeListener
{
public class NaughtyServletContextListener implements ServletContextListener
public static class NaughtyServletContextListener implements ServletContextListener
{
@Override
@ -57,8 +58,25 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeL
}
}
public class InvalidListener implements EventListener
public static class InvalidListener implements EventListener
{
public InvalidListener()
{}
}
public static class ValidListener implements HttpSessionIdListener
{
@Resource(mappedName="maxAmount")
private Double maxAmount;
public ValidListener()
{}
@Override
public void sessionIdChanged(HttpSessionEvent event, String oldSessionId)
{
}
}
@ -94,6 +112,8 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeL
public void contextInitialized(ServletContextEvent sce)
{
System.err.println("Calling TestListener.contextInitialized");
sce.getServletContext().setAttribute("com.acme.AnnotationTest.sclInjectTest", Boolean.valueOf(maxAmount != null));
//Can't add a ServletContextListener from a ServletContextListener even if it is declared in web.xml
@ -126,6 +146,17 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeL
{
sce.getServletContext().setAttribute("com.acme.AnnotationTest.invalidListenerRegoTest", Boolean.FALSE);
}
//Programmatically add a listener and make sure its injected
try
{
ValidListener l = sce.getServletContext().createListener(ValidListener.class);
sce.getServletContext().setAttribute("com.acme.AnnotationTest.programListenerInjectTest", Boolean.valueOf(l != null && l.maxAmount != null));
}
catch (Exception e)
{
sce.getServletContext().setAttribute("com.acme.AnnotationTest.programListenerInjectTest", Boolean.FALSE);
}
}
public void contextDestroyed(ServletContextEvent sce)