View Javadoc
1   /*
2    * Copyright 2002-2014 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.mvc.condition;
18  
19  import java.util.Arrays;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.LinkedHashSet;
23  import java.util.List;
24  import java.util.Set;
25  import javax.servlet.http.HttpServletRequest;
26  
27  import org.springframework.web.bind.annotation.RequestMethod;
28  
29  /**
30   * A logical disjunction (' || ') request condition that matches a request
31   * against a set of {@link RequestMethod}s.
32   *
33   * @author Arjen Poutsma
34   * @author Rossen Stoyanchev
35   * @since 3.1
36   */
37  public final class RequestMethodsRequestCondition extends AbstractRequestCondition<RequestMethodsRequestCondition> {
38  
39  	private final Set<RequestMethod> methods;
40  
41  
42  	/**
43  	 * Create a new instance with the given request methods.
44  	 * @param requestMethods 0 or more HTTP request methods;
45  	 * if, 0 the condition will match to every request
46  	 */
47  	public RequestMethodsRequestCondition(RequestMethod... requestMethods) {
48  		this(asList(requestMethods));
49  	}
50  
51  	private RequestMethodsRequestCondition(Collection<RequestMethod> requestMethods) {
52  		this.methods = Collections.unmodifiableSet(new LinkedHashSet<RequestMethod>(requestMethods));
53  	}
54  
55  
56  	private static List<RequestMethod> asList(RequestMethod... requestMethods) {
57  		return (requestMethods != null ? Arrays.asList(requestMethods) : Collections.<RequestMethod>emptyList());
58  	}
59  
60  
61  	/**
62  	 * Returns all {@link RequestMethod}s contained in this condition.
63  	 */
64  	public Set<RequestMethod> getMethods() {
65  		return this.methods;
66  	}
67  
68  	@Override
69  	protected Collection<RequestMethod> getContent() {
70  		return this.methods;
71  	}
72  
73  	@Override
74  	protected String getToStringInfix() {
75  		return " || ";
76  	}
77  
78  	/**
79  	 * Returns a new instance with a union of the HTTP request methods
80  	 * from "this" and the "other" instance.
81  	 */
82  	@Override
83  	public RequestMethodsRequestCondition combine(RequestMethodsRequestCondition other) {
84  		Set<RequestMethod> set = new LinkedHashSet<RequestMethod>(this.methods);
85  		set.addAll(other.methods);
86  		return new RequestMethodsRequestCondition(set);
87  	}
88  
89  	/**
90  	 * Check if any of the HTTP request methods match the given request and
91  	 * return an instance that contains the matching HTTP request method only.
92  	 * @param request the current request
93  	 * @return the same instance if the condition is empty, a new condition with
94  	 * the matched request method, or {@code null} if no request methods match
95  	 */
96  	@Override
97  	public RequestMethodsRequestCondition getMatchingCondition(HttpServletRequest request) {
98  		if (this.methods.isEmpty()) {
99  			return this;
100 		}
101 		RequestMethod incomingRequestMethod = getRequestMethod(request);
102 		if (incomingRequestMethod != null) {
103 			for (RequestMethod method : this.methods) {
104 				if (method.equals(incomingRequestMethod)) {
105 					return new RequestMethodsRequestCondition(method);
106 				}
107 			}
108 		}
109 		return null;
110 	}
111 
112 	private RequestMethod getRequestMethod(HttpServletRequest request) {
113 		try {
114 			return RequestMethod.valueOf(request.getMethod());
115 		}
116 		catch (IllegalArgumentException ex) {
117 			return null;
118 		}
119 	}
120 
121 	/**
122 	 * Returns:
123 	 * <ul>
124 	 * <li>0 if the two conditions contain the same number of HTTP request methods
125 	 * <li>Less than 0 if "this" instance has an HTTP request method but "other" doesn't
126 	 * <li>Greater than 0 "other" has an HTTP request method but "this" doesn't
127 	 * </ul>
128 	 * <p>It is assumed that both instances have been obtained via
129 	 * {@link #getMatchingCondition(HttpServletRequest)} and therefore each instance
130 	 * contains the matching HTTP request method only or is otherwise empty.
131 	 */
132 	@Override
133 	public int compareTo(RequestMethodsRequestCondition other, HttpServletRequest request) {
134 		return (other.methods.size() - this.methods.size());
135 	}
136 
137 }