View Javadoc
1   /*
2    * Copyright 2002-2012 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.web.servlet.handler;
18  
19  import org.springframework.util.PathMatcher;
20  import org.springframework.web.context.request.WebRequestInterceptor;
21  import org.springframework.web.servlet.HandlerInterceptor;
22  
23  /**
24   * Contains a {@link HandlerInterceptor} along with include (and optionally
25   * exclude) path patterns to which the interceptor should apply. Also provides
26   * matching logic to test if the interceptor applies to a given request path.
27   *
28   * <p>A MappedInterceptor can be registered directly with any
29   * {@link org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
30   * AbstractHandlerMethodMapping}. Furthermore, beans of type MappedInterceptor
31   * are automatically detected by {@code AbstractHandlerMethodMapping} (including
32   * ancestor ApplicationContext's) which effectively means the interceptor is
33   * registered "globally" with all handler mappings.
34   *
35   * @author Keith Donald
36   * @author Rossen Stoyanchev
37   * @since 3.0
38   */
39  public final class MappedInterceptor {
40  
41  	private final String[] includePatterns;
42  
43  	private final String[] excludePatterns;
44  
45  	private final HandlerInterceptor interceptor;
46  
47  	private PathMatcher pathMatcher;
48  
49  
50  	/**
51  	 * Create a new MappedInterceptor instance.
52  	 * @param includePatterns the path patterns to map with a {@code null} value matching to all paths
53  	 * @param interceptor the HandlerInterceptor instance to map to the given patterns
54  	 */
55  	public MappedInterceptor(String[] includePatterns, HandlerInterceptor interceptor) {
56  		this(includePatterns, null, interceptor);
57  	}
58  
59  	/**
60  	 * Create a new MappedInterceptor instance.
61  	 * @param includePatterns the path patterns to map with a {@code null} value matching to all paths
62  	 * @param excludePatterns the path patterns to exclude
63  	 * @param interceptor the HandlerInterceptor instance to map to the given patterns
64  	 */
65  	public MappedInterceptor(String[] includePatterns, String[] excludePatterns, HandlerInterceptor interceptor) {
66  		this.includePatterns = includePatterns;
67  		this.excludePatterns = excludePatterns;
68  		this.interceptor = interceptor;
69  	}
70  
71  
72  	/**
73  	 * Create a new MappedInterceptor instance.
74  	 * @param includePatterns the path patterns to map with a {@code null} value matching to all paths
75  	 * @param interceptor the WebRequestInterceptor instance to map to the given patterns
76  	 */
77  	public MappedInterceptor(String[] includePatterns, WebRequestInterceptor interceptor) {
78  		this(includePatterns, null, interceptor);
79  	}
80  
81  	/**
82  	 * Create a new MappedInterceptor instance.
83  	 * @param includePatterns the path patterns to map with a {@code null} value matching to all paths
84  	 * @param interceptor the WebRequestInterceptor instance to map to the given patterns
85  	 */
86  	public MappedInterceptor(String[] includePatterns, String[] excludePatterns, WebRequestInterceptor interceptor) {
87  		this(includePatterns, excludePatterns, new WebRequestHandlerInterceptorAdapter(interceptor));
88  	}
89  
90  
91  	/**
92  	 * Configure a PathMatcher to use with this MappedInterceptor instead of the
93  	 * one passed by default to the {@link #matches(String, org.springframework.util.PathMatcher)}
94  	 * method. This is an advanced property that is only required when using custom
95  	 * PathMatcher implementations that support mapping metadata other than the
96  	 * Ant-style path patterns supported by default.
97  	 *
98  	 * @param pathMatcher the path matcher to use
99  	 */
100 	public void setPathMatcher(PathMatcher pathMatcher) {
101 		this.pathMatcher = pathMatcher;
102 	}
103 
104 	/**
105 	 * The configured PathMatcher, or {@code null}.
106 	 */
107 	public PathMatcher getPathMatcher() {
108 		return this.pathMatcher;
109 	}
110 
111 	/**
112 	 * The path into the application the interceptor is mapped to.
113 	 */
114 	public String[] getPathPatterns() {
115 		return this.includePatterns;
116 	}
117 
118 	/**
119 	 * The actual Interceptor reference.
120 	 */
121 	public HandlerInterceptor getInterceptor() {
122 		return this.interceptor;
123 	}
124 
125 	/**
126 	 * Returns {@code true} if the interceptor applies to the given request path.
127 	 * @param lookupPath the current request path
128 	 * @param pathMatcher a path matcher for path pattern matching
129 	 */
130 	public boolean matches(String lookupPath, PathMatcher pathMatcher) {
131 		PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher;
132 		if (this.excludePatterns != null) {
133 			for (String pattern : this.excludePatterns) {
134 				if (pathMatcherToUse.match(pattern, lookupPath)) {
135 					return false;
136 				}
137 			}
138 		}
139 		if (this.includePatterns == null) {
140 			return true;
141 		}
142 		else {
143 			for (String pattern : this.includePatterns) {
144 				if (pathMatcherToUse.match(pattern, lookupPath)) {
145 					return true;
146 				}
147 			}
148 			return false;
149 		}
150 	}
151 }