Fix #5835 Durable filters and servlets with a general ServletHandler cleanup update indexes after updating mapping update mappings/indexes before destroyed listeners Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
cc81b309f3
commit
c59de808f1
|
@ -651,7 +651,24 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener instanceof ServletContextListener)
|
if (listener instanceof ServletContextListener)
|
||||||
|
{
|
||||||
|
if (_contextStatus == ContextStatus.INITIALIZED)
|
||||||
|
{
|
||||||
|
ServletContextListener scl = (ServletContextListener)listener;
|
||||||
|
_destroyServletContextListeners.add(scl);
|
||||||
|
if (isStarting())
|
||||||
|
{
|
||||||
|
LOG.warn("ContextListener {} added whilst starting {}", scl, this);
|
||||||
|
callContextInitialized(scl, new ServletContextEvent(_scontext));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG.warn("ContextListener {} added after starting {}", scl, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_servletContextListeners.add((ServletContextListener)listener);
|
_servletContextListeners.add((ServletContextListener)listener);
|
||||||
|
}
|
||||||
|
|
||||||
if (listener instanceof ServletContextAttributeListener)
|
if (listener instanceof ServletContextAttributeListener)
|
||||||
_servletContextAttributeListeners.add((ServletContextAttributeListener)listener);
|
_servletContextAttributeListeners.add((ServletContextAttributeListener)listener);
|
||||||
|
@ -933,31 +950,19 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
||||||
public void contextInitialized() throws Exception
|
public void contextInitialized() throws Exception
|
||||||
{
|
{
|
||||||
// Call context listeners
|
// Call context listeners
|
||||||
switch (_contextStatus)
|
if (_contextStatus == ContextStatus.NOTSET)
|
||||||
{
|
{
|
||||||
case NOTSET:
|
_contextStatus = ContextStatus.INITIALIZED;
|
||||||
|
_destroyServletContextListeners.clear();
|
||||||
|
if (!_servletContextListeners.isEmpty())
|
||||||
{
|
{
|
||||||
try
|
ServletContextEvent event = new ServletContextEvent(_scontext);
|
||||||
|
for (ServletContextListener listener : _servletContextListeners)
|
||||||
{
|
{
|
||||||
_destroyServletContextListeners.clear();
|
callContextInitialized(listener, event);
|
||||||
if (!_servletContextListeners.isEmpty())
|
_destroyServletContextListeners.add(listener);
|
||||||
{
|
|
||||||
ServletContextEvent event = new ServletContextEvent(_scontext);
|
|
||||||
for (ServletContextListener listener : _servletContextListeners)
|
|
||||||
{
|
|
||||||
callContextInitialized(listener, event);
|
|
||||||
_destroyServletContextListeners.add(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_contextStatus = ContextStatus.INITIALIZED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -39,6 +40,7 @@ import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
@ -778,6 +780,71 @@ public class ContextHandlerTest
|
||||||
assertThat("classpath", classpath, containsString(jar.toString()));
|
assertThat("classpath", classpath, containsString(jar.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonDurableContextListener() throws Exception
|
||||||
|
{
|
||||||
|
Server server = new Server();
|
||||||
|
ContextHandler context = new ContextHandler();
|
||||||
|
server.setHandler(context);
|
||||||
|
AtomicInteger initialized = new AtomicInteger();
|
||||||
|
AtomicInteger destroyed = new AtomicInteger();
|
||||||
|
|
||||||
|
context.addEventListener(new ServletContextListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce)
|
||||||
|
{
|
||||||
|
initialized.incrementAndGet();
|
||||||
|
context.addEventListener(new ServletContextListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce)
|
||||||
|
{
|
||||||
|
initialized.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce)
|
||||||
|
{
|
||||||
|
destroyed.incrementAndGet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce)
|
||||||
|
{
|
||||||
|
destroyed.incrementAndGet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LoggerFactory.getLogger(ContextHandler.class).info("Expect WARN ContextListener ... add whilst starting ...");
|
||||||
|
server.start();
|
||||||
|
assertThat(initialized.get(), is(2));
|
||||||
|
|
||||||
|
LoggerFactory.getLogger(ContextHandler.class).info("Expect WARN ContextListener ... add after starting ...");
|
||||||
|
context.addEventListener(new ServletContextListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce)
|
||||||
|
{
|
||||||
|
// This should not get called because added after started
|
||||||
|
initialized.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce)
|
||||||
|
{
|
||||||
|
destroyed.incrementAndGet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assertThat(initialized.get(), is(2));
|
||||||
|
|
||||||
|
server.stop();
|
||||||
|
assertThat(destroyed.get(), is(3));
|
||||||
|
}
|
||||||
|
|
||||||
private void checkResourcePathsForExampleWebApp(String root) throws IOException
|
private void checkResourcePathsForExampleWebApp(String root) throws IOException
|
||||||
{
|
{
|
||||||
File testDirectory = setupTestDirectory();
|
File testDirectory = setupTestDirectory();
|
||||||
|
|
|
@ -16,6 +16,7 @@ package org.eclipse.jetty.servlet;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
@ -27,6 +28,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
|
@ -87,8 +89,8 @@ public class ServletHandler extends ScopedHandler
|
||||||
private final AutoLock _lock = new AutoLock();
|
private final AutoLock _lock = new AutoLock();
|
||||||
private ServletContextHandler _contextHandler;
|
private ServletContextHandler _contextHandler;
|
||||||
private ServletContext _servletContext;
|
private ServletContext _servletContext;
|
||||||
private FilterHolder[] _filters = new FilterHolder[0];
|
private final List<FilterHolder> _filters = new ArrayList<>();
|
||||||
private FilterMapping[] _filterMappings;
|
private final List<FilterMapping> _filterMappings = new ArrayList<>();
|
||||||
private int _matchBeforeIndex = -1; //index of last programmatic FilterMapping with isMatchAfter=false
|
private int _matchBeforeIndex = -1; //index of last programmatic FilterMapping with isMatchAfter=false
|
||||||
private int _matchAfterIndex = -1; //index of 1st programmatic FilterMapping with isMatchAfter=true
|
private int _matchAfterIndex = -1; //index of 1st programmatic FilterMapping with isMatchAfter=true
|
||||||
private boolean _filterChainsCached = true;
|
private boolean _filterChainsCached = true;
|
||||||
|
@ -98,17 +100,18 @@ public class ServletHandler extends ScopedHandler
|
||||||
private IdentityService _identityService;
|
private IdentityService _identityService;
|
||||||
private boolean _allowDuplicateMappings = false;
|
private boolean _allowDuplicateMappings = false;
|
||||||
|
|
||||||
private ServletHolder[] _servlets = new ServletHolder[0];
|
private final List<ServletHolder> _servlets = new ArrayList<>();
|
||||||
private ServletMapping[] _servletMappings;
|
private final List<ServletMapping> _servletMappings = new ArrayList<>();
|
||||||
private final Map<String, FilterHolder> _filterNameMap = new HashMap<>();
|
private final Map<String, FilterHolder> _filterNameMap = new HashMap<>();
|
||||||
private List<FilterMapping> _filterPathMappings;
|
private List<FilterMapping> _filterPathMappings;
|
||||||
private MultiMap<FilterMapping> _filterNameMappings;
|
private MultiMap<FilterMapping> _filterNameMappings;
|
||||||
private List<FilterMapping> _wildFilterNameMappings;
|
private List<FilterMapping> _wildFilterNameMappings;
|
||||||
|
private final List<BaseHolder<?>> _durable = new ArrayList<>();
|
||||||
|
|
||||||
private final Map<String, MappedServlet> _servletNameMap = new HashMap<>();
|
private final Map<String, MappedServlet> _servletNameMap = new HashMap<>();
|
||||||
private PathMappings<MappedServlet> _servletPathMap;
|
private PathMappings<MappedServlet> _servletPathMap;
|
||||||
|
|
||||||
private ListenerHolder[] _listeners = new ListenerHolder[0];
|
private final List<ListenerHolder> _listeners = new ArrayList<>();
|
||||||
private boolean _initialized = false;
|
private boolean _initialized = false;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -126,6 +129,13 @@ public class ServletHandler extends ScopedHandler
|
||||||
return _lock.lock();
|
return _lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> void updateAndSet(Collection<T> target, Collection<T> values)
|
||||||
|
{
|
||||||
|
updateBeans(target, values);
|
||||||
|
target.clear();
|
||||||
|
target.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDumpable(Object o)
|
public boolean isDumpable(Object o)
|
||||||
{
|
{
|
||||||
|
@ -136,17 +146,18 @@ public class ServletHandler extends ScopedHandler
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
{
|
{
|
||||||
dumpObjects(out, indent,
|
dumpObjects(out, indent,
|
||||||
DumpableCollection.fromArray("listeners " + this, _listeners),
|
DumpableCollection.from("listeners " + this, _listeners),
|
||||||
DumpableCollection.fromArray("filters " + this, _filters),
|
DumpableCollection.from("filters " + this, _filters),
|
||||||
DumpableCollection.fromArray("filterMappings " + this, _filterMappings),
|
DumpableCollection.from("filterMappings " + this, _filterMappings),
|
||||||
DumpableCollection.fromArray("servlets " + this, _servlets),
|
DumpableCollection.from("servlets " + this, _servlets),
|
||||||
DumpableCollection.fromArray("servletMappings " + this, _servletMappings));
|
DumpableCollection.from("servletMappings " + this, _servletMappings),
|
||||||
|
DumpableCollection.from("durable " + this, _durable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStart() throws Exception
|
protected void doStart() throws Exception
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
ContextHandler.Context context = ContextHandler.getCurrentContext();
|
ContextHandler.Context context = ContextHandler.getCurrentContext();
|
||||||
_servletContext = context == null ? new ContextHandler.StaticContext() : context;
|
_servletContext = context == null ? new ContextHandler.StaticContext() : context;
|
||||||
|
@ -159,6 +170,11 @@ public class ServletHandler extends ScopedHandler
|
||||||
_identityService = securityHandler.getIdentityService();
|
_identityService = securityHandler.getIdentityService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_durable.clear();
|
||||||
|
_durable.addAll(Arrays.asList(getFilters()));
|
||||||
|
_durable.addAll(Arrays.asList(getServlets()));
|
||||||
|
_durable.addAll(Arrays.asList(getListeners()));
|
||||||
|
|
||||||
updateNameMappings();
|
updateNameMappings();
|
||||||
updateMappings();
|
updateMappings();
|
||||||
|
|
||||||
|
@ -226,113 +242,93 @@ public class ServletHandler extends ScopedHandler
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
super.doStop();
|
super.doStop();
|
||||||
|
|
||||||
// Stop filters
|
// Stop filters
|
||||||
List<FilterHolder> filterHolders = new ArrayList<>();
|
List<FilterHolder> filterHolders = new ArrayList<>();
|
||||||
List<FilterMapping> filterMappings = ArrayUtil.asMutableList(_filterMappings);
|
for (int i = _filters.size(); i-- > 0; )
|
||||||
if (_filters != null)
|
|
||||||
{
|
{
|
||||||
for (int i = _filters.length; i-- > 0; )
|
FilterHolder filter = _filters.get(i);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
FilterHolder filter = _filters[i];
|
filter.stop();
|
||||||
try
|
}
|
||||||
{
|
catch (Exception e)
|
||||||
filter.stop();
|
{
|
||||||
}
|
LOG.warn("Unable to stop filter {}", filter, e);
|
||||||
catch (Exception e)
|
}
|
||||||
{
|
if (_durable.contains(filter))
|
||||||
LOG.warn("Unable to stop filter {}", filter, e);
|
{
|
||||||
}
|
filterHolders.add(filter); //only retain durable
|
||||||
if (filter.getSource() != Source.EMBEDDED)
|
|
||||||
{
|
|
||||||
//remove all of the mappings that were for non-embedded filters
|
|
||||||
_filterNameMap.remove(filter.getName());
|
|
||||||
//remove any mappings associated with this filter
|
|
||||||
filterMappings.removeIf(fm -> fm.getFilterName().equals(filter.getName()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
filterHolders.add(filter); //only retain embedded
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Retain only filters and mappings that were added using jetty api (ie Source.EMBEDDED)
|
//Retain only durable filters
|
||||||
FilterHolder[] fhs = filterHolders.toArray(new FilterHolder[0]);
|
updateBeans(_filters, filterHolders);
|
||||||
updateBeans(_filters, fhs);
|
_filters.clear();
|
||||||
_filters = fhs;
|
_filters.addAll(filterHolders);
|
||||||
FilterMapping[] fms = filterMappings.toArray(new FilterMapping[0]);
|
|
||||||
updateBeans(_filterMappings, fms);
|
|
||||||
_filterMappings = fms;
|
|
||||||
|
|
||||||
_matchAfterIndex = (_filterMappings.length == 0 ? -1 : _filterMappings.length - 1);
|
|
||||||
_matchBeforeIndex = -1;
|
|
||||||
|
|
||||||
// Stop servlets
|
// Stop servlets
|
||||||
List<ServletHolder> servletHolders = new ArrayList<>(); //will be remaining servlets
|
List<ServletHolder> servletHolders = new ArrayList<>(); //will be remaining servlets
|
||||||
List<ServletMapping> servletMappings = ArrayUtil.asMutableList(_servletMappings); //will be remaining mappings
|
for (int i = _servlets.size(); i-- > 0; )
|
||||||
if (_servlets != null)
|
|
||||||
{
|
{
|
||||||
for (int i = _servlets.length; i-- > 0; )
|
ServletHolder servlet = _servlets.get(i);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ServletHolder servlet = _servlets[i];
|
servlet.stop();
|
||||||
try
|
}
|
||||||
{
|
catch (Exception e)
|
||||||
servlet.stop();
|
{
|
||||||
}
|
LOG.warn("Unable to stop servlet {}", servlet, e);
|
||||||
catch (Exception e)
|
}
|
||||||
{
|
|
||||||
LOG.warn("Unable to stop servlet {}", servlet, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (servlet.getSource() != Source.EMBEDDED)
|
if (_durable.contains(servlet))
|
||||||
{
|
{
|
||||||
//remove from servlet name map
|
servletHolders.add(servlet); //only retain embedded
|
||||||
_servletNameMap.remove(servlet.getName());
|
|
||||||
//remove any mappings associated with this servlet
|
|
||||||
servletMappings.removeIf(sm -> sm.getServletName().equals(servlet.getName()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
servletHolders.add(servlet); //only retain embedded
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Retain only Servlets and mappings added via jetty apis (ie Source.EMBEDDED)
|
//Retain only durable Servlets
|
||||||
ServletHolder[] shs = servletHolders.toArray(new ServletHolder[0]);
|
updateBeans(_servlets, servletHolders);
|
||||||
updateBeans(_servlets, shs);
|
_servlets.clear();
|
||||||
_servlets = shs;
|
_servlets.addAll(servletHolders);
|
||||||
ServletMapping[] sms = servletMappings.toArray(new ServletMapping[0]);
|
|
||||||
updateBeans(_servletMappings, sms);
|
updateNameMappings();
|
||||||
_servletMappings = sms;
|
updateAndSet(_servletMappings, _servletMappings.stream().filter(m -> _servletNameMap.containsKey(m.getServletName())).collect(Collectors.toList()));
|
||||||
|
updateAndSet(_filterMappings, _filterMappings.stream().filter(m -> _filterNameMap.containsKey(m.getFilterName())).collect(Collectors.toList()));
|
||||||
|
updateMappings();
|
||||||
|
|
||||||
if (_contextHandler != null)
|
if (_contextHandler != null)
|
||||||
_contextHandler.contextDestroyed();
|
_contextHandler.contextDestroyed();
|
||||||
|
|
||||||
//Retain only Listeners added via jetty apis (is Source.EMBEDDED)
|
//Retain only Listeners added via jetty apis (is Source.EMBEDDED)
|
||||||
List<ListenerHolder> listenerHolders = new ArrayList<>();
|
List<ListenerHolder> listenerHolders = new ArrayList<>();
|
||||||
if (_listeners != null)
|
for (int i = _listeners.size(); i-- > 0; )
|
||||||
{
|
{
|
||||||
for (int i = _listeners.length; i-- > 0; )
|
ListenerHolder listener = _listeners.get(i);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ListenerHolder listener = _listeners[i];
|
listener.stop();
|
||||||
try
|
|
||||||
{
|
|
||||||
listener.stop();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn("Unable to stop listener {}", listener, e);
|
|
||||||
}
|
|
||||||
if (listener.getSource() == Source.EMBEDDED)
|
|
||||||
listenerHolders.add(listener);
|
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOG.warn("Unable to stop listener {}", listener, e);
|
||||||
|
}
|
||||||
|
if (_durable.contains(listener))
|
||||||
|
listenerHolders.add(listener);
|
||||||
}
|
}
|
||||||
ListenerHolder[] listeners = listenerHolders.toArray(new ListenerHolder[0]);
|
|
||||||
updateBeans(_listeners, listeners);
|
|
||||||
_listeners = listeners;
|
|
||||||
|
|
||||||
//will be regenerated on next start
|
updateBeans(_listeners, listenerHolders);
|
||||||
|
_listeners.clear();
|
||||||
|
_listeners.addAll(listenerHolders);
|
||||||
|
|
||||||
|
// Update indexes for prepending filters
|
||||||
|
_matchAfterIndex = (_filterMappings.size() == 0 ? -1 : _filterMappings.size() - 1);
|
||||||
|
_matchBeforeIndex = -1;
|
||||||
|
|
||||||
|
_durable.clear();
|
||||||
_filterPathMappings = null;
|
_filterPathMappings = null;
|
||||||
_filterNameMappings = null;
|
_filterNameMappings = null;
|
||||||
_servletPathMap = null;
|
_servletPathMap = null;
|
||||||
|
@ -348,13 +344,13 @@ public class ServletHandler extends ScopedHandler
|
||||||
@ManagedAttribute(value = "filters", readonly = true)
|
@ManagedAttribute(value = "filters", readonly = true)
|
||||||
public FilterMapping[] getFilterMappings()
|
public FilterMapping[] getFilterMappings()
|
||||||
{
|
{
|
||||||
return _filterMappings;
|
return _filterMappings.toArray(new FilterMapping[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedAttribute(value = "filters", readonly = true)
|
@ManagedAttribute(value = "filters", readonly = true)
|
||||||
public FilterHolder[] getFilters()
|
public FilterHolder[] getFilters()
|
||||||
{
|
{
|
||||||
return _filters;
|
return _filters.toArray(new FilterHolder[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServletContext getServletContext()
|
public ServletContext getServletContext()
|
||||||
|
@ -370,7 +366,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
@ManagedAttribute(value = "mappings of servlets", readonly = true)
|
@ManagedAttribute(value = "mappings of servlets", readonly = true)
|
||||||
public ServletMapping[] getServletMappings()
|
public ServletMapping[] getServletMappings()
|
||||||
{
|
{
|
||||||
return _servletMappings;
|
return _servletMappings.toArray(new ServletMapping[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,13 +377,13 @@ public class ServletHandler extends ScopedHandler
|
||||||
*/
|
*/
|
||||||
public ServletMapping getServletMapping(String pathSpec)
|
public ServletMapping getServletMapping(String pathSpec)
|
||||||
{
|
{
|
||||||
if (pathSpec == null || _servletMappings == null)
|
if (pathSpec == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
ServletMapping mapping = null;
|
ServletMapping mapping = null;
|
||||||
for (int i = 0; i < _servletMappings.length && mapping == null; i++)
|
for (int i = 0; i < _servletMappings.size() && mapping == null; i++)
|
||||||
{
|
{
|
||||||
ServletMapping m = _servletMappings[i];
|
ServletMapping m = _servletMappings.get(i);
|
||||||
if (m.getPathSpecs() != null)
|
if (m.getPathSpecs() != null)
|
||||||
{
|
{
|
||||||
for (String p : m.getPathSpecs())
|
for (String p : m.getPathSpecs())
|
||||||
|
@ -406,7 +402,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
@ManagedAttribute(value = "servlets", readonly = true)
|
@ManagedAttribute(value = "servlets", readonly = true)
|
||||||
public ServletHolder[] getServlets()
|
public ServletHolder[] getServlets()
|
||||||
{
|
{
|
||||||
return _servlets;
|
return _servlets.toArray(new ServletHolder[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ServletHolder> getServlets(Class<?> clazz)
|
public List<ServletHolder> getServlets(Class<?> clazz)
|
||||||
|
@ -483,7 +479,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
FilterChain chain = null;
|
FilterChain chain = null;
|
||||||
|
|
||||||
// find the servlet
|
// find the servlet
|
||||||
if (servletHolder != null && _filterMappings != null && _filterMappings.length > 0)
|
if (servletHolder != null && _filterMappings.size() > 0)
|
||||||
chain = getFilterChain(baseRequest, target.startsWith("/") ? target : null, servletHolder);
|
chain = getFilterChain(baseRequest, target.startsWith("/") ? target : null, servletHolder);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -702,7 +698,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
//Start the listeners so we can call them
|
//Start the listeners so we can call them
|
||||||
Arrays.stream(_listeners).forEach(c);
|
_listeners.forEach(c);
|
||||||
|
|
||||||
//call listeners contextInitialized
|
//call listeners contextInitialized
|
||||||
if (_contextHandler != null)
|
if (_contextHandler != null)
|
||||||
|
@ -713,8 +709,8 @@ public class ServletHandler extends ScopedHandler
|
||||||
|
|
||||||
//Start the filters then the servlets
|
//Start the filters then the servlets
|
||||||
Stream.concat(
|
Stream.concat(
|
||||||
Arrays.stream(_filters),
|
_filters.stream(),
|
||||||
Arrays.stream(_servlets).sorted())
|
_servlets.stream().sorted())
|
||||||
.forEach(c);
|
.forEach(c);
|
||||||
|
|
||||||
mx.ifExceptionThrow();
|
mx.ifExceptionThrow();
|
||||||
|
@ -728,7 +724,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
return _initialized;
|
return _initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initializeHolders(BaseHolder<?>[] holders)
|
protected void initializeHolders(Collection<? extends BaseHolder<?>> holders)
|
||||||
{
|
{
|
||||||
for (BaseHolder<?> holder : holders)
|
for (BaseHolder<?> holder : holders)
|
||||||
{
|
{
|
||||||
|
@ -772,15 +768,16 @@ public class ServletHandler extends ScopedHandler
|
||||||
|
|
||||||
public ListenerHolder[] getListeners()
|
public ListenerHolder[] getListeners()
|
||||||
{
|
{
|
||||||
return _listeners;
|
return _listeners.toArray(new ListenerHolder[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setListeners(ListenerHolder[] listeners)
|
public void setListeners(ListenerHolder[] holders)
|
||||||
{
|
{
|
||||||
if (listeners != null)
|
List<ListenerHolder> listeners = holders == null ? Collections.emptyList() : Arrays.asList(holders);
|
||||||
initializeHolders(listeners);
|
initializeHolders(listeners);
|
||||||
updateBeans(_listeners, listeners);
|
updateBeans(_listeners, listeners);
|
||||||
_listeners = listeners;
|
_listeners.clear();
|
||||||
|
_listeners.addAll(listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenerHolder newListenerHolder(Source source)
|
public ListenerHolder newListenerHolder(Source source)
|
||||||
|
@ -842,7 +839,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
ServletHolder[] holders = getServlets();
|
ServletHolder[] holders = getServlets();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsServletHolder(servlet))
|
if (!containsServletHolder(servlet))
|
||||||
setServlets(ArrayUtil.addToArray(holders, servlet, ServletHolder.class));
|
setServlets(ArrayUtil.addToArray(holders, servlet, ServletHolder.class));
|
||||||
|
@ -870,7 +867,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
if (holder == null)
|
if (holder == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsServletHolder(holder))
|
if (!containsServletHolder(holder))
|
||||||
setServlets(ArrayUtil.addToArray(getServlets(), holder, ServletHolder.class));
|
setServlets(ArrayUtil.addToArray(getServlets(), holder, ServletHolder.class));
|
||||||
|
@ -954,7 +951,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsFilterHolder(holder))
|
if (!containsFilterHolder(holder))
|
||||||
setFilters(ArrayUtil.addToArray(holders, holder, FilterHolder.class));
|
setFilters(ArrayUtil.addToArray(holders, holder, FilterHolder.class));
|
||||||
|
@ -1023,7 +1020,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsFilterHolder(holder))
|
if (!containsFilterHolder(holder))
|
||||||
setFilters(ArrayUtil.addToArray(holders, holder, FilterHolder.class));
|
setFilters(ArrayUtil.addToArray(holders, holder, FilterHolder.class));
|
||||||
|
@ -1052,7 +1049,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
{
|
{
|
||||||
if (filter != null)
|
if (filter != null)
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsFilterHolder(filter))
|
if (!containsFilterHolder(filter))
|
||||||
setFilters(ArrayUtil.addToArray(getFilters(), filter, FilterHolder.class));
|
setFilters(ArrayUtil.addToArray(getFilters(), filter, FilterHolder.class));
|
||||||
|
@ -1072,7 +1069,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
if (filter == null)
|
if (filter == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsFilterHolder(filter))
|
if (!containsFilterHolder(filter))
|
||||||
setFilters(ArrayUtil.addToArray(getFilters(), filter, FilterHolder.class));
|
setFilters(ArrayUtil.addToArray(getFilters(), filter, FilterHolder.class));
|
||||||
|
@ -1089,7 +1086,7 @@ public class ServletHandler extends ScopedHandler
|
||||||
if (filter == null)
|
if (filter == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (!containsFilterHolder(filter))
|
if (!containsFilterHolder(filter))
|
||||||
setFilters(ArrayUtil.prependToArray(filter, getFilters(), FilterHolder.class));
|
setFilters(ArrayUtil.prependToArray(filter, getFilters(), FilterHolder.class));
|
||||||
|
@ -1103,24 +1100,27 @@ public class ServletHandler extends ScopedHandler
|
||||||
*/
|
*/
|
||||||
public void addFilterMapping(FilterMapping mapping)
|
public void addFilterMapping(FilterMapping mapping)
|
||||||
{
|
{
|
||||||
if (mapping != null)
|
if (mapping == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
Source source = (mapping.getFilterHolder() == null ? null : mapping.getFilterHolder().getSource());
|
Source source = (mapping.getFilterHolder() == null ? null : mapping.getFilterHolder().getSource());
|
||||||
FilterMapping[] mappings = getFilterMappings();
|
|
||||||
if (mappings == null || mappings.length == 0)
|
if (_filterMappings.isEmpty())
|
||||||
{
|
{
|
||||||
setFilterMappings(insertFilterMapping(mapping, 0, false));
|
_filterMappings.add(mapping);
|
||||||
if (source == Source.JAVAX_API)
|
if (source == Source.JAVAX_API)
|
||||||
_matchAfterIndex = 0;
|
_matchAfterIndex = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//there are existing entries. If this is a programmatic filtermapping, it is added at the end of the list.
|
//there are existing entries. If this is a programmatic filtermapping, it is added at the end of the list.
|
||||||
//If this is a normal filtermapping, it is inserted after all the other filtermappings (matchBefores and normals),
|
//If this is a normal filtermapping, it is inserted after all the other filtermappings (matchBefores and normals),
|
||||||
//but before the first matchAfter filtermapping.
|
//but before the first matchAfter filtermapping.
|
||||||
if (Source.JAVAX_API == source)
|
if (Source.JAVAX_API == source)
|
||||||
{
|
{
|
||||||
setFilterMappings(insertFilterMapping(mapping, mappings.length - 1, false));
|
_filterMappings.add(mapping);
|
||||||
if (_matchAfterIndex < 0)
|
if (_matchAfterIndex < 0)
|
||||||
_matchAfterIndex = getFilterMappings().length - 1;
|
_matchAfterIndex = getFilterMappings().length - 1;
|
||||||
}
|
}
|
||||||
|
@ -1128,15 +1128,15 @@ public class ServletHandler extends ScopedHandler
|
||||||
{
|
{
|
||||||
//insert non-programmatic filter mappings before any matchAfters, if any
|
//insert non-programmatic filter mappings before any matchAfters, if any
|
||||||
if (_matchAfterIndex < 0)
|
if (_matchAfterIndex < 0)
|
||||||
setFilterMappings(insertFilterMapping(mapping, mappings.length - 1, false));
|
_filterMappings.add(mapping);
|
||||||
else
|
else
|
||||||
{
|
_filterMappings.add(_matchAfterIndex++, mapping);
|
||||||
FilterMapping[] newMappings = insertFilterMapping(mapping, _matchAfterIndex, true);
|
|
||||||
++_matchAfterIndex;
|
|
||||||
setFilterMappings(newMappings);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addBean(mapping);
|
||||||
|
if (isRunning())
|
||||||
|
updateMappings();
|
||||||
|
invalidateChainsCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1147,13 +1147,15 @@ public class ServletHandler extends ScopedHandler
|
||||||
*/
|
*/
|
||||||
public void prependFilterMapping(FilterMapping mapping)
|
public void prependFilterMapping(FilterMapping mapping)
|
||||||
{
|
{
|
||||||
if (mapping != null)
|
if (mapping == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
Source source = (mapping.getFilterHolder() == null ? null : mapping.getFilterHolder().getSource());
|
Source source = (mapping.getFilterHolder() == null ? null : mapping.getFilterHolder().getSource());
|
||||||
FilterMapping[] mappings = getFilterMappings();
|
if (_filterMappings.isEmpty())
|
||||||
if (mappings == null || mappings.length == 0)
|
|
||||||
{
|
{
|
||||||
setFilterMappings(insertFilterMapping(mapping, 0, false));
|
_filterMappings.add(mapping);
|
||||||
if (Source.JAVAX_API == source)
|
if (Source.JAVAX_API == source)
|
||||||
_matchBeforeIndex = 0;
|
_matchBeforeIndex = 0;
|
||||||
}
|
}
|
||||||
|
@ -1169,235 +1171,168 @@ public class ServletHandler extends ScopedHandler
|
||||||
{
|
{
|
||||||
//no programmatically defined prepended filter mappings yet, prepend this one
|
//no programmatically defined prepended filter mappings yet, prepend this one
|
||||||
_matchBeforeIndex = 0;
|
_matchBeforeIndex = 0;
|
||||||
FilterMapping[] newMappings = insertFilterMapping(mapping, 0, true);
|
_filterMappings.add(0, mapping);
|
||||||
setFilterMappings(newMappings);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FilterMapping[] newMappings = insertFilterMapping(mapping, _matchBeforeIndex, false);
|
_filterMappings.add(1 + _matchBeforeIndex++, mapping);
|
||||||
++_matchBeforeIndex;
|
|
||||||
setFilterMappings(newMappings);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//non programmatically defined, just prepend to list
|
//non programmatically defined, just prepend to list
|
||||||
FilterMapping[] newMappings = insertFilterMapping(mapping, 0, true);
|
_filterMappings.add(0, mapping);
|
||||||
setFilterMappings(newMappings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//adjust matchAfterIndex ptr to take account of the mapping we just prepended
|
//adjust matchAfterIndex ptr to take account of the mapping we just prepended
|
||||||
if (_matchAfterIndex >= 0)
|
if (_matchAfterIndex >= 0)
|
||||||
++_matchAfterIndex;
|
++_matchAfterIndex;
|
||||||
}
|
}
|
||||||
|
addBean(mapping);
|
||||||
|
if (isRunning())
|
||||||
|
updateMappings();
|
||||||
|
invalidateChainsCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert a filtermapping in the list
|
|
||||||
*
|
|
||||||
* @param mapping the FilterMapping to add
|
|
||||||
* @param pos the position in the existing arry at which to add it
|
|
||||||
* @param before if true, insert before pos, if false insert after it
|
|
||||||
* @return the new FilterMappings post-insert
|
|
||||||
*/
|
|
||||||
protected FilterMapping[] insertFilterMapping(FilterMapping mapping, int pos, boolean before)
|
|
||||||
{
|
|
||||||
if (pos < 0)
|
|
||||||
throw new IllegalArgumentException("FilterMapping insertion pos < 0");
|
|
||||||
FilterMapping[] mappings = getFilterMappings();
|
|
||||||
|
|
||||||
if (mappings == null || mappings.length == 0)
|
|
||||||
{
|
|
||||||
return new FilterMapping[]{mapping};
|
|
||||||
}
|
|
||||||
FilterMapping[] newMappings = new FilterMapping[mappings.length + 1];
|
|
||||||
|
|
||||||
if (before)
|
|
||||||
{
|
|
||||||
//copy existing filter mappings up to but not including the pos
|
|
||||||
System.arraycopy(mappings, 0, newMappings, 0, pos);
|
|
||||||
|
|
||||||
//add in the new mapping
|
|
||||||
newMappings[pos] = mapping;
|
|
||||||
|
|
||||||
//copy the old pos mapping and any remaining existing mappings
|
|
||||||
System.arraycopy(mappings, pos, newMappings, pos + 1, mappings.length - pos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//copy existing filter mappings up to and including the pos
|
|
||||||
System.arraycopy(mappings, 0, newMappings, 0, pos + 1);
|
|
||||||
//add in the new mapping after the pos
|
|
||||||
newMappings[pos + 1] = mapping;
|
|
||||||
|
|
||||||
//copy the remaining existing mappings
|
|
||||||
if (mappings.length > pos + 1)
|
|
||||||
System.arraycopy(mappings, pos + 1, newMappings, pos + 2, mappings.length - (pos + 1));
|
|
||||||
}
|
|
||||||
return newMappings;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateNameMappings()
|
protected void updateNameMappings()
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
// update filter name map
|
// update filter name map
|
||||||
_filterNameMap.clear();
|
_filterNameMap.clear();
|
||||||
if (_filters != null)
|
for (FilterHolder filter : _filters)
|
||||||
{
|
{
|
||||||
for (FilterHolder filter : _filters)
|
_filterNameMap.put(filter.getName(), filter);
|
||||||
{
|
filter.setServletHandler(this);
|
||||||
_filterNameMap.put(filter.getName(), filter);
|
|
||||||
filter.setServletHandler(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map servlet names to holders
|
// Map servlet names to holders
|
||||||
_servletNameMap.clear();
|
_servletNameMap.clear();
|
||||||
if (_servlets != null)
|
// update the maps
|
||||||
|
for (ServletHolder servlet : _servlets)
|
||||||
{
|
{
|
||||||
// update the maps
|
_servletNameMap.put(servlet.getName(), new MappedServlet(null, servlet));
|
||||||
for (ServletHolder servlet : _servlets)
|
servlet.setServletHandler(this);
|
||||||
{
|
|
||||||
_servletNameMap.put(servlet.getName(), new MappedServlet(null, servlet));
|
|
||||||
servlet.setServletHandler(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateMappings()
|
protected void updateMappings()
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
// update filter mappings
|
// update filter mappings
|
||||||
if (_filterMappings == null)
|
_filterPathMappings = new ArrayList<>();
|
||||||
|
_filterNameMappings = new MultiMap<>();
|
||||||
|
for (FilterMapping filtermapping : _filterMappings)
|
||||||
{
|
{
|
||||||
_filterPathMappings = null;
|
FilterHolder filterHolder = _filterNameMap.get(filtermapping.getFilterName());
|
||||||
_filterNameMappings = null;
|
if (filterHolder == null)
|
||||||
_wildFilterNameMappings = Collections.emptyList();
|
throw new IllegalStateException("No filter named " + filtermapping.getFilterName());
|
||||||
}
|
filtermapping.setFilterHolder(filterHolder);
|
||||||
else
|
if (filtermapping.getPathSpecs() != null)
|
||||||
{
|
_filterPathMappings.add(filtermapping);
|
||||||
_filterPathMappings = new ArrayList<>();
|
|
||||||
_filterNameMappings = new MultiMap<>();
|
|
||||||
for (FilterMapping filtermapping : _filterMappings)
|
|
||||||
{
|
|
||||||
FilterHolder filterHolder = _filterNameMap.get(filtermapping.getFilterName());
|
|
||||||
if (filterHolder == null)
|
|
||||||
throw new IllegalStateException("No filter named " + filtermapping.getFilterName());
|
|
||||||
filtermapping.setFilterHolder(filterHolder);
|
|
||||||
if (filtermapping.getPathSpecs() != null)
|
|
||||||
_filterPathMappings.add(filtermapping);
|
|
||||||
|
|
||||||
if (filtermapping.getServletNames() != null)
|
if (filtermapping.getServletNames() != null)
|
||||||
|
{
|
||||||
|
String[] names = filtermapping.getServletNames();
|
||||||
|
for (String name : names)
|
||||||
{
|
{
|
||||||
String[] names = filtermapping.getServletNames();
|
if (name != null)
|
||||||
for (String name : names)
|
_filterNameMappings.add(name, filtermapping);
|
||||||
{
|
|
||||||
if (name != null)
|
|
||||||
_filterNameMappings.add(name, filtermapping);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Reverse filter mappings to apply as wrappers last filter wrapped first
|
|
||||||
for (Map.Entry<String, List<FilterMapping>> entry : _filterNameMappings.entrySet())
|
|
||||||
Collections.reverse(entry.getValue());
|
|
||||||
Collections.reverse(_filterPathMappings);
|
|
||||||
_wildFilterNameMappings = _filterNameMappings.get("*");
|
|
||||||
if (_wildFilterNameMappings != null)
|
|
||||||
Collections.reverse(_wildFilterNameMappings);
|
|
||||||
}
|
}
|
||||||
|
// Reverse filter mappings to apply as wrappers last filter wrapped first
|
||||||
|
for (Map.Entry<String, List<FilterMapping>> entry : _filterNameMappings.entrySet())
|
||||||
|
Collections.reverse(entry.getValue());
|
||||||
|
Collections.reverse(_filterPathMappings);
|
||||||
|
_wildFilterNameMappings = _filterNameMappings.get("*");
|
||||||
|
if (_wildFilterNameMappings != null)
|
||||||
|
Collections.reverse(_wildFilterNameMappings);
|
||||||
|
|
||||||
// Map servlet paths to holders
|
// Map servlet paths to holders
|
||||||
if (_servletMappings == null)
|
PathMappings<MappedServlet> pm = new PathMappings<>();
|
||||||
{
|
|
||||||
_servletPathMap = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PathMappings<MappedServlet> pm = new PathMappings<>();
|
|
||||||
|
|
||||||
//create a map of paths to set of ServletMappings that define that mapping
|
//create a map of paths to set of ServletMappings that define that mapping
|
||||||
HashMap<String, List<ServletMapping>> sms = new HashMap<>();
|
HashMap<String, List<ServletMapping>> sms = new HashMap<>();
|
||||||
for (ServletMapping servletMapping : _servletMappings)
|
for (ServletMapping servletMapping : _servletMappings)
|
||||||
|
{
|
||||||
|
String[] pathSpecs = servletMapping.getPathSpecs();
|
||||||
|
if (pathSpecs != null)
|
||||||
{
|
{
|
||||||
String[] pathSpecs = servletMapping.getPathSpecs();
|
for (String pathSpec : pathSpecs)
|
||||||
if (pathSpecs != null)
|
|
||||||
{
|
{
|
||||||
for (String pathSpec : pathSpecs)
|
List<ServletMapping> mappings = sms.computeIfAbsent(pathSpec, k -> new ArrayList<>());
|
||||||
{
|
mappings.add(servletMapping);
|
||||||
List<ServletMapping> mappings = sms.computeIfAbsent(pathSpec, k -> new ArrayList<>());
|
|
||||||
mappings.add(servletMapping);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//evaluate path to servlet map based on servlet mappings
|
//evaluate path to servlet map based on servlet mappings
|
||||||
for (String pathSpec : sms.keySet())
|
for (String pathSpec : sms.keySet())
|
||||||
|
{
|
||||||
|
//for each path, look at the mappings where it is referenced
|
||||||
|
//if a mapping is for a servlet that is not enabled, skip it
|
||||||
|
List<ServletMapping> mappings = sms.get(pathSpec);
|
||||||
|
|
||||||
|
ServletMapping finalMapping = null;
|
||||||
|
for (ServletMapping mapping : mappings)
|
||||||
{
|
{
|
||||||
//for each path, look at the mappings where it is referenced
|
//Get servlet associated with the mapping and check it is enabled
|
||||||
//if a mapping is for a servlet that is not enabled, skip it
|
ServletHolder servletHolder = getServlet(mapping.getServletName());
|
||||||
List<ServletMapping> mappings = sms.get(pathSpec);
|
if (servletHolder == null)
|
||||||
|
throw new IllegalStateException("No such servlet: " + mapping.getServletName());
|
||||||
|
//if the servlet related to the mapping is not enabled, skip it from consideration
|
||||||
|
if (!servletHolder.isEnabled())
|
||||||
|
continue;
|
||||||
|
|
||||||
ServletMapping finalMapping = null;
|
//only accept a default mapping if we don't have any other
|
||||||
for (ServletMapping mapping : mappings)
|
if (finalMapping == null)
|
||||||
|
finalMapping = mapping;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//Get servlet associated with the mapping and check it is enabled
|
//already have a candidate - only accept another one
|
||||||
ServletHolder servletHolder = getServlet(mapping.getServletName());
|
//if the candidate is a default, or we're allowing duplicate mappings
|
||||||
if (servletHolder == null)
|
if (finalMapping.isFromDefaultDescriptor())
|
||||||
throw new IllegalStateException("No such servlet: " + mapping.getServletName());
|
|
||||||
//if the servlet related to the mapping is not enabled, skip it from consideration
|
|
||||||
if (!servletHolder.isEnabled())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//only accept a default mapping if we don't have any other
|
|
||||||
if (finalMapping == null)
|
|
||||||
finalMapping = mapping;
|
finalMapping = mapping;
|
||||||
|
else if (isAllowDuplicateMappings())
|
||||||
|
{
|
||||||
|
LOG.warn("Multiple servlets map to path {}: {} and {}, choosing {}", pathSpec, finalMapping.getServletName(), mapping.getServletName(), mapping);
|
||||||
|
finalMapping = mapping;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//already have a candidate - only accept another one
|
//existing candidate isn't a default, if the one we're looking at isn't a default either, then its an error
|
||||||
//if the candidate is a default, or we're allowing duplicate mappings
|
if (!mapping.isFromDefaultDescriptor())
|
||||||
if (finalMapping.isFromDefaultDescriptor())
|
|
||||||
finalMapping = mapping;
|
|
||||||
else if (isAllowDuplicateMappings())
|
|
||||||
{
|
{
|
||||||
LOG.warn("Multiple servlets map to path {}: {} and {}, choosing {}", pathSpec, finalMapping.getServletName(), mapping.getServletName(), mapping);
|
ServletHolder finalMappedServlet = getServlet(finalMapping.getServletName());
|
||||||
finalMapping = mapping;
|
throw new IllegalStateException("Multiple servlets map to path " +
|
||||||
}
|
pathSpec + ": " +
|
||||||
else
|
finalMappedServlet.getName() + "[mapped:" + finalMapping.getSource() + "]," +
|
||||||
{
|
mapping.getServletName() + "[mapped:" + mapping.getSource() + "]");
|
||||||
//existing candidate isn't a default, if the one we're looking at isn't a default either, then its an error
|
|
||||||
if (!mapping.isFromDefaultDescriptor())
|
|
||||||
{
|
|
||||||
ServletHolder finalMappedServlet = getServlet(finalMapping.getServletName());
|
|
||||||
throw new IllegalStateException("Multiple servlets map to path " +
|
|
||||||
pathSpec + ": " +
|
|
||||||
finalMappedServlet.getName() + "[mapped:" + finalMapping.getSource() + "]," +
|
|
||||||
mapping.getServletName() + "[mapped:" + mapping.getSource() + "]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (finalMapping == null)
|
|
||||||
throw new IllegalStateException("No acceptable servlet mappings for " + pathSpec);
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Path={}[{}] mapped to servlet={}[{}]",
|
|
||||||
pathSpec,
|
|
||||||
finalMapping.getSource(),
|
|
||||||
finalMapping.getServletName(),
|
|
||||||
getServlet(finalMapping.getServletName()).getSource());
|
|
||||||
|
|
||||||
ServletPathSpec servletPathSpec = new ServletPathSpec(pathSpec);
|
|
||||||
MappedServlet mappedServlet = new MappedServlet(servletPathSpec, getServlet(finalMapping.getServletName()));
|
|
||||||
pm.put(servletPathSpec, mappedServlet);
|
|
||||||
}
|
}
|
||||||
|
if (finalMapping == null)
|
||||||
|
throw new IllegalStateException("No acceptable servlet mappings for " + pathSpec);
|
||||||
|
|
||||||
_servletPathMap = pm;
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Path={}[{}] mapped to servlet={}[{}]",
|
||||||
|
pathSpec,
|
||||||
|
finalMapping.getSource(),
|
||||||
|
finalMapping.getServletName(),
|
||||||
|
getServlet(finalMapping.getServletName()).getSource());
|
||||||
|
|
||||||
|
ServletPathSpec servletPathSpec = new ServletPathSpec(pathSpec);
|
||||||
|
MappedServlet mappedServlet = new MappedServlet(servletPathSpec, getServlet(finalMapping.getServletName()));
|
||||||
|
pm.put(servletPathSpec, mappedServlet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_servletPathMap = pm;
|
||||||
|
|
||||||
// flush filter chain cache
|
// flush filter chain cache
|
||||||
for (int i = _chainCache.length; i-- > 0; )
|
for (int i = _chainCache.length; i-- > 0; )
|
||||||
{
|
{
|
||||||
|
@ -1423,33 +1358,17 @@ public class ServletHandler extends ScopedHandler
|
||||||
|
|
||||||
protected boolean containsFilterHolder(FilterHolder holder)
|
protected boolean containsFilterHolder(FilterHolder holder)
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (_filters == null)
|
return _filters.contains(holder);
|
||||||
return false;
|
|
||||||
for (FilterHolder f : _filters)
|
|
||||||
{
|
|
||||||
if (f == holder)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean containsServletHolder(ServletHolder holder)
|
protected boolean containsServletHolder(ServletHolder holder)
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (_servlets == null)
|
return _servlets.contains(holder);
|
||||||
return false;
|
|
||||||
for (ServletHolder s : _servlets)
|
|
||||||
{
|
|
||||||
@SuppressWarnings("ReferenceEquality")
|
|
||||||
boolean foundServletHolder = (s == holder);
|
|
||||||
if (foundServletHolder)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1466,22 +1385,23 @@ public class ServletHandler extends ScopedHandler
|
||||||
*/
|
*/
|
||||||
public void setFilterMappings(FilterMapping[] filterMappings)
|
public void setFilterMappings(FilterMapping[] filterMappings)
|
||||||
{
|
{
|
||||||
updateBeans(_filterMappings, filterMappings);
|
try (AutoLock ignored = lock())
|
||||||
_filterMappings = filterMappings;
|
{
|
||||||
if (isRunning())
|
List<FilterMapping> mappings = filterMappings == null ? Collections.emptyList() : Arrays.asList(filterMappings);
|
||||||
updateMappings();
|
updateAndSet(_filterMappings, mappings);
|
||||||
invalidateChainsCache();
|
if (isRunning())
|
||||||
|
updateMappings();
|
||||||
|
invalidateChainsCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilters(FilterHolder[] holders)
|
public void setFilters(FilterHolder[] holders)
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (holders != null)
|
List<FilterHolder> filters = holders == null ? Collections.emptyList() : Arrays.asList(holders);
|
||||||
initializeHolders(holders);
|
initializeHolders(filters);
|
||||||
|
updateAndSet(_filters, filters);
|
||||||
updateBeans(_filters, holders);
|
|
||||||
_filters = holders;
|
|
||||||
updateNameMappings();
|
updateNameMappings();
|
||||||
invalidateChainsCache();
|
invalidateChainsCache();
|
||||||
}
|
}
|
||||||
|
@ -1492,8 +1412,8 @@ public class ServletHandler extends ScopedHandler
|
||||||
*/
|
*/
|
||||||
public void setServletMappings(ServletMapping[] servletMappings)
|
public void setServletMappings(ServletMapping[] servletMappings)
|
||||||
{
|
{
|
||||||
updateBeans(_servletMappings, servletMappings);
|
List<ServletMapping> mappings = servletMappings == null ? Collections.emptyList() : Arrays.asList(servletMappings);
|
||||||
_servletMappings = servletMappings;
|
updateAndSet(_servletMappings, mappings);
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
updateMappings();
|
updateMappings();
|
||||||
invalidateChainsCache();
|
invalidateChainsCache();
|
||||||
|
@ -1506,12 +1426,11 @@ public class ServletHandler extends ScopedHandler
|
||||||
*/
|
*/
|
||||||
public void setServlets(ServletHolder[] holders)
|
public void setServlets(ServletHolder[] holders)
|
||||||
{
|
{
|
||||||
try (AutoLock l = lock())
|
try (AutoLock ignored = lock())
|
||||||
{
|
{
|
||||||
if (holders != null)
|
List<ServletHolder> servlets = holders == null ? Collections.emptyList() : Arrays.asList(holders);
|
||||||
initializeHolders(holders);
|
initializeHolders(servlets);
|
||||||
updateBeans(_servlets, holders);
|
updateAndSet(_servlets, servlets);
|
||||||
_servlets = holders;
|
|
||||||
updateNameMappings();
|
updateNameMappings();
|
||||||
invalidateChainsCache();
|
invalidateChainsCache();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1448,11 +1448,13 @@ public class DefaultServletTest
|
||||||
Path image = docRoot.resolve("image.jpg");
|
Path image = docRoot.resolve("image.jpg");
|
||||||
createFile(image, "not an image");
|
createFile(image, "not an image");
|
||||||
|
|
||||||
|
server.stop();
|
||||||
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
ServletHolder defholder = context.addServlet(DefaultServlet.class, "/");
|
||||||
defholder.setInitParameter("dirAllowed", "false");
|
defholder.setInitParameter("dirAllowed", "false");
|
||||||
defholder.setInitParameter("redirectWelcome", "false");
|
defholder.setInitParameter("redirectWelcome", "false");
|
||||||
defholder.setInitParameter("welcomeServlets", "false");
|
defholder.setInitParameter("welcomeServlets", "false");
|
||||||
defholder.setInitParameter("gzip", "false");
|
defholder.setInitParameter("gzip", "false");
|
||||||
|
server.start();
|
||||||
|
|
||||||
String rawResponse;
|
String rawResponse;
|
||||||
HttpTester.Response response;
|
HttpTester.Response response;
|
||||||
|
|
|
@ -15,19 +15,23 @@ package org.eclipse.jetty.servlet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.FilterConfig;
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSessionEvent;
|
import javax.servlet.http.HttpSessionEvent;
|
||||||
import javax.servlet.http.HttpSessionListener;
|
import javax.servlet.http.HttpSessionListener;
|
||||||
|
|
||||||
import org.eclipse.jetty.http.pathmap.MappedResource;
|
|
||||||
import org.eclipse.jetty.server.LocalConnector;
|
import org.eclipse.jetty.server.LocalConnector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.util.component.Container;
|
import org.eclipse.jetty.util.component.Container;
|
||||||
|
@ -35,7 +39,9 @@ import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
@ -107,34 +113,33 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddFilterIgnoresDuplicates() throws Exception
|
public void testAddFilterIgnoresDuplicates()
|
||||||
{
|
{
|
||||||
|
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
FilterHolder h = new FilterHolder();
|
FilterHolder h = new FilterHolder();
|
||||||
h.setName("x");
|
h.setName("x");
|
||||||
handler.addFilter(h);
|
handler.addFilter(h);
|
||||||
FilterHolder[] holders = handler.getFilters();
|
FilterHolder[] holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
handler.addFilter(h);
|
handler.addFilter(h);
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 1);
|
assertThat(1, is(holders.length));
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
FilterHolder h2 = new FilterHolder();
|
FilterHolder h2 = new FilterHolder();
|
||||||
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
||||||
handler.addFilter(h2);
|
handler.addFilter(h2);
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 2);
|
assertThat(2, is(holders.length));
|
||||||
assertTrue(holders[1] == h2);
|
assertThat(h2, is(holders[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddFilterIgnoresDuplicates2() throws Exception
|
public void testAddFilterIgnoresDuplicates2()
|
||||||
{
|
{
|
||||||
|
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
|
@ -147,7 +152,7 @@ public class ServletHandlerTest
|
||||||
handler.addFilter(h, m);
|
handler.addFilter(h, m);
|
||||||
FilterHolder[] holders = handler.getFilters();
|
FilterHolder[] holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
FilterMapping m2 = new FilterMapping();
|
FilterMapping m2 = new FilterMapping();
|
||||||
m2.setPathSpec("/*");
|
m2.setPathSpec("/*");
|
||||||
|
@ -155,8 +160,8 @@ public class ServletHandlerTest
|
||||||
handler.addFilter(h, m2);
|
handler.addFilter(h, m2);
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 1);
|
assertThat(1, is(holders.length));
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
FilterHolder h2 = new FilterHolder();
|
FilterHolder h2 = new FilterHolder();
|
||||||
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
||||||
|
@ -167,12 +172,12 @@ public class ServletHandlerTest
|
||||||
handler.addFilter(h2, m3);
|
handler.addFilter(h2, m3);
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 2);
|
assertThat(2, is(holders.length));
|
||||||
assertTrue(holders[1] == h2);
|
assertThat(h2, is(holders[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddFilterWithMappingIgnoresDuplicateFilters() throws Exception
|
public void testAddFilterWithMappingIgnoresDuplicateFilters()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
FilterHolder h = new FilterHolder();
|
FilterHolder h = new FilterHolder();
|
||||||
|
@ -181,13 +186,13 @@ public class ServletHandlerTest
|
||||||
handler.addFilterWithMapping(h, "/*", 0);
|
handler.addFilterWithMapping(h, "/*", 0);
|
||||||
FilterHolder[] holders = handler.getFilters();
|
FilterHolder[] holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
handler.addFilterWithMapping(h, "/*", 1);
|
handler.addFilterWithMapping(h, "/*", 1);
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 1);
|
assertThat(1, is(holders.length));
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
FilterHolder h2 = new FilterHolder();
|
FilterHolder h2 = new FilterHolder();
|
||||||
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
||||||
|
@ -195,12 +200,12 @@ public class ServletHandlerTest
|
||||||
handler.addFilterWithMapping(h2, "/*", 0);
|
handler.addFilterWithMapping(h2, "/*", 0);
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 2);
|
assertThat(2, is(holders.length));
|
||||||
assertTrue(holders[1] == h2);
|
assertThat(h2, is(holders[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddFilterWithMappingIngoresDuplicateFilters2() throws Exception
|
public void testAddFilterWithMappingIngoresDuplicateFilters2()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
FilterHolder h = new FilterHolder();
|
FilterHolder h = new FilterHolder();
|
||||||
|
@ -209,13 +214,13 @@ public class ServletHandlerTest
|
||||||
handler.addFilterWithMapping(h, "/*", EnumSet.allOf(DispatcherType.class));
|
handler.addFilterWithMapping(h, "/*", EnumSet.allOf(DispatcherType.class));
|
||||||
FilterHolder[] holders = handler.getFilters();
|
FilterHolder[] holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
handler.addFilterWithMapping(h, "/x", EnumSet.allOf(DispatcherType.class));
|
handler.addFilterWithMapping(h, "/x", EnumSet.allOf(DispatcherType.class));
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 1);
|
assertThat(1, is(holders.length));
|
||||||
assertTrue(holders[0] == h);
|
assertThat(h, is(holders[0]));
|
||||||
|
|
||||||
FilterHolder h2 = new FilterHolder();
|
FilterHolder h2 = new FilterHolder();
|
||||||
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
h2.setName("x"); //not allowed by servlet spec, just here to test object equality
|
||||||
|
@ -223,12 +228,12 @@ public class ServletHandlerTest
|
||||||
handler.addFilterWithMapping(h2, "/*", EnumSet.allOf(DispatcherType.class));
|
handler.addFilterWithMapping(h2, "/*", EnumSet.allOf(DispatcherType.class));
|
||||||
holders = handler.getFilters();
|
holders = handler.getFilters();
|
||||||
assertNotNull(holders);
|
assertNotNull(holders);
|
||||||
assertTrue(holders.length == 2);
|
assertThat(2, is(holders.length));
|
||||||
assertTrue(holders[1] == h2);
|
assertThat(h2, is(holders[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateMappingsForbidden() throws Exception
|
public void testDuplicateMappingsForbidden()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
handler.setAllowDuplicateMappings(false);
|
handler.setAllowDuplicateMappings(false);
|
||||||
|
@ -250,7 +255,7 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateMappingsWithDefaults() throws Exception
|
public void testDuplicateMappingsWithDefaults()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
handler.setAllowDuplicateMappings(false);
|
handler.setAllowDuplicateMappings(false);
|
||||||
|
@ -269,7 +274,7 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateMappingsSameServlet() throws Exception
|
public void testDuplicateMappingsSameServlet()
|
||||||
{
|
{
|
||||||
ServletHolder sh4 = new ServletHolder();
|
ServletHolder sh4 = new ServletHolder();
|
||||||
|
|
||||||
|
@ -292,7 +297,7 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateMappingsAllowed() throws Exception
|
public void testDuplicateMappingsAllowed()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
handler.setAllowDuplicateMappings(true);
|
handler.setAllowDuplicateMappings(true);
|
||||||
|
@ -310,7 +315,7 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllNonProgrammaticFilterMappings() throws Exception
|
public void testAllNonProgrammaticFilterMappings()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
handler.addFilter(fh1);
|
handler.addFilter(fh1);
|
||||||
|
@ -322,8 +327,8 @@ public class ServletHandlerTest
|
||||||
|
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertTrue(fm1 == mappings[0]);
|
assertThat(mappings[0], is(fm1));
|
||||||
assertTrue(fm2 == mappings[1]);
|
assertThat(mappings[1], is(fm2));
|
||||||
|
|
||||||
//add another ordinary mapping
|
//add another ordinary mapping
|
||||||
FilterHolder of1 = new FilterHolder(new Source(Source.Origin.DESCRIPTOR, "foo.xml"));
|
FilterHolder of1 = new FilterHolder(new Source(Source.Origin.DESCRIPTOR, "foo.xml"));
|
||||||
|
@ -336,13 +341,13 @@ public class ServletHandlerTest
|
||||||
|
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertTrue(fm1 == mappings[0]);
|
assertThat(mappings[0], is(fm1));
|
||||||
assertTrue(fm2 == mappings[1]);
|
assertThat(mappings[1], is(fm2));
|
||||||
assertTrue(ofm1 == mappings[2]);
|
assertThat(mappings[2], is(ofm1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllBeforeFilterMappings() throws Exception
|
public void testAllBeforeFilterMappings()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
|
|
||||||
|
@ -362,12 +367,12 @@ public class ServletHandlerTest
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(2, mappings.length);
|
assertEquals(2, mappings.length);
|
||||||
|
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
assertTrue(fm5 == mappings[1]);
|
assertThat(mappings[1], is(fm5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllAfterFilterMappings() throws Exception
|
public void testAllAfterFilterMappings()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=true)
|
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=true)
|
||||||
|
@ -375,19 +380,19 @@ public class ServletHandlerTest
|
||||||
handler.addFilterMapping(fm4);
|
handler.addFilterMapping(fm4);
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertEquals(1, mappings.length);
|
assertEquals(1, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
|
|
||||||
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=true)
|
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=true)
|
||||||
handler.addFilter(fh5);
|
handler.addFilter(fh5);
|
||||||
handler.addFilterMapping(fm5);
|
handler.addFilterMapping(fm5);
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertEquals(2, mappings.length);
|
assertEquals(2, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
assertTrue(fm5 == mappings[1]);
|
assertThat(mappings[1], is(fm5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatchAfterAndBefore() throws Exception
|
public void testMatchAfterAndBefore()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
|
|
||||||
|
@ -397,7 +402,7 @@ public class ServletHandlerTest
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(1, mappings.length);
|
assertEquals(1, mappings.length);
|
||||||
assertTrue(fm3 == mappings[0]);
|
assertThat(mappings[0], is(fm3));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
handler.addFilter(fh4);
|
handler.addFilter(fh4);
|
||||||
|
@ -405,12 +410,12 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(2, mappings.length);
|
assertEquals(2, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
assertTrue(fm3 == mappings[1]);
|
assertThat(mappings[1], is(fm3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatchBeforeAndAfter() throws Exception
|
public void testMatchBeforeAndAfter()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
|
|
||||||
|
@ -420,7 +425,7 @@ public class ServletHandlerTest
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(1, mappings.length);
|
assertEquals(1, mappings.length);
|
||||||
assertTrue(fm3 == mappings[0]);
|
assertThat(mappings[0], is(fm3));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=true
|
//add a programmatic one, isMatchAfter=true
|
||||||
handler.addFilter(fh4);
|
handler.addFilter(fh4);
|
||||||
|
@ -428,12 +433,12 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(2, mappings.length);
|
assertEquals(2, mappings.length);
|
||||||
assertTrue(fm3 == mappings[0]);
|
assertThat(mappings[0], is(fm3));
|
||||||
assertTrue(fm4 == mappings[1]);
|
assertThat(mappings[1], is(fm4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExistingFilterMappings() throws Exception
|
public void testExistingFilterMappings()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
handler.addFilter(fh1);
|
handler.addFilter(fh1);
|
||||||
|
@ -445,26 +450,26 @@ public class ServletHandlerTest
|
||||||
|
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertTrue(fm1 == mappings[0]);
|
assertThat(mappings[0], is(fm1));
|
||||||
assertTrue(fm2 == mappings[1]);
|
assertThat(mappings[1], is(fm2));
|
||||||
|
|
||||||
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=false)
|
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=false)
|
||||||
handler.addFilter(fh4);
|
handler.addFilter(fh4);
|
||||||
handler.prependFilterMapping(fm4);
|
handler.prependFilterMapping(fm4);
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertEquals(3, mappings.length);
|
assertEquals(3, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
|
|
||||||
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=true)
|
//do equivalent of FilterRegistration.addMappingForUrlPatterns(isMatchAfter=true)
|
||||||
handler.addFilter(fh5);
|
handler.addFilter(fh5);
|
||||||
handler.addFilterMapping(fm5);
|
handler.addFilterMapping(fm5);
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertEquals(4, mappings.length);
|
assertEquals(4, mappings.length);
|
||||||
assertTrue(fm5 == mappings[mappings.length - 1]);
|
assertThat(mappings[mappings.length - 1], is(fm5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFilterMappingNoFilter() throws Exception
|
public void testFilterMappingNoFilter()
|
||||||
{
|
{
|
||||||
FilterMapping mapping = new FilterMapping();
|
FilterMapping mapping = new FilterMapping();
|
||||||
mapping.setPathSpec("/*");
|
mapping.setPathSpec("/*");
|
||||||
|
@ -474,7 +479,7 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFilterMappingsMix() throws Exception
|
public void testFilterMappingsMix()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
|
|
||||||
|
@ -483,7 +488,7 @@ public class ServletHandlerTest
|
||||||
handler.addFilterMapping(fm1);
|
handler.addFilterMapping(fm1);
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertTrue(fm1 == mappings[0]);
|
assertThat(mappings[0], is(fm1));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
handler.addFilter(fh4);
|
handler.addFilter(fh4);
|
||||||
|
@ -491,8 +496,8 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(2, mappings.length);
|
assertEquals(2, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
assertTrue(fm1 == mappings[1]);
|
assertThat(mappings[1], is(fm1));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=true
|
//add a programmatic one, isMatchAfter=true
|
||||||
handler.addFilter(fh3);
|
handler.addFilter(fh3);
|
||||||
|
@ -500,9 +505,9 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(3, mappings.length);
|
assertEquals(3, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]);
|
assertThat(mappings[0], is(fm4));
|
||||||
assertTrue(fm1 == mappings[1]);
|
assertThat(mappings[1], is(fm1));
|
||||||
assertTrue(fm3 == mappings[2]);
|
assertThat(mappings[2], is(fm3));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
handler.addFilter(fh5);
|
handler.addFilter(fh5);
|
||||||
|
@ -510,10 +515,10 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(4, mappings.length);
|
assertEquals(4, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]); //isMatchAfter = false;
|
assertThat(mappings[0], is(fm4)); //isMatchAfter = false;
|
||||||
assertTrue(fm5 == mappings[1]); //isMatchAfter = false;
|
assertThat(mappings[1], is(fm5)); //isMatchAfter = false;
|
||||||
assertTrue(fm1 == mappings[2]); //ordinary
|
assertThat(mappings[2], is(fm1)); //ordinary
|
||||||
assertTrue(fm3 == mappings[3]); //isMatchAfter = true;
|
assertThat(mappings[3], is(fm3)); //isMatchAfter = true;
|
||||||
|
|
||||||
//add a non-programmatic one
|
//add a non-programmatic one
|
||||||
FilterHolder f = new FilterHolder(Source.EMBEDDED);
|
FilterHolder f = new FilterHolder(Source.EMBEDDED);
|
||||||
|
@ -526,11 +531,11 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(5, mappings.length);
|
assertEquals(5, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]); //isMatchAfter = false;
|
assertThat(mappings[0], is(fm4)); //isMatchAfter = false;
|
||||||
assertTrue(fm5 == mappings[1]); //isMatchAfter = false;
|
assertThat(mappings[1], is(fm5)); //isMatchAfter = false;
|
||||||
assertTrue(fm1 == mappings[2]); //ordinary
|
assertThat(mappings[2], is(fm1)); //ordinary
|
||||||
assertTrue(fm == mappings[3]); //ordinary
|
assertThat(mappings[3], is(fm)); //ordinary
|
||||||
assertTrue(fm3 == mappings[4]); //isMatchAfter = true;
|
assertThat(mappings[4], is(fm3)); //isMatchAfter = true;
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=true
|
//add a programmatic one, isMatchAfter=true
|
||||||
FilterHolder pf = new FilterHolder(Source.JAVAX_API);
|
FilterHolder pf = new FilterHolder(Source.JAVAX_API);
|
||||||
|
@ -543,12 +548,12 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(6, mappings.length);
|
assertEquals(6, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]); //isMatchAfter = false;
|
assertThat(mappings[0], is(fm4)); //isMatchAfter = false;
|
||||||
assertTrue(fm5 == mappings[1]); //isMatchAfter = false;
|
assertThat(mappings[1], is(fm5)); //isMatchAfter = false;
|
||||||
assertTrue(fm1 == mappings[2]); //ordinary
|
assertThat(mappings[2], is(fm1)); //ordinary
|
||||||
assertTrue(fm == mappings[3]); //ordinary
|
assertThat(mappings[3], is(fm)); //ordinary
|
||||||
assertTrue(fm3 == mappings[4]); //isMatchAfter = true;
|
assertThat(mappings[4], is(fm3)); //isMatchAfter = true;
|
||||||
assertTrue(pfm == mappings[5]); //isMatchAfter = true;
|
assertThat(mappings[5], is(pfm)); //isMatchAfter = true;
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
FilterHolder pf2 = new FilterHolder(Source.JAVAX_API);
|
FilterHolder pf2 = new FilterHolder(Source.JAVAX_API);
|
||||||
|
@ -561,17 +566,17 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(7, mappings.length);
|
assertEquals(7, mappings.length);
|
||||||
assertTrue(fm4 == mappings[0]); //isMatchAfter = false;
|
assertThat(mappings[0], is(fm4)); //isMatchAfter = false;
|
||||||
assertTrue(fm5 == mappings[1]); //isMatchAfter = false;
|
assertThat(mappings[1], is(fm5)); //isMatchAfter = false;
|
||||||
assertTrue(pfm2 == mappings[2]); //isMatchAfter = false;
|
assertThat(mappings[2], is(pfm2)); //isMatchAfter = false;
|
||||||
assertTrue(fm1 == mappings[3]); //ordinary
|
assertThat(mappings[3], is(fm1)); //ordinary
|
||||||
assertTrue(fm == mappings[4]); //ordinary
|
assertThat(mappings[4], is(fm)); //ordinary
|
||||||
assertTrue(fm3 == mappings[5]); //isMatchAfter = true;
|
assertThat(mappings[5], is(fm3)); //isMatchAfter = true;
|
||||||
assertTrue(pfm == mappings[6]); //isMatchAfter = true;
|
assertThat(mappings[6], is(pfm)); //isMatchAfter = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddFilterWithMappingAPI() throws Exception
|
public void testAddFilterWithMappingAPI()
|
||||||
{
|
{
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
|
|
||||||
|
@ -580,7 +585,7 @@ public class ServletHandlerTest
|
||||||
handler.updateMappings();
|
handler.updateMappings();
|
||||||
FilterMapping[] mappings = handler.getFilterMappings();
|
FilterMapping[] mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertTrue(fh1 == mappings[0].getFilterHolder());
|
assertThat(mappings[0].getFilterHolder(), is(fh1));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
fh4.setServletHandler(handler);
|
fh4.setServletHandler(handler);
|
||||||
|
@ -590,8 +595,8 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(2, mappings.length);
|
assertEquals(2, mappings.length);
|
||||||
assertTrue(fh4 == mappings[0].getFilterHolder());
|
assertThat(mappings[0].getFilterHolder(), is(fh4));
|
||||||
assertTrue(fh1 == mappings[1].getFilterHolder());
|
assertThat(mappings[1].getFilterHolder(), is(fh1));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=true
|
//add a programmatic one, isMatchAfter=true
|
||||||
fh3.setServletHandler(handler);
|
fh3.setServletHandler(handler);
|
||||||
|
@ -601,9 +606,9 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(3, mappings.length);
|
assertEquals(3, mappings.length);
|
||||||
assertTrue(fh4 == mappings[0].getFilterHolder());
|
assertThat(mappings[0].getFilterHolder(), is(fh4));
|
||||||
assertTrue(fh1 == mappings[1].getFilterHolder());
|
assertThat(mappings[1].getFilterHolder(), is(fh1));
|
||||||
assertTrue(fh3 == mappings[2].getFilterHolder());
|
assertThat(mappings[2].getFilterHolder(), is(fh3));
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
fh5.setServletHandler(handler);
|
fh5.setServletHandler(handler);
|
||||||
|
@ -613,10 +618,10 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(4, mappings.length);
|
assertEquals(4, mappings.length);
|
||||||
assertTrue(fh4 == mappings[0].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[0].getFilterHolder(), is(fh4)); //isMatchAfter = false;
|
||||||
assertTrue(fh5 == mappings[1].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[1].getFilterHolder(), is(fh5)); //isMatchAfter = false;
|
||||||
assertTrue(fh1 == mappings[2].getFilterHolder()); //ordinary
|
assertThat(mappings[2].getFilterHolder(), is(fh1)); //ordinary
|
||||||
assertTrue(fh3 == mappings[3].getFilterHolder()); //isMatchAfter = true;
|
assertThat(mappings[3].getFilterHolder(), is(fh3)); //isMatchAfter = true;
|
||||||
|
|
||||||
//add a non-programmatic one
|
//add a non-programmatic one
|
||||||
FilterHolder f = new FilterHolder(Source.EMBEDDED);
|
FilterHolder f = new FilterHolder(Source.EMBEDDED);
|
||||||
|
@ -626,11 +631,11 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(5, mappings.length);
|
assertEquals(5, mappings.length);
|
||||||
assertTrue(fh4 == mappings[0].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[0].getFilterHolder(), is(fh4)); //isMatchAfter = false;
|
||||||
assertTrue(fh5 == mappings[1].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[1].getFilterHolder(), is(fh5)); //isMatchAfter = false;
|
||||||
assertTrue(fh1 == mappings[2].getFilterHolder()); //ordinary
|
assertThat(mappings[2].getFilterHolder(), is(fh1)); //ordinary
|
||||||
assertTrue(f == mappings[3].getFilterHolder()); //ordinary
|
assertThat(mappings[3].getFilterHolder(), is(f)); //ordinary
|
||||||
assertTrue(fh3 == mappings[4].getFilterHolder()); //isMatchAfter = true;
|
assertThat(mappings[4].getFilterHolder(), is(fh3)); //isMatchAfter = true;
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=true
|
//add a programmatic one, isMatchAfter=true
|
||||||
FilterHolder pf = new FilterHolder(Source.JAVAX_API);
|
FilterHolder pf = new FilterHolder(Source.JAVAX_API);
|
||||||
|
@ -642,12 +647,12 @@ public class ServletHandlerTest
|
||||||
mappings = handler.getFilterMappings();
|
mappings = handler.getFilterMappings();
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(6, mappings.length);
|
assertEquals(6, mappings.length);
|
||||||
assertTrue(fh4 == mappings[0].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[0].getFilterHolder(), is(fh4)); //isMatchAfter = false;
|
||||||
assertTrue(fh5 == mappings[1].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[1].getFilterHolder(), is(fh5)); //isMatchAfter = false;
|
||||||
assertTrue(fh1 == mappings[2].getFilterHolder()); //ordinary
|
assertThat(mappings[2].getFilterHolder(), is(fh1)); //ordinary
|
||||||
assertTrue(f == mappings[3].getFilterHolder()); //ordinary
|
assertThat(mappings[3].getFilterHolder(), is(f)); //ordinary
|
||||||
assertTrue(fh3 == mappings[4].getFilterHolder()); //isMatchAfter = true;
|
assertThat(mappings[4].getFilterHolder(), is(fh3)); //isMatchAfter = true;
|
||||||
assertTrue(pf == mappings[5].getFilterHolder()); //isMatchAfter = true;
|
assertThat(mappings[5].getFilterHolder(), is(pf)); //isMatchAfter = true;
|
||||||
|
|
||||||
//add a programmatic one, isMatchAfter=false
|
//add a programmatic one, isMatchAfter=false
|
||||||
FilterHolder pf2 = new FilterHolder(Source.JAVAX_API);
|
FilterHolder pf2 = new FilterHolder(Source.JAVAX_API);
|
||||||
|
@ -660,17 +665,17 @@ public class ServletHandlerTest
|
||||||
|
|
||||||
assertNotNull(mappings);
|
assertNotNull(mappings);
|
||||||
assertEquals(7, mappings.length);
|
assertEquals(7, mappings.length);
|
||||||
assertTrue(fh4 == mappings[0].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[0].getFilterHolder(), is(fh4)); //isMatchAfter = false;
|
||||||
assertTrue(fh5 == mappings[1].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[1].getFilterHolder(), is(fh5)); //isMatchAfter = false;
|
||||||
assertTrue(pf2 == mappings[2].getFilterHolder()); //isMatchAfter = false;
|
assertThat(mappings[2].getFilterHolder(), is(pf2)); //isMatchAfter = false;
|
||||||
assertTrue(fh1 == mappings[3].getFilterHolder()); //ordinary
|
assertThat(mappings[3].getFilterHolder(), is(fh1)); //ordinary
|
||||||
assertTrue(f == mappings[4].getFilterHolder()); //ordinary
|
assertThat(mappings[4].getFilterHolder(), is(f)); //ordinary
|
||||||
assertTrue(fh3 == mappings[5].getFilterHolder()); //isMatchAfter = true;
|
assertThat(mappings[5].getFilterHolder(), is(fh3)); //isMatchAfter = true;
|
||||||
assertTrue(pf == mappings[6].getFilterHolder()); //isMatchAfter = true;
|
assertThat(mappings[6].getFilterHolder(), is(pf)); //isMatchAfter = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFiltersServletsListenersAsBeans() throws Exception
|
public void testFiltersServletsListenersAsBeans()
|
||||||
{
|
{
|
||||||
ServletContextHandler context = new ServletContextHandler();
|
ServletContextHandler context = new ServletContextHandler();
|
||||||
|
|
||||||
|
@ -747,7 +752,7 @@ public class ServletHandlerTest
|
||||||
handler.addServletWithMapping(new ServletHolder(new HttpServlet()
|
handler.addServletWithMapping(new ServletHolder(new HttpServlet()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
|
||||||
{
|
{
|
||||||
resp.getOutputStream().println("mapping='" + mapping + "'");
|
resp.getOutputStream().println("mapping='" + mapping + "'");
|
||||||
}
|
}
|
||||||
|
@ -779,7 +784,7 @@ public class ServletHandlerTest
|
||||||
ServletHolder foo = new ServletHolder(new HttpServlet()
|
ServletHolder foo = new ServletHolder(new HttpServlet()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
|
||||||
{
|
{
|
||||||
resp.getOutputStream().println("FOO");
|
resp.getOutputStream().println("FOO");
|
||||||
}
|
}
|
||||||
|
@ -790,7 +795,7 @@ public class ServletHandlerTest
|
||||||
ServletHolder def = new ServletHolder(new HttpServlet()
|
ServletHolder def = new ServletHolder(new HttpServlet()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
|
||||||
{
|
{
|
||||||
resp.getOutputStream().println("default");
|
resp.getOutputStream().println("default");
|
||||||
}
|
}
|
||||||
|
@ -830,6 +835,67 @@ public class ServletHandlerTest
|
||||||
assertThat(connector.getResponse("GET /other.bob HTTP/1.0\r\n\r\n"), containsString("path-/*-path-*.bob-default"));
|
assertThat(connector.getResponse("GET /other.bob HTTP/1.0\r\n\r\n"), containsString("path-/*-path-*.bob-default"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDurable() throws Exception
|
||||||
|
{
|
||||||
|
Server server = new Server();
|
||||||
|
ServletContextHandler context = new ServletContextHandler();
|
||||||
|
server.setHandler(context);
|
||||||
|
ServletHandler handler = new ServletHandler();
|
||||||
|
context.setHandler(handler);
|
||||||
|
ListenerHolder lh1 = new ListenerHolder(HSListener.class);
|
||||||
|
ListenerHolder lh2 = new ListenerHolder(SCListener.class);
|
||||||
|
|
||||||
|
fh1.setFilter(new SomeFilter());
|
||||||
|
fm1.setPathSpec("/sm1");
|
||||||
|
fm1.setFilterHolder(fh1);
|
||||||
|
fh2.setFilter(new SomeFilter(){});
|
||||||
|
fm2.setPathSpec("/sm2");
|
||||||
|
fm2.setFilterHolder(fh2);
|
||||||
|
sh1.setServlet(new SomeServlet());
|
||||||
|
sm1.setPathSpec("/sm1");
|
||||||
|
sm1.setServletName(sh1.getName());
|
||||||
|
sh2.setServlet(new SomeServlet());
|
||||||
|
sm2.setPathSpec("/sm2");
|
||||||
|
sm2.setServletName(sh2.getName());
|
||||||
|
|
||||||
|
handler.setListeners(new ListenerHolder[] {lh1});
|
||||||
|
handler.setFilters(new FilterHolder[] {fh1});
|
||||||
|
handler.setFilterMappings(new FilterMapping[] {fm1});
|
||||||
|
handler.setServlets(new ServletHolder[] {sh1});
|
||||||
|
handler.setServletMappings(new ServletMapping[] {sm1});
|
||||||
|
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
handler.setListeners(new ListenerHolder[] {lh1, lh2});
|
||||||
|
handler.setFilters(new FilterHolder[] {fh1, fh2});
|
||||||
|
handler.setFilterMappings(new FilterMapping[] {fm1, fm2});
|
||||||
|
handler.setServlets(new ServletHolder[] {sh1, sh2});
|
||||||
|
handler.setServletMappings(new ServletMapping[] {sm1, sm2});
|
||||||
|
|
||||||
|
assertThat(Arrays.asList(handler.getListeners()), contains(lh1, lh2));
|
||||||
|
assertThat(Arrays.asList(handler.getFilters()), contains(fh1, fh2));
|
||||||
|
assertThat(Arrays.asList(handler.getFilterMappings()), contains(fm1, fm2));
|
||||||
|
assertThat(Arrays.asList(handler.getServlets()), contains(sh1, sh2));
|
||||||
|
assertThat(Arrays.asList(handler.getServletMappings()), contains(sm1, sm2));
|
||||||
|
|
||||||
|
server.stop();
|
||||||
|
|
||||||
|
assertThat(Arrays.asList(handler.getListeners()), contains(lh1));
|
||||||
|
assertThat(Arrays.asList(handler.getFilters()), contains(fh1));
|
||||||
|
assertThat(Arrays.asList(handler.getFilterMappings()), contains(fm1));
|
||||||
|
assertThat(Arrays.asList(handler.getServlets()), contains(sh1));
|
||||||
|
assertThat(Arrays.asList(handler.getServletMappings()), contains(sm1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HSListener implements HttpSessionListener
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SCListener implements ServletContextListener
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private interface TestFilter extends Filter
|
private interface TestFilter extends Filter
|
||||||
{
|
{
|
||||||
default void init(FilterConfig filterConfig) throws ServletException
|
default void init(FilterConfig filterConfig) throws ServletException
|
||||||
|
@ -842,4 +908,17 @@ public class ServletHandlerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SomeFilter implements TestFilter
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||||
|
{
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SomeServlet extends HttpServlet
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,13 @@ package org.eclipse.jetty.util.component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
@ -489,12 +491,13 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
||||||
if (super.removeEventListener(listener))
|
if (super.removeEventListener(listener))
|
||||||
{
|
{
|
||||||
removeBean(listener);
|
removeBean(listener);
|
||||||
if (_listeners.remove(listener))
|
if (listener instanceof Container.Listener && _listeners.remove(listener))
|
||||||
{
|
{
|
||||||
|
Container.Listener cl = (Container.Listener)listener;
|
||||||
// remove existing beans
|
// remove existing beans
|
||||||
for (Bean b : _beans)
|
for (Bean b : _beans)
|
||||||
{
|
{
|
||||||
((Container.Listener)listener).beanRemoved(this, b._bean);
|
cl.beanRemoved(this, b._bean);
|
||||||
|
|
||||||
if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)
|
if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)
|
||||||
((Container)b._bean).removeBean(listener);
|
((Container)b._bean).removeBean(listener);
|
||||||
|
@ -813,40 +816,28 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
||||||
|
|
||||||
public void updateBeans(Object[] oldBeans, final Object[] newBeans)
|
public void updateBeans(Object[] oldBeans, final Object[] newBeans)
|
||||||
{
|
{
|
||||||
|
updateBeans(
|
||||||
|
oldBeans == null ? Collections.emptyList() : Arrays.asList(oldBeans),
|
||||||
|
newBeans == null ? Collections.emptyList() : Arrays.asList(newBeans));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateBeans(final Collection<?> oldBeans, final Collection<?> newBeans)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(oldBeans);
|
||||||
|
Objects.requireNonNull(newBeans);
|
||||||
|
|
||||||
// remove oldChildren not in newChildren
|
// remove oldChildren not in newChildren
|
||||||
if (oldBeans != null)
|
for (Object o : oldBeans)
|
||||||
{
|
{
|
||||||
loop:
|
if (!newBeans.contains(o))
|
||||||
for (Object o : oldBeans)
|
|
||||||
{
|
|
||||||
if (newBeans != null)
|
|
||||||
{
|
|
||||||
for (Object n : newBeans)
|
|
||||||
{
|
|
||||||
if (o == n)
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
removeBean(o);
|
removeBean(o);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add new beans not in old
|
// add new beans not in old
|
||||||
if (newBeans != null)
|
for (Object n : newBeans)
|
||||||
{
|
{
|
||||||
loop:
|
if (!oldBeans.contains(n))
|
||||||
for (Object n : newBeans)
|
|
||||||
{
|
|
||||||
if (oldBeans != null)
|
|
||||||
{
|
|
||||||
for (Object o : oldBeans)
|
|
||||||
{
|
|
||||||
if (o == n)
|
|
||||||
continue loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addBean(n);
|
addBean(n);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,11 @@ public class DumpableCollection implements Dumpable
|
||||||
return new DumpableCollection(name, items == null ? Collections.emptyList() : Arrays.asList(items));
|
return new DumpableCollection(name, items == null ? Collections.emptyList() : Arrays.asList(items));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DumpableCollection from(String name, Collection<?> collection)
|
||||||
|
{
|
||||||
|
return new DumpableCollection(name, collection);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String dump()
|
public String dump()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue