Commit 626417c6 authored by daryl herzmann's avatar daryl herzmann Committed by GitHub

Merge pull request #685 from guusdk/OF-1227_Plugin-servlet-filter

OF-1227: Plugins should be able to have proper servlet filters.
parents 61a34e5d e828c22f
......@@ -20,63 +20,213 @@
package org.jivesoftware.admin;
import org.apache.mina.util.CopyOnWriteMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* A servlet filter that plugin classes can use to dynamically register and un-register
* filter logic. The filter logic that each plugin can register is fairly limited;
* instead of having full control over the filter chain, each instance of
* {@link SimpleFilter} only has the ability to use the ServletRequest and ServletResponse
* objects and then return <tt>true</tt> if further filters in the chain should be run.
* A servlet filter that plugin classes can use to dynamically register and un-register filter logic.
*
* The original, now deprecated, filter logic that each plugin can register was fairly limited; instead of having full
* control over the filter chain, each instance of {@link SimpleFilter} only has the ability to use the ServletRequest
* and ServletResponse objects and then return <tt>true</tt> if further filters in the chain should be run.
*
* The new, non-deprecated functionality allows for regular {@link Filter} instances to be registered with this class,
* which removes much of the limitations that was present in the SimpleFilter approach.
*
* This implementation assumes, but does not enforce, that filters installed by plugins are applied to URL patterns that
* match the plugin. When filters installed by different plugins are applied to the same URL, the behavior of this
* implementation is undetermined.
*
* @author Matt Tucker
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class PluginFilter implements Filter {
private static final Logger Log = LoggerFactory.getLogger( PluginFilter.class );
@Deprecated
private static List<SimpleFilter> pluginFilters = new CopyOnWriteArrayList<>();
private static Map<String, List<Filter>> filters = new CopyOnWriteMap<>();
/**
* Adds a filter to the list of filters that will be run on every request.
* This method should be called by plugins when starting up.
*
* @param filter the filter.
* @deprecated Replaced by {@link #addPluginFilter(String, Filter)}
*/
@Deprecated
public static void addPluginFilter(SimpleFilter filter) {
pluginFilters.add(filter);
}
/**
* Adds a filter to the list of filters that will be run on every request of which the URL matches the URL that
* is registered with this filter. More specifically, the request URL should be equal to, or start with, the filter
* URL.
*
* Multiple filters can be registered on the same URL, in which case they will be executed in the order in which
* they were added.
*
* Adding a filter does not initialize the plugin instance.
*
* @param filterUrl The URL pattern to which the filter is to be applied. Cannot be null nor an empty string.
* @param filter The filter. Cannot be null.
*/
public static void addPluginFilter( String filterUrl, Filter filter )
{
if ( filterUrl == null || filterUrl.isEmpty() || filter == null )
{
throw new IllegalArgumentException();
}
if ( !filters.containsKey( filterUrl ) )
{
filters.put( filterUrl, new ArrayList<Filter>() );
}
final List<Filter> urlFilters = PluginFilter.filters.get( filterUrl );
if ( urlFilters.contains( filter ) )
{
Log.warn( "Cannot add filter '{}' as it was already added for URL '{}'!", filter, filterUrl );
}
else
{
urlFilters.add( filter );
Log.debug( "Added filter '{}' for URL '{}'", filter, filterUrl );
}
}
/**
* Removes a filter from the list of filters that will be run on every request.
* This method should be called by plugins when shutting down.
*
* @param filter the filter.
* @deprecated
*/
@Deprecated
public static void removePluginFilter(SimpleFilter filter) {
pluginFilters.remove(filter);
}
/**
* Removes a filter that is applied to a certain URL.
*
* Removing a filter does not destroy the plugin instance.
*
* @param filterUrl The URL pattern to which the filter is applied. Cannot be null nor an empty string.
* @param filterClassName The filter class name. Cannot be null or empty string.
* @return The filter instance that was removed, or null if the URL and name combination did not match a filter.
*/
public static Filter removePluginFilter( String filterUrl, String filterClassName )
{
if ( filterUrl == null || filterUrl.isEmpty() || filterClassName == null || filterClassName.isEmpty() )
{
throw new IllegalArgumentException();
}
Filter result = null;
if ( filters.containsKey( filterUrl ) )
{
final List<Filter> urlFilters = PluginFilter.filters.get( filterUrl );
final Iterator<Filter> iterator = urlFilters.iterator();
while ( iterator.hasNext() )
{
final Filter filter = iterator.next();
if ( filter.getClass().getName().equals( filterClassName ) )
{
iterator.remove();
result = filter; // assumed to be unique, but check the entire collection to avoid leaks.
}
}
if ( urlFilters.isEmpty() )
{
filters.remove( filterUrl );
}
}
if ( result == null )
{
Log.warn( "Unable to removed filter of class '{}' for URL '{}'. No such filter is present.", filterClassName, filterUrl );
}
else
{
Log.debug( "Removed filter '{}' for URL '{}'", result, filterUrl );
}
return result;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* This class is a Filter implementation itself. It acts as a dynamic proxy to filters that are registered by
* Openfire plugins.
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException
{
boolean continueChain = true;
// Process each plugin filter.
for (SimpleFilter filter : pluginFilters) {
// Process each of the (deprecated) SimplePlugin filters.
for ( SimpleFilter filter : pluginFilters ) {
Log.trace( "(deprecated) Executing wrapped simple filter '{}'...", filter );
if (!filter.doFilter(servletRequest, servletResponse)) {
// The filter returned false so no further filters in the
// chain should be run.
Log.debug( "The simple filter returned false so no further filters in the chain should be run." );
continueChain = false;
break;
}
}
if (continueChain) {
// Process the 'regular' servlet filters.
if ( continueChain )
{
if ( servletRequest instanceof HttpServletRequest )
{
final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
final String requestPath = ( httpServletRequest.getContextPath() + httpServletRequest.getServletPath() + httpServletRequest.getPathInfo() ).toLowerCase();
final List<Filter> applicableFilters = new ArrayList<>();
for ( final Map.Entry<String, List<Filter>> entry : filters.entrySet() )
{
String filterUrl = entry.getKey();
if ( filterUrl.endsWith( "*" ))
{
filterUrl = filterUrl.substring( 0, filterUrl.length() -1 );
}
filterUrl = filterUrl.toLowerCase();
if ( requestPath.startsWith( filterUrl ) )
{
for ( final Filter filter : entry.getValue() )
{
applicableFilters.add( filter );
}
}
}
if ( !applicableFilters.isEmpty() )
{
Log.debug( "Wrapping filter chain in order to run plugin-specific filters." );
filterChain = new FilterChainInjector( filterChain, applicableFilters );
}
}
else
{
Log.warn( "ServletRequest is not an instance of an HttpServletRequest." );
}
// Plugin filtering is done. Progress down the filter chain that was initially provided.
filterChain.doFilter(servletRequest, servletResponse);
}
}
......@@ -86,13 +236,17 @@ public class PluginFilter implements Filter {
// If the destroy method is being called, the Openfire instance is being shutdown.
// Therefore, clear out the list of plugin filters.
pluginFilters.clear();
filters.clear();
}
/**
* A simplified version of a servlet filter. Instead of having full control
* over the filter chain, a simple filter can only control whether further
* filters in the chain are run.
*
* @Deprecated Use {@link Filter} instead.
*/
@Deprecated
public interface SimpleFilter {
/**
......@@ -117,4 +271,53 @@ public class PluginFilter implements Filter {
throws IOException, ServletException;
}
/**
* A wrapper that can be used to inject a list of filters into an existing a filter chain.
*
* An instance of this class is expected to be created within the execution of a 'parent' filter chain. After
* instantiation, the caller is expected to invoke #doFilter once, after which all provided filters will be
* invoked. Afterwards, the original filter chain (as supplied in the constructor) will be resumed.
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
private static class FilterChainInjector implements FilterChain
{
private static final Logger Log = LoggerFactory.getLogger( FilterChainInjector.class );
private final FilterChain parentChain;
private final List<Filter> filters;
private int index = 0;
/**
* Creates a new instance.
*
* @param parentChain the chain to which the filters are to be appended (cannot be null).
* @param filters The filters to append (cannot be null, but can be empty).
*/
private FilterChainInjector( FilterChain parentChain, List<Filter> filters )
{
if ( parentChain == null || filters == null )
{
throw new IllegalArgumentException();
}
this.parentChain = parentChain;
this.filters = filters;
}
@Override
public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse ) throws IOException, ServletException
{
if ( index < filters.size() )
{
Log.trace( "Executing injected filter {} of {}...", index + 1, filters.size() );
filters.get( index++ ).doFilter( servletRequest, servletResponse, this );
}
else
{
Log.trace( "Executed all injected filters. Resuming original chain." );
parentChain.doFilter( servletRequest, servletResponse );
}
}
}
}
\ No newline at end of file
......@@ -29,6 +29,7 @@ import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.jivesoftware.openfire.XMPPServer;
import org.slf4j.Logger;
......
......@@ -25,26 +25,22 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspC;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.jivesoftware.admin.PluginFilter;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.WebXmlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
......@@ -132,62 +128,125 @@ public class PluginServlet extends HttpServlet {
* @param webXML the web.xml file containing JSP page names to servlet class file
* mappings.
*/
public static void registerServlets(PluginManager manager, Plugin plugin, File webXML) {
public static void registerServlets( PluginManager manager, final Plugin plugin, File webXML)
{
pluginManager = manager;
if (!webXML.exists()) {
Log.error("Could not register plugin servlets, file " + webXML.getAbsolutePath() +
" does not exist.");
if ( !webXML.exists() )
{
Log.error("Could not register plugin servlets, file " + webXML.getAbsolutePath() + " does not exist.");
return;
}
// Find the name of the plugin directory given that the webXML file
// lives in plugins/[pluginName]/web/web.xml
String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName();
try {
// Make the reader non-validating so that it doesn't try to resolve external
// DTD's. Trying to resolve external DTD's can break on some firewall configurations.
SAXReader saxReader = new SAXReader(false);
try {
saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
}
catch (SAXException e) {
Log.warn("Error setting SAXReader feature", e);
}
Document doc = saxReader.read(webXML);
// Find all <servlet> entries to discover name to class mapping.
List classes = doc.getRootElement().elements("servlet");
Map<String, Class> classMap = new HashMap<>();
for (int i = 0; i < classes.size(); i++) {
Element servletElement = (Element)classes.get(i);
String name = servletElement.element("servlet-name").getTextTrim();
String className = servletElement.element("servlet-class").getTextTrim();
classMap.put(name, manager.loadClass(plugin, className));
}
// Find all <servelt-mapping> entries to discover name to URL mapping.
List names = doc.getRootElement().elements("servlet-mapping");
for (int i = 0; i < names.size(); i++) {
Element nameElement = (Element)names.get(i);
String name = nameElement.element("servlet-name").getTextTrim();
String url = nameElement.element("url-pattern").getTextTrim();
// Register the servlet for the URL.
Class servletClass = classMap.get(name);
if(servletClass == null) {
Log.error("Unable to load servlet, " + name + ", servlet-class not found.");
// Find the name of the plugin directory given that the webXML file lives in plugins/[pluginName]/web/web.xml
final String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName();
try
{
final Document webXmlDoc = WebXmlUtils.asDocument( webXML );
final List<String> servletNames = WebXmlUtils.getServletNames( webXmlDoc );
for ( final String servletName : servletNames )
{
Log.debug( "Loading servlet '{}' of plugin '{}'...", servletName, pluginName );
final String className = WebXmlUtils.getServletClassName( webXmlDoc, servletName );
if ( className == null || className.isEmpty() )
{
Log.warn( "Could not load servlet '{}' of plugin '{}'. web-xml does not define a class name for this servlet.", servletName, pluginName );
continue;
}
final Class theClass = manager.loadClass( plugin, className );
final Object instance = theClass.newInstance();
if ( !(instance instanceof GenericServlet) )
{
Log.warn( "Could not load servlet '{}' of plugin '{}'. Its class ({}) is not an instance of javax.servlet.GenericServlet.", servletName, pluginName, className );
continue;
}
Object instance = servletClass.newInstance();
if (instance instanceof GenericServlet) {
// Initialize the servlet then add it to the map..
((GenericServlet)instance).init(servletConfig);
servlets.put((pluginName + url).toLowerCase(), (GenericServlet)instance);
Log.debug( "Initializing servlet '{}' of plugin '{}'...", servletName, pluginName );
( (GenericServlet) instance ).init( servletConfig );
Log.debug( "Registering servlet '{}' of plugin '{}' URL patterns.", servletName, pluginName );
final Set<String> urlPatterns = WebXmlUtils.getServletUrlPatterns( webXmlDoc, servletName );
for ( final String urlPattern : urlPatterns )
{
servlets.put( ( pluginName + urlPattern ).toLowerCase(), (GenericServlet) instance );
}
else {
Log.warn("Could not load " + (pluginName + url) + ": not a servlet.");
Log.debug( "Servlet '{}' of plugin '{}' loaded successfully.", servletName, pluginName );
}
final List<String> filterNames = WebXmlUtils.getFilterNames( webXmlDoc );
for ( final String filterName : filterNames )
{
Log.debug( "Loading filter '{}' of plugin '{}'...", filterName, pluginName );
final String className = WebXmlUtils.getFilterClassName( webXmlDoc, filterName );
if ( className == null || className.isEmpty() )
{
Log.warn( "Could not load filter '{}' of plugin '{}'. web-xml does not define a class name for this filter.", filterName, pluginName );
continue;
}
final Class theClass = manager.loadClass( plugin, className );
final Object instance = theClass.newInstance();
if ( !(instance instanceof Filter) )
{
Log.warn( "Could not load filter '{}' of plugin '{}'. Its class ({}) is not an instance of javax.servlet.Filter.", filterName, pluginName, className );
continue;
}
Log.debug( "Initializing filter '{}' of plugin '{}'...", filterName, pluginName );
( (Filter) instance ).init( new FilterConfig()
{
@Override
public String getFilterName()
{
return filterName;
}
@Override
public ServletContext getServletContext()
{
return new PluginServletContext( servletConfig.getServletContext(), pluginManager, plugin );
}
catch (Throwable e) {
Log.error(e.getMessage(), e);
@Override
public String getInitParameter( String s )
{
final Map<String, String> params = WebXmlUtils.getFilterInitParams( webXmlDoc, filterName );
if ( params == null || params.isEmpty() )
{
return null;
}
return params.get( s );
}
@Override
public Enumeration<String> getInitParameterNames()
{
final Map<String, String> params = WebXmlUtils.getFilterInitParams( webXmlDoc, filterName );;
if ( params == null || params.isEmpty() )
{
return Collections.emptyEnumeration();
}
return Collections.enumeration( params.keySet() );
}
} );
Log.debug( "Registering filter '{}' of plugin '{}' URL patterns.", filterName, pluginName );
final Set<String> urlPatterns = WebXmlUtils.getFilterUrlPatterns( webXmlDoc, filterName );
for ( final String urlPattern : urlPatterns )
{
PluginFilter.addPluginFilter( urlPattern, ( (Filter) instance ) );
}
Log.debug( "Filter '{}' of plugin '{}' loaded successfully.", filterName, pluginName );
}
}
catch (Throwable e)
{
Log.error( "An unexpected problem occurred while attempting to register servlets for plugin '{}'.", plugin, e);
}
}
......@@ -197,39 +256,74 @@ public class PluginServlet extends HttpServlet {
* @param webXML the web.xml file containing JSP page names to servlet class file
* mappings.
*/
public static void unregisterServlets(File webXML) {
if (!webXML.exists()) {
Log.error("Could not unregister plugin servlets, file " + webXML.getAbsolutePath() +
" does not exist.");
public static void unregisterServlets(File webXML)
{
if ( !webXML.exists() )
{
Log.error("Could not unregister plugin servlets, file " + webXML.getAbsolutePath() + " does not exist.");
return;
}
// Find the name of the plugin directory given that the webXML file
// lives in plugins/[pluginName]/web/web.xml
String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName();
try {
SAXReader saxReader = new SAXReader(false);
saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
Document doc = saxReader.read(webXML);
// Find all <servlet-mapping> entries to discover name to URL mapping.
List names = doc.getRootElement().elements("servlet-mapping");
for (int i = 0; i < names.size(); i++) {
Element nameElement = (Element)names.get(i);
String url = nameElement.element("url-pattern").getTextTrim();
// Destroy the servlet than remove from servlets map.
GenericServlet servlet = servlets.get((pluginName + url).toLowerCase());
if (servlet != null) {
// Find the name of the plugin directory given that the webXML file lives in plugins/[pluginName]/web/web.xml
final String pluginName = webXML.getParentFile().getParentFile().getParentFile().getName();
try
{
final Document webXmlDoc = WebXmlUtils.asDocument( webXML );
// Un-register and destroy all servlets.
final List<String> servletNames = WebXmlUtils.getServletNames( webXmlDoc );
for ( final String servletName : servletNames )
{
Log.debug( "Unregistering servlet '{}' of plugin '{}'", servletName, pluginName );
final Set<Servlet> toDestroy = new HashSet<>();
final Set<String> urlPatterns = WebXmlUtils.getServletUrlPatterns( webXmlDoc, servletName );
for ( final String urlPattern : urlPatterns )
{
final GenericServlet servlet = servlets.remove( ( pluginName + urlPattern ).toLowerCase() );
if (servlet != null)
{
toDestroy.add( servlet );
}
}
for ( final Servlet servlet : toDestroy )
{
servlet.destroy();
}
servlets.remove((pluginName + url).toLowerCase());
servlet = null;
Log.debug( "Servlet '{}' of plugin '{}' unregistered and destroyed successfully.", servletName, pluginName );
}
// Un-register and destroy all servlet filters.
final List<String> filterNames = WebXmlUtils.getFilterNames( webXmlDoc );
for ( final String filterName : filterNames )
{
Log.debug( "Unregistering filter '{}' of plugin '{}'", filterName, pluginName );
final Set<Filter> toDestroy = new HashSet<>();
final String className = WebXmlUtils.getFilterClassName( webXmlDoc, filterName );
final Set<String> urlPatterns = WebXmlUtils.getFilterUrlPatterns( webXmlDoc, filterName );
for ( final String urlPattern : urlPatterns )
{
final Filter filter = PluginFilter.removePluginFilter( urlPattern, className );
if (filter != null)
{
toDestroy.add( filter );
}
catch (Throwable e) {
Log.error(e.getMessage(), e);
}
for ( final Filter filter : toDestroy )
{
filter.destroy();
}
Log.debug( "Filter '{}' of plugin '{}' unregistered and destroyesd successfully.", filterName, pluginName );
}
}
catch (Throwable e) {
Log.error( "An unexpected problem occurred while attempting to unregister servlets.", e);
}
}
/**
* Registers a live servlet for a plugin programmatically, does not
......
/*
* Copyright 2016 IgniteRealtime.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.container;
import javax.servlet.*;
import javax.servlet.descriptor.JspConfigDescriptor;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
/**
* A Servlet Context to be used by Openfire plugins.
*
* This implementation is used do load resources from the plugin classpath. Other functionality is delegated to a proxy
* implementation.
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class PluginServletContext implements ServletContext
{
protected final ServletContext proxy;
private final PluginManager pluginManager;
private final Plugin plugin;
public PluginServletContext( ServletContext proxy, PluginManager pluginManager, Plugin plugin )
{
this.proxy = proxy;
this.pluginManager = pluginManager;
this.plugin = plugin;
}
/**
* The plugin classloader is an URL classloadeer, which will do lookups in directories with entries like these:
* jar:file:/home/guus/github/Openfire/target/openfire/plugins/oauthresourceserver/lib/plugin-oauthresourceserver.jar!/
* (note the trailing slash).
*
* To prevent lookup failures, strip any leading slash (which, when concatinated, would result "//").
*
* @param input A string (cannot be null)
* @return The string without the first leading slash.
*/
protected static String stripLeadingSlash( String input ) {
if (input.startsWith("/"))
{
return input.substring(1);
}
else{
return input;
}
}
@Override
public String getContextPath()
{
return proxy.getContextPath();
}
@Override
public ServletContext getContext( String s )
{
return proxy.getContext( s );
}
@Override
public int getMajorVersion()
{
return proxy.getMajorVersion();
}
@Override
public int getMinorVersion()
{
return proxy.getMinorVersion();
}
@Override
public int getEffectiveMajorVersion()
{
return proxy.getEffectiveMajorVersion();
}
@Override
public int getEffectiveMinorVersion()
{
return proxy.getEffectiveMinorVersion();
}
@Override
public String getMimeType( String s )
{
return proxy.getMimeType( s );
}
@Override
public Set<String> getResourcePaths( String s )
{
final String pluginPath = "/plugins/" + pluginManager.getName( plugin ) + "/";
final Set<String> proxyResults = proxy.getResourcePaths( pluginPath + s );
final Set<String> results = new HashSet<>();
for ( final String proxyResult : proxyResults )
{
results.add( proxyResult.replaceFirst( pluginPath, "" ) );
}
return results;
}
@Override
public URL getResource( String s ) throws MalformedURLException
{
return pluginManager.getPluginClassloader( plugin ).getResource( stripLeadingSlash( s ) );
}
@Override
public InputStream getResourceAsStream( String s )
{
return pluginManager.getPluginClassloader( plugin ).getResourceAsStream( stripLeadingSlash( s ) );
}
@Override
public RequestDispatcher getRequestDispatcher( String s )
{
return proxy.getRequestDispatcher( s );
}
@Override
public RequestDispatcher getNamedDispatcher( String s )
{
return proxy.getNamedDispatcher( s );
}
@Override
public Servlet getServlet( String s ) throws ServletException
{
return proxy.getServlet( s );
}
@Override
public Enumeration<Servlet> getServlets()
{
return proxy.getServlets();
}
@Override
public Enumeration<String> getServletNames()
{
return proxy.getServletNames();
}
@Override
public void log( String s )
{
proxy.log( s );
}
@Override
public void log( Exception e, String s )
{
proxy.log( e, s );
}
@Override
public void log( String s, Throwable throwable )
{
proxy.log( s, throwable );
}
@Override
public String getRealPath( String s )
{
return null;
}
@Override
public String getServerInfo()
{
return proxy.getServerInfo();
}
@Override
public String getInitParameter( String s )
{
return proxy.getInitParameter( s );
}
@Override
public Enumeration<String> getInitParameterNames()
{
return proxy.getInitParameterNames();
}
@Override
public boolean setInitParameter( String s, String s1 )
{
return proxy.setInitParameter( s, s1 );
}
@Override
public Object getAttribute( String s )
{
return proxy.getAttribute( s );
}
@Override
public Enumeration<String> getAttributeNames()
{
return proxy.getAttributeNames();
}
@Override
public void setAttribute( String s, Object o )
{
proxy.setAttribute( s, o );
}
@Override
public void removeAttribute( String s )
{
proxy.removeAttribute( s );
}
@Override
public String getServletContextName()
{
return proxy.getServletContextName();
}
@Override
public ServletRegistration.Dynamic addServlet( String s, String s1 )
{
return proxy.addServlet( s, s1 );
}
@Override
public ServletRegistration.Dynamic addServlet( String s, Servlet servlet )
{
return proxy.addServlet( s, servlet );
}
@Override
public ServletRegistration.Dynamic addServlet( String s, Class<? extends Servlet> aClass )
{
return proxy.addServlet( s, aClass );
}
@Override
public <T extends Servlet> T createServlet( Class<T> aClass ) throws ServletException
{
return proxy.createServlet( aClass );
}
@Override
public ServletRegistration getServletRegistration( String s )
{
return proxy.getServletRegistration( s );
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations()
{
return proxy.getServletRegistrations();
}
@Override
public FilterRegistration.Dynamic addFilter( String s, String s1 )
{
return proxy.addFilter( s, s1 );
}
@Override
public FilterRegistration.Dynamic addFilter( String s, Filter filter )
{
return proxy.addFilter( s, filter );
}
@Override
public FilterRegistration.Dynamic addFilter( String s, Class<? extends Filter> aClass )
{
return proxy.addFilter( s, aClass );
}
@Override
public <T extends Filter> T createFilter( Class<T> aClass ) throws ServletException
{
return proxy.createFilter( aClass );
}
@Override
public FilterRegistration getFilterRegistration( String s )
{
return proxy.getFilterRegistration( s );
}
@Override
public Map<String, ? extends FilterRegistration> getFilterRegistrations()
{
return proxy.getFilterRegistrations();
}
@Override
public SessionCookieConfig getSessionCookieConfig()
{
return proxy.getSessionCookieConfig();
}
@Override
public void setSessionTrackingModes( Set<SessionTrackingMode> set )
{
proxy.setSessionTrackingModes( set );
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
{
return proxy.getDefaultSessionTrackingModes();
}
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
{
return proxy.getEffectiveSessionTrackingModes();
}
@Override
public void addListener( String s )
{
proxy.addListener( s );
}
@Override
public <T extends EventListener> void addListener( T t )
{
proxy.addListener( t );
}
@Override
public void addListener( Class<? extends EventListener> aClass )
{
proxy.addListener( aClass );
}
@Override
public <T extends EventListener> T createListener( Class<T> aClass ) throws ServletException
{
return proxy.createListener( aClass );
}
@Override
public JspConfigDescriptor getJspConfigDescriptor()
{
return proxy.getJspConfigDescriptor();
}
@Override
public ClassLoader getClassLoader()
{
return pluginManager.getPluginClassloader( plugin );
}
@Override
public void declareRoles( String... strings )
{
proxy.declareRoles( strings );
}
@Override
public String getVirtualServerName()
{
return proxy.getVirtualServerName();
}
}
package org.jivesoftware.util;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import java.io.File;
import java.util.*;
/**
* Utilities to extract data from a web.xml file.
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class WebXmlUtils
{
private final static Logger Log = LoggerFactory.getLogger( WebXmlUtils.class );
public static Document asDocument( File webXML ) throws DocumentException
{
// Make the reader non-validating so that it doesn't try to resolve external DTD's. Trying to resolve
// external DTD's can break on some firewall configurations.
SAXReader saxReader = new SAXReader( false);
try {
saxReader.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false );
}
catch (SAXException e)
{
Log.warn("Error setting SAXReader feature", e);
}
return saxReader.read( webXML );
}
/**
* Retrieves the names of all servlets from a web.xml document.
*
* Returns a list that contains 'sessioncreate' and 'sessiondestroy' from this web.xml document:
* <servlet>
* <servlet-name>sessioncreate</servlet-name>
* <servlet-class>SessionCreateServlet</servlet-class>
* </servlet>
* <servlet>
* <servlet-name>sessiondestroy</servlet-name>
* <servlet-class>SessionDestroyServlet</servlet-class>
* </servlet>
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @return The name of the filter class, or null when no such class was defined.
*/
public static List<String> getServletNames( Document webXml )
{
return getNames( "servlet", webXml );
}
/**
* Retrieves the names of all filters from a web.xml document.
*
* Returns a list that contains 'message' from this web.xml document:
* <filter>
* <filter-name>message</filter-name>
* <filter-class>com.acme.filter.MessageFilter</filter-class>
* </filter>
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @return The name of the filter class, or null when no such class was defined.
*/
public static List<String> getFilterNames( Document webXml )
{
return getNames( "filter", webXml );
}
private static List<String> getNames( String type, Document webXml )
{
final List<String> result = new ArrayList<>();
final List<Element> elements = webXml.getRootElement().elements( type ); // all elements of 'type' (filter or servlet).
for ( final Element element : elements )
{
final String name = element.elementTextTrim( type + "-name" );
if ( name != null && !name.isEmpty() )
{
result.add( name );
}
}
return result;
}
/**
* Retrieves the class name for a particular servlet from a web.xml document.
*
* Returns 'SessionCreateServlet' for 'sessioncreate' of this web.xml document:
* <servlet>
* <servlet-name>sessioncreate</servlet-name>
* <servlet-class>SessionCreateServlet</servlet-class>
* </servlet>
* <servlet>
* <servlet-name>sessiondestroy</servlet-name>
* <servlet-class>SessionDestroyServlet</servlet-class>
* </servlet>
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @param servletName The name of the servlet (cannot be null or empty).
* @return The name of the filter class, or null when no such class was defined.
*/
public static String getServletClassName( Document webXml, String servletName )
{
return getClassName( "servlet", webXml, servletName );
}
/**
* Retrieves the class name for a particular filter from a web.xml document.
*
* Returns 'com.acme.filter.MessageFilter' for 'message' of this web.xml document:
* <filter>
* <filter-name>message</filter-name>
* <filter-class>com.acme.filter.MessageFilter</filter-class>
* </filter>
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @param filterName The name of the filter (cannot be null or empty).
* @return The name of the filter class, or null when no such class was defined.
*/
public static String getFilterClassName( Document webXml, String filterName )
{
return getClassName( "filter", webXml, filterName );
}
private static String getClassName( String type, Document webXml, String typeName )
{
String className = null;
final List<Element> elements = webXml.getRootElement().elements( type ); // all elements of 'type' (filter or servlet).
for ( final Element element : elements )
{
final String name = element.elementTextTrim( type + "-name" );
if ( typeName.equals( name ) )
{
className = element.elementTextTrim( type + "-class" );
break;
}
}
if (className == null || className.isEmpty() )
{
return null;
}
return className;
}
/**
* Retrieves a map of init param/values for a particular servlet from a web.xml document.
*
* For filter 'message' of this web.xml document, returns a map with two entries: foo-> bar, test->value.
* <servlet>
* <servlet-name>sessioncreate</servlet-name>
* <servlet-class>SessionCreateServlet</servlet-class>
* <init-param>
* <param-name>foo</param-name>
* <param-value>bar</param-value>
* </init-param>
* <init-param>
* <param-name>test</param-name>
* <param-value>value</param-value>
* </init-param>
* </servlet>
*
* Parameters with no or empty name are ignored. When multiple parameters have the same name, only one of them is
* returned.
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @param servletName The name of the servlet (cannot be null or empty).
* @return A map (possibly empty, but never null).
*/
public static Map<String, String> getServletInitParams( Document webXml, String servletName )
{
return getInitParams( "servlet", webXml, servletName );
}
/**
* Retrieves a map of init param/values for a particular filter from a web.xml document.
*
* For filter 'message' of this web.xml document, returns a map with two entries: foo-> bar, test->value.
* <filter>
* <filter-name>message</filter-name>
* <filter-class>com.acme.filter.MessageFilter</filter-class>
* <init-param>
* <param-name>foo</param-name>
* <param-value>bar</param-value>
* </init-param>
* <init-param>
* <param-name>test</param-name>
* <param-value>value</param-value>
* </init-param>
* </filter>
*
* Parameters with no or empty name are ignored. When multiple parameters have the same name, only one of them is
* returned.
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @param filterName The name of the filter (cannot be null or empty).
* @return A map (possibly empty, but never null).
*/
public static Map<String, String> getFilterInitParams( Document webXml, String filterName )
{
return getInitParams( "filter", webXml, filterName );
}
private static Map<String, String> getInitParams( String type, Document webXml, String typeName )
{
final Map<String, String> result = new HashMap<>();
final List<Element> elements = webXml.getRootElement().elements( type ); // all elements of 'type' (filter or servlet).
for ( final Element element : elements )
{
final String name = element.elementTextTrim( type + "-name" );
if ( typeName.equals( name ) )
{
final List<Element> initParamElements = element.elements( "init-param" );
for ( final Element initParamElement : initParamElements )
{
final String pName = initParamElement.elementTextTrim( "param-name" );
final String pValue = initParamElement.elementTextTrim( "param-value" );
if ( pName == null || pName.isEmpty() ) {
Log.warn( "Unable to add init-param that has no name" );
}
else
{
result.put( pName, pValue );
}
}
}
}
return result;
}
/**
* Retrieves all URL patterns that apply to a specific servlet.
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @param servletName The name of the servlet (cannot be null or empty).
* @return A collection (possibly empty, but never null).
*/
public static Set<String> getServletUrlPatterns( Document webXml, String servletName )
{
return getUrlPatterns( "servlet", webXml, servletName );
}
/**
* Retrieves all URL patterns that apply to a specific filter.
*
* @param webXml web.xml document, parsed as XML (cannot be null)
* @param filterName The name of the filter (cannot be null or empty).
* @return A collection (possibly empty, but never null).
*/
public static Set<String> getFilterUrlPatterns( Document webXml, String filterName )
{
return getUrlPatterns( "filter", webXml, filterName );
}
private static Set<String> getUrlPatterns( String type, Document webXml, String typeName )
{
final Set<String> result = new HashSet<>();
final List<Element> elements = webXml.getRootElement().elements( type + "-mapping" ); // all elements of 'type'-mapping (filter-mapping or servlet-mapping).
for ( final Element element : elements )
{
final String name = element.elementTextTrim( type + "-name" );
if ( typeName.equals( name ) )
{
final List<Element> urlPatternElements = element.elements( "url-pattern" );
for ( final Element urlPatternElement : urlPatternElements )
{
final String urlPattern = urlPatternElement.getTextTrim();
if ( urlPattern != null )
{
result.add( urlPattern );
}
}
// A filter can also be mapped to a servlet (by name). In that case, all url-patterns of the corresponding servlet-mapping should be used.
if ( "filter".equals( type ) )
{
final List<Element> servletNameElements = element.elements( "servlet-name" );
for ( final Element servletNameElement : servletNameElements )
{
final String servletName = servletNameElement.getTextTrim();
if ( servletName != null )
{
result.addAll( getUrlPatterns( "servlet", webXml, servletName ) );
}
}
}
break;
}
}
return result;
}
}
package org.jivesoftware.util;
import org.dom4j.Document;
import org.junit.Test;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
/**
* Unit tests for {@link WebXmlUtils}
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class WebXmlUtilsTest
{
@Test
public void testGetServletNames() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
// Execute system under test.
final List<String> results = WebXmlUtils.getServletNames( webXml );
// Verify result.
assertNotNull( results );
final Iterator iterator = results.iterator(); // Names should be reported in order.
assertEquals( "PluginServlet", iterator.next() );
assertEquals( "FaviconServlet", iterator.next() );
assertEquals( "dwr-invoker", iterator.next() );
assertEquals( "PluginIconServlet", iterator.next() );
assertFalse( iterator.hasNext() );
}
@Test
public void testGetFilterNames() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
// Execute system under test.
final List<String> results = WebXmlUtils.getFilterNames( webXml );
// Verify result.
assertNotNull( results );
final Iterator iterator = results.iterator(); // Names should be reported in order.
assertEquals( "AuthCheck", iterator.next() );
assertEquals( "PluginFilter", iterator.next() );
assertEquals( "Set Character Encoding", iterator.next() );
assertEquals( "LocaleFilter", iterator.next() );
assertEquals( "sitemesh", iterator.next() );
assertFalse( iterator.hasNext() );
}
@Test
public void testGetServletClassName() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "dwr-invoker";
// Execute system under test.
final String result = WebXmlUtils.getServletClassName( webXml, servletName );
// Verify result.
assertEquals( "uk.ltd.getahead.dwr.DWRServlet", result );
}
@Test
public void testGetServletClassNameForNonExistingServlet() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "This does not exist";
// Execute system under test.
final String result = WebXmlUtils.getServletClassName( webXml, servletName );
// Verify result.
assertNull( result );
}
@Test
public void testGetFilterClassName() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "Set Character Encoding";
// Execute system under test.
final String result = WebXmlUtils.getFilterClassName( webXml, filterName );
// Verify result.
assertEquals( "org.jivesoftware.util.SetCharacterEncodingFilter", result );
}
@Test
public void testGetFilterClassNameForNonExistingFilter() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "This does not exist";
// Execute system under test.
final String result = WebXmlUtils.getFilterClassName( webXml, filterName );
// Verify result.
assertNull( result );
}
@Test
public void testGetServletInitParams() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "FaviconServlet";
// Execute system under test.
final Map<String, String> result = WebXmlUtils.getServletInitParams( webXml, servletName );
// Verify result.
assertNotNull( result );
assertEquals( 2, result.size() );
assertEquals( "42", result.get("answer") );
assertEquals( "fishes", result.get("thanks") );
}
@Test
public void testGetServletInitParamsForServletWithoutParams() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "PluginServlet";
// Execute system under test.
final Map<String, String> result = WebXmlUtils.getServletInitParams( webXml, servletName );
// Verify result.
assertNotNull( result );
assertEquals( 0, result.size() );
}
@Test
public void testGetServletInitParamsForNonExistingServlet() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "This does not exist";
// Execute system under test.
final Map<String, String> result = WebXmlUtils.getServletInitParams( webXml, servletName );
// Verify result.
assertNotNull( result );
assertEquals( 0, result.size() );
}
@Test
public void testGetFilterInitParams() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "AuthCheck";
// Execute system under test.
final Map<String, String> result = WebXmlUtils.getFilterInitParams( webXml, filterName );
// Verify result.
assertNotNull( result );
assertEquals( 1, result.size() );
assertEquals( "login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-*,.gif,.png,error-serverdown.jsp", result.get("excludes") );
}
@Test
public void testGetFilterInitParamsForFilterWithoutParams() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "PluginFilter";
// Execute system under test.
final Map<String, String> result = WebXmlUtils.getFilterInitParams( webXml, filterName );
// Verify result.
assertNotNull( result );
assertEquals( 0, result.size() );
}
@Test
public void testGetFilterInitParamsForNonExistingFilter() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "This does not exist";
// Execute system under test.
final Map<String, String> result = WebXmlUtils.getFilterInitParams( webXml, filterName );
// Verify result.
assertNotNull( result );
assertEquals( 0, result.size() );
}
@Test
public void testGetServletUrlPatterns() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "dwr-invoker";
// Execute system under test.
final Set<String> results = WebXmlUtils.getServletUrlPatterns( webXml, servletName );
// Verify result.
assertNotNull( results );
assertEquals( 2, results.size() );
assertTrue( results.contains( "/dwr/*" ));
assertTrue( results.contains( "/more-dwr/*" ));
}
@Test
public void testGetServletUrlPatternsForNonExistingServlet() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String servletName = "This does not exist";
// Execute system under test.
final Set<String> results = WebXmlUtils.getServletUrlPatterns( webXml, servletName );
// Verify result.
assertNotNull( results );
assertEquals( 0, results.size() );
}
@Test
public void testGetFilterUrlPatterns() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "LocaleFilter";
// Execute system under test.
final Set<String> results = WebXmlUtils.getFilterUrlPatterns( webXml, filterName );
// Verify result.
assertNotNull( results );
assertEquals( 2, results.size() );
assertTrue( results.contains( "*.jsp" ));
assertTrue( results.contains( "foo.bar" ));
}
@Test
public void testGetFilterUrlPatternsForNonExistingFilter() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "This does not exist";
// Execute system under test.
final Set<String> results = WebXmlUtils.getFilterUrlPatterns( webXml, filterName );
// Verify result.
assertNotNull( results );
assertEquals( 0, results.size() );
}
@Test
public void testGetFilterUrlPatternsForFilterThatUsesServletMapping() throws Exception
{
// Setup fixture.
final Document webXml = WebXmlUtils.asDocument( new File( WebXmlUtilsTest.class.getResource( "/org/jivesoftware/util/test-web.xml" ).toURI() ) );
final String filterName = "AuthCheck";
// Execute system under test.
final Set<String> results = WebXmlUtils.getFilterUrlPatterns( webXml, filterName );
// Verify result.
assertNotNull( results );
assertEquals( 3, results.size() );
assertTrue( results.contains( "test/*.jsp" )); // from url pattern
assertTrue( results.contains( "/dwr/*" )); // from servlet-mapping
assertTrue( results.contains( "/more-dwr/*" ));// from servlet-mapping
}
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Openfire</display-name>
<!-- OF-902 use HttpOnly for session cookie -->
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
<!-- prevent URL rewritting with jsessionid included, OF-669 -->
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionIdPathParameterName</param-name>
<param-value>none</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>openfire_i18n</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.locale</param-name>
<param-value>zh_CN</param-value>
</context-param>
<filter>
<filter-name>AuthCheck</filter-name>
<filter-class>org.jivesoftware.admin.AuthCheckFilter</filter-class>
<init-param>
<param-name>excludes</param-name>
<param-value>
login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-*,.gif,.png,error-serverdown.jsp
</param-value>
</init-param>
</filter>
<filter>
<filter-name>PluginFilter</filter-name>
<filter-class>org.jivesoftware.admin.PluginFilter</filter-class>
</filter>
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>org.jivesoftware.util.SetCharacterEncodingFilter</filter-class>
</filter>
<filter>
<filter-name>LocaleFilter</filter-name>
<filter-class>org.jivesoftware.util.LocaleFilter</filter-class>
</filter>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PluginFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LocaleFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>foo.bar</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>PluginFilter</filter-name>
<servlet-name>PluginServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AuthCheck</filter-name>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>test/*.jsp</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.jivesoftware.openfire.XMPPContextListener</listener-class>
</listener>
<servlet>
<servlet-name>PluginServlet</servlet-name>
<servlet-class>org.jivesoftware.openfire.container.PluginServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>FaviconServlet</servlet-name>
<servlet-class>org.jivesoftware.util.FaviconServlet</servlet-class>
<init-param>
<param-name>thanks</param-name>
<param-value>fishes</param-value>
</init-param>
<init-param>
<param-name>answer</param-name>
<param-value>42</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>PluginIconServlet</servlet-name>
<servlet-class>org.jivesoftware.openfire.container.PluginIconServlet</servlet-class>
</servlet>
<!--<servlet>
<servlet-name>WebDAVLiteServlet</servlet-name>
<servlet-class>org.jivesoftware.openfire.webdav.WebDAVLiteServlet</servlet-class>
</servlet>-->
<!--@@JSPC-SERVLETS@@-->
<servlet-mapping>
<servlet-name>PluginServlet</servlet-name>
<url-pattern>/plugins/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FaviconServlet</servlet-name>
<url-pattern>/getFavicon</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PluginIconServlet</servlet-name>
<url-pattern>/geticon</url-pattern>
</servlet-mapping>
<!--<servlet-mapping>
<servlet-name>WebDAVLiteServlet</servlet-name>
<url-pattern>/webdav/*</url-pattern>
</servlet-mapping>-->
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
<url-pattern>/more-dwr/*</url-pattern>
</servlet-mapping>
</web-app>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment