Merge "Deprecate odl-aaa-keystone feature"
[aaa.git] / aaa-filterchain / src / main / java / org / opendaylight / aaa / filterchain / filters / AAAFilterChain.java
1 /*
2  * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.aaa.filterchain.filters;
10
11 import java.io.IOException;
12 import java.util.Iterator;
13 import java.util.List;
14
15 import javax.servlet.Filter;
16 import javax.servlet.FilterChain;
17 import javax.servlet.ServletException;
18 import javax.servlet.ServletRequest;
19 import javax.servlet.ServletResponse;
20
21 /**
22  * Recreates the <code>javax.servlet.Filter</code> chain of responsibility
23  * Pattern to allow for programmatic injection of Filters.  Essentially, the
24  * links of the injected chain are traversed, and if the Requests makes it
25  * through all of the injected Filters, then the original, existing chain
26  * is maintained.
27  *
28  * This revision of code assumes that the url-pattern for injected filters
29  * is exactly the same as the one specified for <code>CustomFilterAdapter</code>.
30  *
31  * @author Ryan Goulding (ryandgoulding@gmail.com)
32  *
33  */
34 public final class AAAFilterChain implements FilterChain {
35
36     // Must be stored locally to be used within javax.servlet.FilterChain.doFilter(
37     // ServletRequest, ServletResponse) due to rigid API contract.
38     private volatile Iterator<Filter> injectedFilterChainIterator;
39     private volatile FilterChain existingFilterChain;
40
41     private AAAFilterChain() {
42     }
43
44     public static AAAFilterChain createAAAFilterChain() {
45         return new AAAFilterChain();
46     }
47
48     @Override
49     public void doFilter(final ServletRequest request, final ServletResponse response)
50             throws IOException, ServletException {
51
52         // Recursive call using the next available link in the chain iterator If a "next" link does
53         // not exist and we have traversed the chain thus far, that means the Request has successfully
54         // traversed the injected filter chain links and we can invoke filtering on the existing chain.
55         if (injectedFilterChainIterator.hasNext()) {
56             injectedFilterChainIterator.next().doFilter(request, response, this);
57         } else {
58             existingFilterChain.doFilter(request, response);
59         }
60     }
61
62     /**
63      * A wrapper method used to inject a new Filter chain.  Essentially, this just adds links to the existing chain.
64      *
65      * @param request Wrapped parameter passed directly to <code>doFilter(ServletRequest, ServletResponse)</code>
66      * @param response Wrapped parameter passed directly to <code>doFilter(ServletRequest, ServletResponse)</code>
67      * @param existingFilterChain The chain provided from Jersey as defined in the Servlet's <code>web.xml</code>
68      * @param injectedFilterChain The programmatically injected chain, which may be empty
69      * @throws IOException Wrapped exception handling from <code>doFilter(ServletRequest, ServletResponse)</code>
70      * @throws ServletException Wrapped exception handling from <code>doFilter(ServletRequest, ServletResponse)</code>
71      */
72     public void doFilter(final ServletRequest request, final ServletResponse response,
73             final FilterChain existingFilterChain, final List<Filter> injectedFilterChain)
74                     throws IOException, ServletException {
75
76         this.existingFilterChain = existingFilterChain;
77         this.injectedFilterChainIterator = injectedFilterChain.iterator();
78         doFilter(request, response);
79     }
80 }