Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   //
   //  ========================================================================
   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
   //  ------------------------------------------------------------------------
   //  All rights reserved. This program and the accompanying materials
   //  are made available under the terms of the Eclipse Public License v1.0
   //  and Apache License v2.0 which accompanies this distribution.
   //
   //      The Eclipse Public License is available at
  //      http://www.eclipse.org/legal/epl-v10.html
  //
  //      The Apache License v2.0 is available at
  //      http://www.opensource.org/licenses/apache2.0.php
  //
  //  You may elect to redistribute this code under either of these licenses.
  //  ========================================================================
  //
  
  package org.eclipse.jetty.servlet;
  
  import java.util.Arrays;
  import java.util.EnumSet;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Set;
  import java.util.List;
  import java.util.Map;
  import java.util.Queue;
  
  
  
  /* --------------------------------------------------------------------- */
Servlet HttpHandler. This handler maps requests to servlets that implement the javax.servlet.http.HttpServlet API.

This handler does not implement the full J2EE features and is intended to be used directly when a full web application is not required. If a Web application is required, then this handler should be used as part of a org.eclipse.jetty.webapp.WebAppContext.

Unless run as part of a ServletContextHandler or derivative, the initialize() method must be called manually after start().

  
  public class ServletHandler extends ScopedHandler
  {
      private static final Logger LOG = Log.getLogger(ServletHandler.class);
  
      /* ------------------------------------------------------------ */
      public static final String __DEFAULT_SERVLET="default";
          
      /* ------------------------------------------------------------ */
      private FilterHolder[] _filters=new FilterHolder[0];
     private FilterMapping[] _filterMappings;
     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 boolean _filterChainsCached=true;
     private int _maxFilterChainsCacheSize=512;
     private boolean _startWithUnavailable=true;
     
     private ServletHolder[] _servlets=new ServletHolder[0];
     private ServletMapping[] _servletMappings;
     
     private final Map<String,FilterHolder_filterNameMapnew HashMap<String,FilterHolder>();
     private MultiMap<String_filterNameMappings;
     
     private PathMap _servletPathMap;
     
     protected final ConcurrentMap<String,FilterChain_chainCache[] = new ConcurrentMap[.];
     protected final Queue<String>[] _chainLRU = new Queue[.];
 
 
     /* ------------------------------------------------------------ */
    
Constructor.
 
     public ServletHandler()
     {
     }
 
     /* ------------------------------------------------------------ */
     /* 
      * @see org.eclipse.jetty.server.handler.AbstractHandler#setServer(org.eclipse.jetty.server.Server)
      */
     public void setServer(Server server)
     {
         Server old=getServer();
         if (old!=null && old!=server)
         {
             getServer().getContainer().update(thisnull"filter",true);
             getServer().getContainer().update(thisnull"filterMapping",true);
             getServer().getContainer().update(thisnull"servlet",true);
             getServer().getContainer().update(thisnull"servletMapping",true);
         }
 
         super.setServer(server);
         
         if (server!=null && old!=server)
         {
             server.getContainer().update(thisnull"filter",true);
             server.getContainer().update(thisnull"filterMapping",true);
             server.getContainer().update(thisnull"servlet",true);
             server.getContainer().update(thisnull"servletMapping",true);
         }
     }
 
     /* ----------------------------------------------------------------- */
     @Override
     protected synchronized void doStart()
         throws Exception
     {
         =ContextHandler.getCurrentContext();
 
         if (!=null)
         {
             SecurityHandler security_handler = (SecurityHandler).getChildHandlerByClass(SecurityHandler.class);
             if (security_handler!=null)
                 =security_handler.getIdentityService();
         }
         
         updateNameMappings();
         updateMappings();
         
         if()
         {
             
             [.]=new ConcurrentLinkedQueue<String>();
             [.]=new ConcurrentLinkedQueue<String>();
             [.]=new ConcurrentLinkedQueue<String>();
             [.]=new ConcurrentLinkedQueue<String>();
             [.]=new ConcurrentLinkedQueue<String>();
         }
 
         super.doStart();
         
         if (==null || !( instanceof ServletContextHandler))
             initialize();
     }   
     
     /* ----------------------------------------------------------------- */
     @Override
     protected synchronized void doStop()
         throws Exception
     {
         super.doStop();
         
         // Stop filters
         if (!=null)
         {
             for (int i=.i-->0;)
             {
                 try { [i].stop(); }catch(Exception e){.warn(.,e);}
             }
         }
         
         // Stop servlets
         if (!=null)
         {
             for (int i=.i-->0;)
             {
                 try { [i].stop(); }catch(Exception e){.warn(.,e);}
             }
         }
 
         =null;
         =null;
         
         =null;
     }
 
     /* ------------------------------------------------------------ */
     {
         return ;
     }
     
     /* ------------------------------------------------------------ */
    

Returns:
Returns the contextLog.
 
     public Object getContextLog()
     {
         return null;
     }
     
     /* ------------------------------------------------------------ */
    

Returns:
Returns the filterMappings.
 
     public FilterMapping[] getFilterMappings()
     {
         return ;
     }
     
     /* ------------------------------------------------------------ */
    
Get Filters.

Returns:
Array of defined servlets
 
     public FilterHolder[] getFilters()
     {
         return ;
     }
     
     /* ------------------------------------------------------------ */
    
ServletHolder matching path.

Parameters:
pathInContext Path within _context.
Returns:
PathMap Entries pathspec to ServletHolder
 
     public PathMap.Entry getHolderEntry(String pathInContext)
     {
         if (==null)
             return null;
         return .getMatch(pathInContext);
     }
  
     /* ------------------------------------------------------------ */
     {
         return ;
     }
     
     /* ------------------------------------------------------------ */
    

Returns:
Returns the servletMappings.
 
     public ServletMapping[] getServletMappings()
     {
         return ;
     }
     
     /* ------------------------------------------------------------ */
    

Returns:
Returns the servletMappings.
 
     public ServletMapping getServletMapping(String pattern)
     {
         ServletMapping theMapping = null;
         if (!=null)
         {
             for (ServletMapping m:)
             {
                 String[] paths=m.getPathSpecs();
                 if (paths!=null)
                 {
                     for (String path:paths)
                     {
                         if (pattern.equals(path))
                             theMapping = m;
                     }
                 }
             }
         }
         return theMapping;
     }
         
     /* ------------------------------------------------------------ */
    
Get Servlets.

Returns:
Array of defined servlets
 
     public ServletHolder[] getServlets()
     {
         return ;
     }
 
     /* ------------------------------------------------------------ */
     public ServletHolder getServlet(String name)
     {
         return (ServletHolder).get(name);
     }
 
     /* ------------------------------------------------------------ */
     @Override
     public void doScope(String targetRequest baseRequestHttpServletRequest requestHttpServletResponse responsethrows IOExceptionServletException
     {
         // Get the base requests
         final String old_servlet_path=baseRequest.getServletPath();
         final String old_path_info=baseRequest.getPathInfo();
 
         DispatcherType type = baseRequest.getDispatcherType();
        
         ServletHolder servlet_holder=null;
         UserIdentity.Scope old_scope=null;
 
         // find the servlet
         if (target.startsWith("/"))
         {
             // Look for the servlet by path
             PathMap.Entry entry=getHolderEntry(target);
             if (entry!=null)
             {
                 servlet_holder=(ServletHolder)entry.getValue();
 
                 String servlet_path_spec=(String)entry.getKey(); 
                 String servlet_path=entry.getMapped()!=null?entry.getMapped():PathMap.pathMatch(servlet_path_spec,target);
                 String path_info=PathMap.pathInfo(servlet_path_spec,target); 
                 
                 if (..equals(type))
                 {
                     baseRequest.setAttribute(.,servlet_path);
                     baseRequest.setAttribute(.path_info);
                 }
                 else
                 {
                     baseRequest.setServletPath(servlet_path);
                     baseRequest.setPathInfo(path_info);
                 }
             }      
         }
         else
         {
             // look for a servlet by name!
             servlet_holder=(ServletHolder).get(target);
         }
        
         if (.isDebugEnabled())
             .debug("servlet {}|{}|{} -> {}",baseRequest.getContextPath(),baseRequest.getServletPath(),baseRequest.getPathInfo(),servlet_holder);
 
         try
         {
             // Do the filter/handling thang
             old_scope=baseRequest.getUserIdentityScope();
             baseRequest.setUserIdentityScope(servlet_holder);
 
             // start manual inline of nextScope(target,baseRequest,request,response);
             if (never())
                 nextScope(target,baseRequest,request,response);
             else if (!=null)
                 .doScope(target,baseRequest,requestresponse);
             else if (!=null)
                 .doHandle(target,baseRequest,requestresponse);
             else 
                 doHandle(target,baseRequest,requestresponse);
             // end manual inline (pathentic attempt to reduce stack depth)
         }
         finally
         {
             if (old_scope!=null)
                 baseRequest.setUserIdentityScope(old_scope);
 
             if (!(..equals(type)))
             {
                 baseRequest.setServletPath(old_servlet_path);
                 baseRequest.setPathInfo(old_path_info); 
             }
         }
     }
     
     /* ------------------------------------------------------------ */
     /* 
      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
      */
     @Override
     public void doHandle(String targetRequest baseRequest,HttpServletRequest requestHttpServletResponse response)
         throws IOExceptionServletException
     {
         DispatcherType type = baseRequest.getDispatcherType();
         
         ServletHolder servlet_holder=(ServletHolderbaseRequest.getUserIdentityScope();
         FilterChain chain=null;
 
         // find the servlet
         if (target.startsWith("/"))
         {
             if (servlet_holder!=null && !=null && .>0)
                 chain=getFilterChain(baseRequesttargetservlet_holder);
         }
         else
         {
             if (servlet_holder!=null)
             {
                 if (!=null && .>0)
                 {
                     chain=getFilterChain(baseRequestnull,servlet_holder);
                 }
             }
         }
 
         .debug("chain={}",chain);
         
         try
         {
             if (servlet_holder==null)
             {
                 if (getHandler()==null)
                     notFound(requestresponse);
                 else
                     nextHandle(target,baseRequest,request,response);
             }
             else
             {
                 // unwrap any tunnelling of base Servlet request/responses
                 ServletRequest req = request;
                 if (req instanceof ServletRequestHttpWrapper)
                     req = ((ServletRequestHttpWrapper)req).getRequest();
                 ServletResponse res = response;
                 if (res instanceof ServletResponseHttpWrapper)
                     res = ((ServletResponseHttpWrapper)res).getResponse();
 
                 // Do the filter/handling thang
                 if (chain!=null)
                     chain.doFilter(reqres);
                 else 
                     servlet_holder.handle(baseRequest,req,res);
             }
         }
         catch(EofException e)
         {
             throw e;
         }
         catch(RuntimeIOException e)
         {
             throw e;
         }
         catch(ContinuationThrowable e)
         {   
             throw e;
         }
         catch(Exception e)
         {
             if (!(..equals(type) || ..equals(type)))
             {
                 if (e instanceof IOException)
                     throw (IOException)e;
                 if (e instanceof RuntimeException)
                     throw (RuntimeException)e;
                 if (e instanceof ServletException)
                     throw (ServletException)e;
             }
 
             // unwrap cause
             Throwable th=e;
             if (th instanceof UnavailableException)
             {
                 .debug(th); 
             }
             else if (th instanceof ServletException)
             {
                 .warn(th);
                 Throwable cause=((ServletException)th).getRootCause();
                 if (cause!=null)
                     th=cause;
             }
 
             // handle or log exception
             if (th instanceof HttpException)
                 throw (HttpException)th;
             else if (th instanceof RuntimeIOException)
                 throw (RuntimeIOException)th;
             else if (th instanceof EofException)
                 throw (EofException)th;
 
             else if (.isDebugEnabled())
             {
                 .warn(request.getRequestURI(), th); 
                 .debug(request.toString()); 
             }
             else if (th instanceof IOException || th instanceof UnavailableException)
             {
                 .debug(request.getRequestURI(),th);
             }
             else
             {
                 .warn(request.getRequestURI(),th);
             }
 
             if (!response.isCommitted())
             {
                 request.setAttribute(.,th.getClass());
                 request.setAttribute(.,th);
                 if (th instanceof UnavailableException)
                 {
                     UnavailableException ue = (UnavailableException)th;
                     if (ue.isPermanent())
                         response.sendError(.);
                     else
                         response.sendError(.);
                 }
                 else
                     response.sendError(.);
             }
             else
                 .debug("Response already committed for handling "+th);
         }
         catch(Error e)
         {   
             if (!(..equals(type) || ..equals(type)))
                 throw e;
             .warn("Error for "+request.getRequestURI(),e);
             if(.isDebugEnabled()).debug(request.toString());
 
             // TODO httpResponse.getHttpConnection().forceClose();
             if (!response.isCommitted())
             {
                 request.setAttribute(.,e.getClass());
                 request.setAttribute(.,e);
                 response.sendError(.);
             }
             else
                 .debug("Response already committed for handling ",e);
         }
         finally
         {
             if (servlet_holder!=null)
                 baseRequest.setHandled(true);
         }
     }
 
     /* ------------------------------------------------------------ */
     private FilterChain getFilterChain(Request baseRequestString pathInContextServletHolder servletHolder
     {
         String key=pathInContext==null?servletHolder.getName():pathInContext;
         int dispatch = FilterMapping.dispatch(baseRequest.getDispatcherType());
         
         if ( && !=null)
         {
             FilterChain chain = (FilterChain)[dispatch].get(key);
             if (chain!=null)
                 return chain;
         }
         
         // Build list of filters
         Object filtersnull;
         // Path filters
         if (pathInContext!=null && !=null)
         {
             for (int i= 0; i < .size(); i++)
             {
                 FilterMapping mapping = (FilterMapping).get(i);
                 if (mapping.appliesTo(pathInContextdispatch))
                     filters= LazyList.add(filtersmapping.getFilterHolder());
             }
         }
 
         // Servlet name filters
         if (servletHolder != null && !=null && .size() > 0)
         {
             // Servlet name filters
             if (.size() > 0)
             {
                 Object o.get(servletHolder.getName());
                 for (int i=0; i<LazyList.size(o);i++)
                 {
                     FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
                     if (mapping.appliesTo(dispatch))
                         filters=LazyList.add(filters,mapping.getFilterHolder());
                 }
                 
                 o.get("*");
                 for (int i=0; i<LazyList.size(o);i++)
                 {
                     FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
                     if (mapping.appliesTo(dispatch))
                         filters=LazyList.add(filters,mapping.getFilterHolder());
                 }
             }
         }
         
         if (filters==null)
             return null;
         
         
         FilterChain chain = null;
         if ()
         {
             if (LazyList.size(filters) > 0)
                 chainnew CachedChain(filtersservletHolder);
 
             final Map<String,FilterChaincache=[dispatch];
             final Queue<Stringlru=[dispatch];
 
         	// Do we have too many cached chains?
         	while (>0 && cache.size()>=)
         	{
         	    // The LRU list is not atomic with the cache map, so be prepared to invalidate if 
         	    // a key is not found to delete.
         	    // Delete by LRU (where U==created)
         	    String k=lru.poll();
         	    if (k==null)
         	    {
         	        cache.clear();
         	        break;
         	    }
         	    cache.remove(k);
         	}
         	
         	cache.put(key,chain);
         	lru.add(key);
         }
         else if (LazyList.size(filters) > 0)
             chain = new Chain(baseRequest,filtersservletHolder);
     
         return chain;
     }
     
     /* ------------------------------------------------------------ */
     private void invalidateChainsCache()
     {
         if ([.]!=null)
         {
             [.].clear();
             [.].clear();
             [.].clear();
             [.].clear();
             [.].clear();
 
             [.].clear();
             [.].clear();
             [.].clear();
             [.].clear();
             [.].clear();
         }
     }
 
     /* ------------------------------------------------------------ */
    

Returns:
true if the handler is started and there are no unavailable servlets
 
     public boolean isAvailable()
     {
         if (!isStarted())
             return false;
         ServletHolder[] holders = getServlets();
         for (int i=0;i<holders.length;i++)
         {
             ServletHolder holder = holders[i];
             if (holder!=null && !holder.isAvailable())
                 return false;
         }
         return true;
     }
     
     /* ------------------------------------------------------------ */
    

Parameters:
start True if this handler will start with unavailable servlets
 
     public void setStartWithUnavailable(boolean start)
     {
         =start;
     }
     
     /* ------------------------------------------------------------ */
    

Returns:
True if this handler will start with unavailable servlets
 
     public boolean isStartWithUnavailable()
     {
         return ;
     }
     
     
     
     /* ------------------------------------------------------------ */
    
Initialize filters and load-on-startup servlets. Called automatically from start if autoInitializeServlet is true.
 
     public void initialize()
         throws Exception
     {
         MultiException mx = new MultiException();
 
         // Start filters
         if (!=null)
         {
             for (int i=0;i<.i++)
                 [i].start();
         }
         
         if (!=null)
         {
             // Sort and Initialize servlets
             ServletHolder[] servlets = (ServletHolder[]).clone();
             Arrays.sort(servlets);
             for (int i=0; i<servlets.lengthi++)
             {
                 try
                 {
                     if (servlets[i].getClassName()==null && servlets[i].getForcedPath()!=null)
                     {
                         ServletHolder forced_holder = (ServletHolder).match(servlets[i].getForcedPath());
                         if (forced_holder==null || forced_holder.getClassName()==null)
                         {    
                             mx.add(new IllegalStateException("No forced path servlet for "+servlets[i].getForcedPath()));
                             continue;
                         }
                         servlets[i].setClassName(forced_holder.getClassName());
                     }
                     
                     servlets[i].start();
                 }
                 catch(Throwable e)
                 {
                     .debug(.,e);
                     mx.add(e);
                 }
             } 
             mx.ifExceptionThrow();  
         }
     }
     
     /* ------------------------------------------------------------ */
    

Returns:
Returns the filterChainsCached.
 
     public boolean isFilterChainsCached()
     {
         return ;
     }
 
     /* ------------------------------------------------------------ */
    
see also newServletHolder(Class)
 
     public ServletHolder newServletHolder(Holder.Source source)
     {
         return new ServletHolder(source);
     }
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a servlet Holder. public ServletHolder newServletHolder(Class<? extends Servlet> servlet) { return new ServletHolder(servlet); } /* ------------------------------------------------------------
 
    
Convenience method to add a servlet.

Returns:
The servlet holder.
 
     public ServletHolder addServletWithMapping (String className,String pathSpec)
     {
         ServletHolder holder = newServletHolder(null);
         holder.setName(className+"-"+LazyList.size());
         holder.setClassName(className);
         addServletWithMapping(holder,pathSpec);
         return holder;
     }   
     
     /* ------------------------------------------------------------ */
    
conveniance method to add a servlet.

Returns:
The servlet holder.
 
     public ServletHolder addServletWithMapping (Class<? extends Servletservlet,String pathSpec)
     {
         ServletHolder holder = newServletHolder(..);
         holder.setHeldClass(servlet);
         setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holderServletHolder.class));
         addServletWithMapping(holder,pathSpec);
         
         return holder;
     }   
     
     /* ------------------------------------------------------------ */
    
conveniance method to add a servlet.

Parameters:
servlet servlet holder to add
pathSpec servlet mappings for the servletHolder
 
     public void addServletWithMapping (ServletHolder servlet,String pathSpec)
     {
         ServletHolder[] holders=getServlets();
         if (holders!=null)
             holders = holders.clone();
         
         try
         {
             setServlets((ServletHolder[])LazyList.addToArray(holdersservletServletHolder.class));
             
             ServletMapping mapping = new ServletMapping();
             mapping.setServletName(servlet.getName());
             mapping.setPathSpec(pathSpec);
             setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mappingServletMapping.class));
         }
         catch (Exception e)
         {
             setServlets(holders);
             if (e instanceof RuntimeException)
                 throw (RuntimeException)e;
             throw new RuntimeException(e);
         }
     }
 
     
     /* ------------------------------------------------------------ */    
    
Convenience method to add a pre-constructed ServletHolder.

Parameters:
holder
 
     public void addServlet(ServletHolder holder)
     {
         setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holderServletHolder.class));
     }
     
     /* ------------------------------------------------------------ */    
    
Convenience method to add a pre-constructed ServletMapping.

Parameters:
mapping
 
     public void addServletMapping (ServletMapping mapping)
     {
         setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mappingServletMapping.class));
     }
 
     public Set<String>  setServletSecurity(ServletRegistration.Dynamic registrationServletSecurityElement servletSecurityElement) {
         if ( != null) {
             return .setServletSecurity(registrationservletSecurityElement);
         }
         return Collections.emptySet();
     }
 
     /* ------------------------------------------------------------ */
    
 
     public FilterHolder newFilterHolder(Holder.Source source)
     {
         return new FilterHolder(source);
     }
 
     /* ------------------------------------------------------------ */
     public FilterHolder getFilter(String name)
     {
         return (FilterHolder).get(name);
     }
 
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a filter.

Parameters:
filter class of filter to create
pathSpec filter mappings for filter
dispatches see FilterMapping.setDispatches(int)
Returns:
The filter holder.
 
     public FilterHolder addFilterWithMapping (Class<? extends Filterfilter,String pathSpec,EnumSet<DispatcherTypedispatches)
     {
         FilterHolder holder = newFilterHolder(..);
         holder.setHeldClass(filter);
         addFilterWithMapping(holder,pathSpec,dispatches);
         
         return holder;
     }
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a filter.

Parameters:
className of filter
pathSpec filter mappings for filter
dispatches see FilterMapping.setDispatches(int)
Returns:
The filter holder.
 
     public FilterHolder addFilterWithMapping (String className,String pathSpec,EnumSet<DispatcherTypedispatches)
     {
         FilterHolder holder = newFilterHolder(..);
         holder.setName(className+"-"+.);
         holder.setClassName(className);
         
         addFilterWithMapping(holder,pathSpec,dispatches);
         return holder;
     }
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a filter.

Parameters:
holder filter holder to add
pathSpec filter mappings for filter
dispatches see FilterMapping.setDispatches(int)
 
     public void addFilterWithMapping (FilterHolder holder,String pathSpec,EnumSet<DispatcherTypedispatches)
     {
         FilterHolder[] holders = getFilters();
         if (holders!=null)
             holders = (FilterHolder[])holders.clone();
         
         try
         {
             setFilters((FilterHolder[])LazyList.addToArray(holdersholderFilterHolder.class));
             
             FilterMapping mapping = new FilterMapping();
             mapping.setFilterName(holder.getName());
             mapping.setPathSpec(pathSpec);
             mapping.setDispatcherTypes(dispatches);
             //setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
             addFilterMapping(mapping);
             
         }
         catch (RuntimeException e)
         {
             setFilters(holders);
             throw e;
         }
         catch (Error e)
         {
             setFilters(holders);
             throw e;
         }
             
     }
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a filter.

Parameters:
filter class of filter to create
pathSpec filter mappings for filter
dispatches see FilterMapping.setDispatches(int)
Returns:
The filter holder.
 
     public FilterHolder addFilterWithMapping (Class<? extends Filterfilter,String pathSpec,int dispatches)
     {
         FilterHolder holder = newFilterHolder(..);
         holder.setHeldClass(filter);
         addFilterWithMapping(holder,pathSpec,dispatches);
         
         return holder;
     }
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a filter.

Parameters:
className of filter
pathSpec filter mappings for filter
dispatches see FilterMapping.setDispatches(int)
Returns:
The filter holder.
 
     public FilterHolder addFilterWithMapping (String className,String pathSpec,int dispatches)
     {
         FilterHolder holder = newFilterHolder(null);
         holder.setName(className+"-"+.);
         holder.setClassName(className);
         
         addFilterWithMapping(holder,pathSpec,dispatches);
         return holder;
     }
     
     /* ------------------------------------------------------------ */
    
Convenience method to add a filter.

Parameters:
holder filter holder to add
pathSpec filter mappings for filter
dispatches see FilterMapping.setDispatches(int)
 
     public void addFilterWithMapping (FilterHolder holder,String pathSpec,int dispatches)
     {
         FilterHolder[] holders = getFilters();
         if (holders!=null)
             holders = (FilterHolder[])holders.clone();
         
         try
         {
             setFilters((FilterHolder[])LazyList.addToArray(holdersholderFilterHolder.class));
             
             FilterMapping mapping = new FilterMapping();
             mapping.setFilterName(holder.getName());
             mapping.setPathSpec(pathSpec);
             mapping.setDispatches(dispatches);
            //setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
            addFilterMapping(mapping);
        }
        catch (RuntimeException e)
        {
            setFilters(holders);
            throw e;
        }
        catch (Error e)
        {
            setFilters(holders);
            throw e;
        }
            
    }
    
    /* ------------------------------------------------------------ */
    
Convenience method to add a filter with a mapping

Deprecated:
use addFilterWithMapping(Class, String, EnumSet<DispatcherType>) instead
Parameters:
className
pathSpec
dispatches
Returns:
the filter holder created
    public FilterHolder addFilter (String className,String pathSpec,EnumSet<DispatcherTypedispatches)
    {
        return addFilterWithMapping(classNamepathSpecdispatches);
    }
    
    /* ------------------------------------------------------------ */
    
convenience method to add a filter and mapping

Parameters:
filter
filterMapping
    public void addFilter (FilterHolder filterFilterMapping filterMapping)
    {
        if (filter != null)
            setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filterFilterHolder.class));
        if (filterMapping != null)
            //setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), filterMapping, FilterMapping.class));
            addFilterMapping(filterMapping);
    }
    
    /* ------------------------------------------------------------ */  
    
Convenience method to add a preconstructed FilterHolder

Parameters:
filter
    public void addFilter (FilterHolder filter)
    {
        if (filter != null)
            setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filterFilterHolder.class));
    }
    
    /* ------------------------------------------------------------ */
    
Convenience method to add a preconstructed FilterMapping

Parameters:
mapping
    public void addFilterMapping (FilterMapping mapping)
    {
        if (mapping != null)
        { 
            Source source = (mapping.getFilterHolder()==null?null:mapping.getFilterHolder().getSource());
            FilterMapping[] mappings =getFilterMappings();
            if (mappings==null || mappings.length==0)
            {
                setFilterMappings(insertFilterMapping(mapping,0,false));
                if (source != null && source == .)
                     = 0;
            }
            else
            {
                //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), 
                //but before the first matchAfter filtermapping.
                if (source != null && . == source)
                {
                    setFilterMappings(insertFilterMapping(mapping,mappings.length-1, false));
                    if ( < 0)
                         = getFilterMappings().length-1;
                }
                else
                {
                    //insert non-programmatic filter mappings before any matchAfters, if any
                    if ( < 0)
                        setFilterMappings(insertFilterMapping(mapping,mappings.length-1, false));
                    else
                    {
                        FilterMapping[] new_mappings = insertFilterMapping(mappingtrue);
                        ++;
                        setFilterMappings(new_mappings);
                    }
                }
            }
        }
    }
    
    
    /* ------------------------------------------------------------ */
    
Convenience method to add a preconstructed FilterMapping

Parameters:
mapping
    public void prependFilterMapping (FilterMapping mapping)
    {
        if (mapping != null)
        {
            Source source = mapping.getFilterHolder().getSource();
            
            FilterMapping[] mappings = getFilterMappings();
            if (mappings==null || mappings.length==0)
            {
                setFilterMappings(insertFilterMapping(mapping, 0, false));
                if (source != null && . == source)
                     = 0;
            }
            else
            {
                if (source != null && . == source)
</