Coverage Report - org.apache.shiro.web.servlet.AdviceFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
AdviceFilter
5%
2/40
0%
0/18
3.333
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.shiro.web.servlet;
 20  
 
 21  
 import org.slf4j.Logger;
 22  
 import org.slf4j.LoggerFactory;
 23  
 
 24  
 import javax.servlet.FilterChain;
 25  
 import javax.servlet.ServletException;
 26  
 import javax.servlet.ServletRequest;
 27  
 import javax.servlet.ServletResponse;
 28  
 import java.io.IOException;
 29  
 
 30  
 /**
 31  
  * A Servlet Filter that enables AOP-style "around" advice for a ServletRequest via
 32  
  * {@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) preHandle},
 33  
  * {@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) postHandle},
 34  
  * and {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
 35  
  * hooks.
 36  
  *
 37  
  * @since 0.9
 38  
  */
 39  542
 public abstract class AdviceFilter extends OncePerRequestFilter {
 40  
 
 41  
     /**
 42  
      * The static logger available to this class only
 43  
      */
 44  1
     private static final Logger log = LoggerFactory.getLogger(AdviceFilter.class);
 45  
 
 46  
     /**
 47  
      * Returns {@code true} if the filter chain should be allowed to continue, {@code false} otherwise.
 48  
      * It is called before the chain is actually consulted/executed.
 49  
      * <p/>
 50  
      * The default implementation returns {@code true} always and exists as a template method for subclasses.
 51  
      *
 52  
      * @param request  the incoming ServletRequest
 53  
      * @param response the outgoing ServletResponse
 54  
      * @return {@code true} if the filter chain should be allowed to continue, {@code false} otherwise.
 55  
      * @throws Exception if there is any error.
 56  
      */
 57  
     protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
 58  0
         return true;
 59  
     }
 60  
 
 61  
     /**
 62  
      * Allows 'post' advice logic to be called, but only if no exception occurs during filter chain execution.  That
 63  
      * is, if {@link #executeChain executeChain} throws an exception, this method will never be called.  Be aware of
 64  
      * this when implementing logic.  Most resource 'cleanup' behavior is often done in the
 65  
      * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion(request,response,exception)}
 66  
      * implementation, which is guaranteed to be called for every request, even when the chain processing throws
 67  
      * an Exception.
 68  
      * <p/>
 69  
      * The default implementation does nothing (no-op) and exists as a template method for subclasses.
 70  
      *
 71  
      * @param request  the incoming ServletRequest
 72  
      * @param response the outgoing ServletResponse
 73  
      * @throws Exception if an error occurs.
 74  
      */
 75  
     @SuppressWarnings({"UnusedDeclaration"})
 76  
     protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
 77  0
     }
 78  
 
 79  
     /**
 80  
      * Called in all cases in a {@code finally} block even if {@link #preHandle preHandle} returns
 81  
      * {@code false} or if an exception is thrown during filter chain processing.  Can be used for resource
 82  
      * cleanup if so desired.
 83  
      * <p/>
 84  
      * The default implementation does nothing (no-op) and exists as a template method for subclasses.
 85  
      *
 86  
      * @param request   the incoming ServletRequest
 87  
      * @param response  the outgoing ServletResponse
 88  
      * @param exception any exception thrown during {@link #preHandle preHandle}, {@link #executeChain executeChain},
 89  
      *                  or {@link #postHandle postHandle} execution, or {@code null} if no exception was thrown
 90  
      *                  (i.e. the chain processed successfully).
 91  
      * @throws Exception if an error occurs.
 92  
      */
 93  
     @SuppressWarnings({"UnusedDeclaration"})
 94  
     public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
 95  0
     }
 96  
 
 97  
     /**
 98  
      * Actually executes the specified filter chain by calling <code>chain.doFilter(request,response);</code>.
 99  
      * <p/>
 100  
      * Can be overridden by subclasses for custom logic.
 101  
      *
 102  
      * @param request  the incoming ServletRequest
 103  
      * @param response the outgoing ServletResponse
 104  
      * @param chain    the filter chain to execute
 105  
      * @throws Exception if there is any error executing the chain.
 106  
      */
 107  
     protected void executeChain(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
 108  0
         chain.doFilter(request, response);
 109  0
     }
 110  
 
 111  
     /**
 112  
      * Actually implements the chain execution logic, utilizing
 113  
      * {@link #preHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) pre},
 114  
      * {@link #postHandle(javax.servlet.ServletRequest, javax.servlet.ServletResponse) post}, and
 115  
      * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) after}
 116  
      * advice hooks.
 117  
      *
 118  
      * @param request  the incoming ServletRequest
 119  
      * @param response the outgoing ServletResponse
 120  
      * @param chain    the filter chain to execute
 121  
      * @throws ServletException if a servlet-related error occurs
 122  
      * @throws IOException      if an IO error occurs
 123  
      */
 124  
     public void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
 125  
             throws ServletException, IOException {
 126  
 
 127  0
         Exception exception = null;
 128  
 
 129  
         try {
 130  
 
 131  0
             boolean continueChain = preHandle(request, response);
 132  0
             if (log.isTraceEnabled()) {
 133  0
                 log.trace("Invoked preHandle method.  Continuing chain?: [" + continueChain + "]");
 134  
             }
 135  
 
 136  0
             if (continueChain) {
 137  0
                 executeChain(request, response, chain);
 138  
             }
 139  
 
 140  0
             postHandle(request, response);
 141  0
             if (log.isTraceEnabled()) {
 142  0
                 log.trace("Successfully invoked postHandle method");
 143  
             }
 144  
 
 145  0
         } catch (Exception e) {
 146  0
             exception = e;
 147  
         } finally {
 148  0
             cleanup(request, response, exception);
 149  0
         }
 150  0
     }
 151  
 
 152  
     /**
 153  
      * Executes cleanup logic in the {@code finally} code block in the
 154  
      * {@link #doFilterInternal(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) doFilterInternal}
 155  
      * implementation.
 156  
      * <p/>
 157  
      * This implementation specifically calls
 158  
      * {@link #afterCompletion(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Exception) afterCompletion}
 159  
      * as well as handles any exceptions properly.
 160  
      *
 161  
      * @param request  the incoming {@code ServletRequest}
 162  
      * @param response the outgoing {@code ServletResponse}
 163  
      * @param existing any exception that might have occurred while executing the {@code FilterChain} or
 164  
      *                 pre or post advice, or {@code null} if the pre/chain/post execution did not throw an {@code Exception}.
 165  
      * @throws ServletException if any exception other than an {@code IOException} is thrown.
 166  
      * @throws IOException      if the pre/chain/post execution throw an {@code IOException}
 167  
      */
 168  
     protected void cleanup(ServletRequest request, ServletResponse response, Exception existing)
 169  
             throws ServletException, IOException {
 170  0
         Exception exception = existing;
 171  
         try {
 172  0
             afterCompletion(request, response, exception);
 173  0
             if (log.isTraceEnabled()) {
 174  0
                 log.trace("Successfully invoked afterCompletion method.");
 175  
             }
 176  0
         } catch (Exception e) {
 177  0
             if (exception == null) {
 178  0
                 exception = e;
 179  
             } else {
 180  0
                 log.debug("afterCompletion implementation threw an exception.  This will be ignored to " +
 181  
                         "allow the original source exception to be propagated.", e);
 182  
             }
 183  0
         }
 184  0
         if (exception != null) {
 185  0
             if (exception instanceof ServletException) {
 186  0
                 throw (ServletException) exception;
 187  0
             } else if (exception instanceof IOException) {
 188  0
                 throw (IOException) exception;
 189  
             } else {
 190  0
                 if (log.isDebugEnabled()) {
 191  0
                     String msg = "Filter execution resulted in an unexpected Exception " +
 192  
                             "(not IOException or ServletException as the Filter API recommends).  " +
 193  
                             "Wrapping in ServletException and propagating.";
 194  0
                     log.debug(msg);
 195  
                 }
 196  0
                 throw new ServletException(exception);
 197  
             }
 198  
         }
 199  0
     }
 200  
 }