From 9b0c66dc6cd312c681dd27548d8d79829565d002 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 11 May 2011 10:38:30 +0000 Subject: [PATCH] Make HTTP methods a RequestCondition --- .../RequestMappingHandlerMapping.java | 7 +- .../method/annotation/RequestMappingInfo.java | 67 +++----- .../condition/HeadersRequestCondition.java | 2 +- .../LogicalConjunctionRequestCondition.java | 2 +- .../LogicalDisjunctionRequestCondition.java | 3 + .../condition/ParamsRequestCondition.java | 2 +- .../condition/RequestConditionComposite.java | 4 + .../condition/RequestConditionFactory.java | 23 ++- .../RequestMethodsRequestCondition.java | 153 ++++++++++++++++++ ...=> RequestMappingInfoComparatorTests.java} | 8 +- ...ests.java => RequestMappingInfoTests.java} | 71 ++++---- .../RequestMethodsRequestConditionTests.java | 88 ++++++++++ 12 files changed, 344 insertions(+), 86 deletions(-) create mode 100644 org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java rename org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/{RequestKeyComparatorTests.java => RequestMappingInfoComparatorTests.java} (93%) rename org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/{RequestKeyTests.java => RequestMappingInfoTests.java} (86%) create mode 100644 org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestConditionTests.java diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 43a63e5c4da..9dfdf262e07 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -124,7 +124,8 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping patterns; - private final Set methods; + private final RequestMethodsRequestCondition methodsCondition; private final ParamsRequestCondition paramsCondition; @@ -62,20 +64,20 @@ public final class RequestMappingInfo { * *

Package protected for testing purposes. */ - RequestMappingInfo(Collection patterns, Collection methods) { - this(patterns, methods, null, null, null); + RequestMappingInfo(Collection patterns, RequestMethod[] methods) { + this(patterns, RequestConditionFactory.parseMethods(methods), null, null, null); } /** * Creates a new {@code RequestMappingInfo} instance with a full set of conditions. */ public RequestMappingInfo(Collection patterns, - Collection methods, + RequestMethodsRequestCondition methodsCondition, ParamsRequestCondition paramsCondition, HeadersRequestCondition headersCondition, ConsumesRequestCondition consumesCondition) { this.patterns = asUnmodifiableSet(prependLeadingSlash(patterns)); - this.methods = asUnmodifiableSet(methods); + this.methodsCondition = methodsCondition != null ? methodsCondition : new RequestMethodsRequestCondition(); this.paramsCondition = paramsCondition != null ? paramsCondition : new ParamsRequestCondition(); this.headersCondition = headersCondition != null ? headersCondition : new HeadersRequestCondition(); this.consumesCondition = consumesCondition != null ? consumesCondition : new ConsumesRequestCondition(); @@ -111,10 +113,10 @@ public final class RequestMappingInfo { } /** - * Returns the request methods of this request key. + * Returns the request method conditions of this request key. */ - public Set getMethods() { - return methods; + public RequestMethodsRequestCondition getMethods() { + return methodsCondition; } /** @@ -158,7 +160,7 @@ public final class RequestMappingInfo { */ public RequestMappingInfo combine(RequestMappingInfo methodKey, PathMatcher pathMatcher) { Set patterns = combinePatterns(this.patterns, methodKey.patterns, pathMatcher); - Set methods = union(this.methods, methodKey.methods); + RequestMethodsRequestCondition methods = this.methodsCondition.combine(methodKey.methodsCondition); ParamsRequestCondition params = this.paramsCondition.combine(methodKey.paramsCondition); HeadersRequestCondition headers = this.headersCondition.combine(methodKey.headersCondition); ConsumesRequestCondition consumes = this.consumesCondition.combine(methodKey.consumesCondition); @@ -189,12 +191,6 @@ public final class RequestMappingInfo { return result; } - private static Set union(Collection s1, Collection s2) { - Set union = new LinkedHashSet(s1); - union.addAll(s2); - return union; - } - /** * Returns a new {@code RequestMappingInfo} that contains all conditions of this key that are relevant to the request. *

    @@ -210,19 +206,19 @@ public final class RequestMappingInfo { * @return a new request key that contains all matching attributes, or {@code null} if not all conditions match */ public RequestMappingInfo getMatchingRequestMapping(String lookupPath, HttpServletRequest request, PathMatcher pathMatcher) { + RequestMethodsRequestCondition matchingMethodCondition = methodsCondition.getMatchingCondition(request); ParamsRequestCondition matchingParamsCondition = paramsCondition.getMatchingCondition(request); HeadersRequestCondition matchingHeadersCondition = headersCondition.getMatchingCondition(request); ConsumesRequestCondition matchingConsumesCondition = consumesCondition.getMatchingCondition(request); - if (!checkMethod(request) || matchingParamsCondition == null || matchingHeadersCondition == null || + if (matchingMethodCondition == null || matchingParamsCondition == null || matchingHeadersCondition == null || matchingConsumesCondition == null) { return null; } else { - List matchingPatterns = getMatchingPatterns(lookupPath, request, pathMatcher); + List matchingPatterns = getMatchingPatterns(lookupPath, pathMatcher); if (!matchingPatterns.isEmpty()) { - Set matchingMethods = getMatchingMethod(request); - return new RequestMappingInfo(matchingPatterns, matchingMethods, matchingParamsCondition, + return new RequestMappingInfo(matchingPatterns, matchingMethodCondition, matchingParamsCondition, matchingHeadersCondition, matchingConsumesCondition); } else { @@ -231,9 +227,7 @@ public final class RequestMappingInfo { } } - private List getMatchingPatterns(String lookupPath, - HttpServletRequest request, - PathMatcher pathMatcher) { + private List getMatchingPatterns(String lookupPath, PathMatcher pathMatcher) { List matchingPatterns = new ArrayList(); for (String pattern : this.patterns) { @@ -248,19 +242,6 @@ public final class RequestMappingInfo { return matchingPatterns; } - private Set getMatchingMethod(HttpServletRequest request) { - if (this.methods.isEmpty()) { - return this.methods; - } - else { - return Collections.singleton(RequestMethod.valueOf(request.getMethod())); - } - } - - private boolean checkMethod(HttpServletRequest request) { - return methods.isEmpty() || methods.contains(RequestMethod.valueOf(request.getMethod())); - } - private String getMatchingPattern(String pattern, String lookupPath, PathMatcher pathMatcher) { if (pattern.equals(lookupPath)) { return pattern; @@ -286,7 +267,8 @@ public final class RequestMappingInfo { } if (obj != null && obj instanceof RequestMappingInfo) { RequestMappingInfo other = (RequestMappingInfo) obj; - return (this.patterns.equals(other.patterns) && this.methods.equals(other.methods) && + return (this.patterns.equals(other.patterns) && + this.methodsCondition.equals(other.methodsCondition) && this.paramsCondition.equals(other.paramsCondition) && this.headersCondition.equals(other.headersCondition) && this.consumesCondition.equals(other.consumesCondition)); @@ -299,7 +281,7 @@ public final class RequestMappingInfo { int result = hash; if (result == 0) { result = patterns.hashCode(); - result = 31 * result + methods.hashCode(); + result = 31 * result + methodsCondition.hashCode(); result = 31 * result + paramsCondition.hashCode(); result = 31 * result + headersCondition.hashCode(); result = 31 * result + consumesCondition.hashCode(); @@ -312,13 +294,10 @@ public final class RequestMappingInfo { public String toString() { StringBuilder builder = new StringBuilder("{"); builder.append(patterns); - if (!methods.isEmpty()) { - builder.append(','); - builder.append(methods); - } - builder.append(",params=").append(paramsCondition.toString()); - builder.append(",headers=").append(headersCondition.toString()); - builder.append(",consumes=").append(consumesCondition.toString()); + builder.append(",methods=").append(methodsCondition); + builder.append(",params=").append(paramsCondition); + builder.append(",headers=").append(headersCondition); + builder.append(",consumes=").append(consumesCondition); builder.append('}'); return builder.toString(); } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java index fbe4bdfa786..bb41c829098 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/HeadersRequestCondition.java @@ -59,7 +59,7 @@ public class HeadersRequestCondition } /** - * Returns a new {@code RequestCondition} that contains all conditions of this key that match the request. + * Returns a new {@code RequestCondition} that contains all conditions that match the request. * * @param request the request * @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalConjunctionRequestCondition.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalConjunctionRequestCondition.java index fd8058b3f2e..7873d909628 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalConjunctionRequestCondition.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalConjunctionRequestCondition.java @@ -34,7 +34,7 @@ class LogicalConjunctionRequestCondition extends Req public boolean match(HttpServletRequest request) { Set conditions = getConditions(); - if (conditions.isEmpty()) { + if (isEmpty()) { return true; } for (T condition : conditions) { diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalDisjunctionRequestCondition.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalDisjunctionRequestCondition.java index a4e5e653c57..e775a76c96a 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalDisjunctionRequestCondition.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/LogicalDisjunctionRequestCondition.java @@ -32,6 +32,9 @@ class LogicalDisjunctionRequestCondition extends Req } public boolean match(HttpServletRequest request) { + if (isEmpty()) { + return true; + } for (RequestCondition condition : getConditions()) { if (condition.match(request)) { return true; diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java index e3f6b5fb940..fba088f8ed7 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/ParamsRequestCondition.java @@ -62,7 +62,7 @@ public class ParamsRequestCondition } /** - * Returns a new {@code RequestCondition} that contains all conditions of this key that match the request. + * Returns a new {@code RequestCondition} that contains all conditions that match the request. * * @param request the request * @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionComposite.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionComposite.java index 7d1816bb42c..319ab9917cd 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionComposite.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionComposite.java @@ -40,6 +40,10 @@ abstract class RequestConditionComposite implements return conditions; } + boolean isEmpty() { + return conditions.isEmpty(); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java index f05a9428b22..461d48dc21b 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestConditionFactory.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Set; import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMethod; /** * Factory for {@link RequestCondition} objects. @@ -38,14 +39,25 @@ public abstract class RequestConditionFactory { private static final String ACCEPT_HEADER = "Accept"; /** - * Parses the given parameters, and returns them as a single request conditions. + * Parses the given request methods, and returns them as a single request condition. + * + * @param methods the methods + * @return the request condition + * @see org.springframework.web.bind.annotation.RequestMapping#method() + */ + public static RequestMethodsRequestCondition parseMethods(RequestMethod... methods) { + return methods != null ? new RequestMethodsRequestCondition(methods) : new RequestMethodsRequestCondition(); + } + + /** + * Parses the given parameters, and returns them as a single request condition. * * @param params the parameters * @return the request condition * @see org.springframework.web.bind.annotation.RequestMapping#params() */ public static ParamsRequestCondition parseParams(String... params) { - return new ParamsRequestCondition(params); + return params != null ? new ParamsRequestCondition(params) : new ParamsRequestCondition(); } /** @@ -56,6 +68,9 @@ public abstract class RequestConditionFactory { * @see org.springframework.web.bind.annotation.RequestMapping#headers() */ public static HeadersRequestCondition parseHeaders(String... headers) { + if (headers == null) { + return new HeadersRequestCondition(); + } HeadersRequestCondition headersCondition = new HeadersRequestCondition(headers); // filter out Accept and Content-Type headers, they are dealt with by produces and consumes respectively @@ -107,8 +122,8 @@ public abstract class RequestConditionFactory { if (CONTENT_TYPE_HEADER.equalsIgnoreCase(headerCondition.name)) { List mediaTypes = MediaType.parseMediaTypes(headerCondition.value); for (MediaType mediaType : mediaTypes) { - allConditions.add( - new ConsumesRequestCondition.ConsumeRequestCondition(mediaType, headerCondition.isNegated)); + allConditions.add(new ConsumesRequestCondition.ConsumeRequestCondition(mediaType, + headerCondition.isNegated)); } } } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java new file mode 100644 index 00000000000..4a851567b8c --- /dev/null +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestCondition.java @@ -0,0 +1,153 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.mvc.method.condition; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Represents a collection of {@link RequestMethod} conditions, typically obtained from {@link + * org.springframework.web.bind.annotation.RequestMapping#method() @RequestMapping.methods()}. + * + * @author Arjen Poutsma + * @see RequestConditionFactory#parseMethods(RequestMethod...) + * @since 3.1 + */ +public class RequestMethodsRequestCondition + extends LogicalDisjunctionRequestCondition + implements Comparable { + + private RequestMethodsRequestCondition(Collection conditions) { + super(conditions); + } + + RequestMethodsRequestCondition(RequestMethod... methods) { + this(parseConditions(Arrays.asList(methods))); + } + + private static Set parseConditions(List methods) { + Set conditions = + new LinkedHashSet(methods.size()); + for (RequestMethod method : methods) { + conditions.add(new RequestMethodRequestCondition(method)); + } + return conditions; + } + + + /** + * Creates an empty set of method request conditions. + */ + public RequestMethodsRequestCondition() { + this(Collections.emptySet()); + } + + /** + * Returns all {@link RequestMethod}s contained in this condition. + */ + public Set getMethods() { + Set result = new LinkedHashSet(); + for (RequestMethodRequestCondition condition : getConditions()) { + result.add(condition.getMethod()); + } + return result; + } + + public int compareTo(RequestMethodsRequestCondition other) { + return other.getConditions().size() - this.getConditions().size(); + } + + /** + * Returns a new {@code RequestMethodsRequestCondition} that contains all conditions that match the request. + * + * @param request the request + * @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match + */ + public RequestMethodsRequestCondition getMatchingCondition(HttpServletRequest request) { + if (isEmpty()) { + return this; + } + else { + if (match(request)) { + return new RequestMethodsRequestCondition(RequestMethod.valueOf(request.getMethod())); + } + else { + return null; + } + } + + } + + /** + * Combines this collection of request method conditions with another by combining all methods into a logical OR. + * + * @param other the condition to combine with + */ + public RequestMethodsRequestCondition combine(RequestMethodsRequestCondition other) { + Set conditions = + new LinkedHashSet(getConditions()); + conditions.addAll(other.getConditions()); + return new RequestMethodsRequestCondition(conditions); + } + + static class RequestMethodRequestCondition implements RequestCondition { + + private final RequestMethod method; + + RequestMethodRequestCondition(RequestMethod method) { + this.method = method; + } + + RequestMethod getMethod() { + return method; + } + + public boolean match(HttpServletRequest request) { + RequestMethod method = RequestMethod.valueOf(request.getMethod()); + return this.method.equals(method); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj != null && obj instanceof RequestMethodRequestCondition) { + RequestMethodRequestCondition other = (RequestMethodRequestCondition) obj; + return this.method.equals(other.method); + } + return false; + } + + @Override + public int hashCode() { + return method.hashCode(); + } + + @Override + public String toString() { + return method.toString(); + } + } +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyComparatorTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoComparatorTests.java similarity index 93% rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyComparatorTests.java rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoComparatorTests.java index 1264b2c4542..68e31284383 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyComparatorTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoComparatorTests.java @@ -38,7 +38,7 @@ import static org.junit.Assert.*; * @author Arjen Poutsma * @author Rossen Stoyanchev */ -public class RequestKeyComparatorTests { +public class RequestMappingInfoComparatorTests { private RequestMappingHandlerMapping handlerMapping; @@ -90,7 +90,7 @@ public class RequestKeyComparatorTests { public void oneMethodWinsOverNone() { Comparator comparator = handlerMapping.getMappingComparator("", request); RequestMappingInfo key1 = new RequestMappingInfo(null, null); - RequestMappingInfo key2 = new RequestMappingInfo(null, asList(RequestMethod.GET)); + RequestMappingInfo key2 = new RequestMappingInfo(null, new RequestMethod[] {RequestMethod.GET}); assertEquals(1, comparator.compare(key1, key2)); } @@ -98,9 +98,9 @@ public class RequestKeyComparatorTests { @Test public void methodsAndParams() { RequestMappingInfo empty = new RequestMappingInfo(null, null); - RequestMappingInfo oneMethod = new RequestMappingInfo(null, asList(RequestMethod.GET)); + RequestMappingInfo oneMethod = new RequestMappingInfo(null, new RequestMethod[] {RequestMethod.GET}); RequestMappingInfo oneMethodOneParam = - new RequestMappingInfo(null, asList(RequestMethod.GET), RequestConditionFactory.parseParams("foo"), null, null); + new RequestMappingInfo(null, RequestConditionFactory.parseMethods(RequestMethod.GET), RequestConditionFactory.parseParams("foo"), null, null); List list = asList(empty, oneMethod, oneMethodOneParam); Collections.shuffle(list); Collections.sort(list, handlerMapping.getMappingComparator("", request)); diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoTests.java similarity index 86% rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyTests.java rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoTests.java index d95b6c1c9cb..65e9bed971e 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestKeyTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingInfoTests.java @@ -16,33 +16,32 @@ package org.springframework.web.servlet.mvc.method.annotation; -import static java.util.Arrays.asList; -import static java.util.Collections.singleton; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.springframework.web.bind.annotation.RequestMethod.GET; -import static org.springframework.web.bind.annotation.RequestMethod.POST; - import org.junit.Test; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.util.AntPathMatcher; import org.springframework.util.PathMatcher; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory; import org.springframework.web.util.UrlPathHelper; +import static java.util.Arrays.*; +import static java.util.Collections.*; +import static org.junit.Assert.*; +import static org.springframework.web.bind.annotation.RequestMethod.*; + /** * Test fixture for {@link RequestMappingInfo} tests. - * + * * @author Arjen Poutsma * @author Rossen Stoyanchev */ -public class RequestKeyTests { +public class RequestMappingInfoTests { @Test public void equals() { - RequestMappingInfo key1 = new RequestMappingInfo(singleton("/foo"), singleton(GET)); - RequestMappingInfo key2 = new RequestMappingInfo(singleton("/foo"), singleton(GET)); + RequestMappingInfo key1 = new RequestMappingInfo(singleton("/foo"), methods(GET)); + RequestMappingInfo key2 = new RequestMappingInfo(singleton("/foo"), methods(GET)); assertEquals(key1, key2); assertEquals(key1.hashCode(), key2.hashCode()); @@ -50,8 +49,8 @@ public class RequestKeyTests { @Test public void equalsPrependSlash() { - RequestMappingInfo key1 = new RequestMappingInfo(singleton("/foo"), singleton(GET)); - RequestMappingInfo key2 = new RequestMappingInfo(singleton("foo"), singleton(GET)); + RequestMappingInfo key1 = new RequestMappingInfo(singleton("/foo"), methods(GET)); + RequestMappingInfo key2 = new RequestMappingInfo(singleton("foo"), methods(GET)); assertEquals(key1, key2); assertEquals(key1.hashCode(), key2.hashCode()); @@ -86,7 +85,7 @@ public class RequestKeyTests { key3 = createKeyFromPatterns("/t1"); assertEquals(key3.getPatterns(), key1.combine(key2, pathMatcher).getPatterns()); } - + @Test public void matchPatternsToRequest() { UrlPathHelper pathHelper = new UrlPathHelper(); @@ -94,7 +93,8 @@ public class RequestKeyTests { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); RequestMappingInfo key = new RequestMappingInfo(singleton("/foo"), null); - RequestMappingInfo match = key.getMatchingRequestMapping(pathHelper.getLookupPathForRequest(request), request, pathMatcher); + RequestMappingInfo match = + key.getMatchingRequestMapping(pathHelper.getLookupPathForRequest(request), request, pathMatcher); assertNotNull(match); @@ -142,12 +142,12 @@ public class RequestKeyTests { assertNotNull("No method matches any method", match); - key = new RequestMappingInfo(singleton("/foo"), singleton(GET)); + key = new RequestMappingInfo(singleton("/foo"), methods(GET)); match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNotNull("Exact match", match); - key = new RequestMappingInfo(singleton("/foo"), singleton(POST)); + key = new RequestMappingInfo(singleton("/foo"), methods(POST)); match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNull("No match", match); @@ -159,9 +159,9 @@ public class RequestKeyTests { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); String lookupPath = new UrlPathHelper().getLookupPathForRequest(request); - RequestMappingInfo key = new RequestMappingInfo(asList("/foo*", "/bar"), asList(GET, POST)); + RequestMappingInfo key = new RequestMappingInfo(asList("/foo*", "/bar"), methods(GET, POST)); RequestMappingInfo match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); - RequestMappingInfo expected = new RequestMappingInfo(singleton("/foo*"), singleton(GET)); + RequestMappingInfo expected = new RequestMappingInfo(singleton("/foo*"), methods(GET)); assertEquals("Matching RequestKey contains matched patterns and methods only", expected, match); @@ -179,12 +179,15 @@ public class RequestKeyTests { request.setParameter("foo", "bar"); String lookupPath = new UrlPathHelper().getLookupPathForRequest(request); - RequestMappingInfo key = new RequestMappingInfo(asList("/foo"), null, RequestConditionFactory.parseParams("foo=bar"), null, null); + RequestMappingInfo key = + new RequestMappingInfo(asList("/foo"), null, RequestConditionFactory.parseParams("foo=bar"), null, + null); RequestMappingInfo match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNotNull(match); - key = new RequestMappingInfo(singleton("/foo"), null, RequestConditionFactory.parseParams("foo!=bar"), null, null); + key = new RequestMappingInfo(singleton("/foo"), null, RequestConditionFactory.parseParams("foo!=bar"), null, + null); match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNull(match); @@ -197,12 +200,15 @@ public class RequestKeyTests { request.addHeader("foo", "bar"); String lookupPath = new UrlPathHelper().getLookupPathForRequest(request); - RequestMappingInfo key = new RequestMappingInfo(singleton("/foo"), null, null, RequestConditionFactory.parseHeaders("foo=bar"), null); + RequestMappingInfo key = + new RequestMappingInfo(singleton("/foo"), null, null, RequestConditionFactory.parseHeaders("foo=bar"), + null); RequestMappingInfo match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNotNull(match); - key = new RequestMappingInfo(singleton("/foo"), null, null, RequestConditionFactory.parseHeaders("foo!=bar"), null); + key = new RequestMappingInfo(singleton("/foo"), null, null, RequestConditionFactory.parseHeaders("foo!=bar"), + null); match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNull(match); @@ -215,14 +221,14 @@ public class RequestKeyTests { request.setContentType("text/plain"); String lookupPath = new UrlPathHelper().getLookupPathForRequest(request); - RequestMappingInfo key = new RequestMappingInfo(singleton("/foo"), null, null, null, RequestConditionFactory.parseConsumes( - "text/plain")); + RequestMappingInfo key = new RequestMappingInfo(singleton("/foo"), null, null, null, + RequestConditionFactory.parseConsumes("text/plain")); RequestMappingInfo match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNotNull(match); - key = new RequestMappingInfo(singleton("/foo"), null, null, null, RequestConditionFactory.parseConsumes( - "application/xml")); + key = new RequestMappingInfo(singleton("/foo"), null, null, null, + RequestConditionFactory.parseConsumes("application/xml")); match = key.getMatchingRequestMapping(lookupPath, request, pathMatcher); assertNull(match); @@ -232,4 +238,13 @@ public class RequestKeyTests { return new RequestMappingInfo(asList(patterns), null); } + private RequestMethod[] methods(RequestMethod... methods) { + if (methods != null) { + return methods; + } + else { + return new RequestMethod[0]; + } + } + } \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestConditionTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestConditionTests.java new file mode 100644 index 00000000000..ab16fe22ca1 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/condition/RequestMethodsRequestConditionTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.mvc.method.condition; + +import org.junit.Test; + +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.bind.annotation.RequestMethod; + +import static org.junit.Assert.*; + +/** + * @author Arjen Poutsma + */ +public class RequestMethodsRequestConditionTests { + + @Test + public void methodMatch() { + RequestCondition condition = new RequestMethodsRequestCondition(RequestMethod.GET); + + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); + + assertTrue(condition.match(request)); + } + + @Test + public void methodNoMatch() { + RequestCondition condition = new RequestMethodsRequestCondition(RequestMethod.GET); + + MockHttpServletRequest request = new MockHttpServletRequest("POST", "/foo"); + + assertFalse(condition.match(request)); + } + + @Test + public void multipleMethodsMatch() { + RequestCondition condition = new RequestMethodsRequestCondition(RequestMethod.GET, RequestMethod.POST); + + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); + + assertTrue(condition.match(request)); + } + + + @Test + public void compareTo() { + RequestMethodsRequestCondition condition1 = new RequestMethodsRequestCondition(RequestMethod.GET, RequestMethod.HEAD); + RequestMethodsRequestCondition condition2 = new RequestMethodsRequestCondition(RequestMethod.POST); + RequestMethodsRequestCondition condition3 = new RequestMethodsRequestCondition(); + + int result = condition1.compareTo(condition2); + assertTrue("Invalid comparison result: " + result, result < 0); + + result = condition2.compareTo(condition1); + assertTrue("Invalid comparison result: " + result, result > 0); + + result = condition2.compareTo(condition3); + assertTrue("Invalid comparison result: " + result, result < 0); + + result = condition1.compareTo(condition1); + assertEquals("Invalid comparison result ", 0, result); + } + + @Test + public void combine() { + RequestMethodsRequestCondition condition1 = new RequestMethodsRequestCondition(RequestMethod.GET); + RequestMethodsRequestCondition condition2 = new RequestMethodsRequestCondition(RequestMethod.POST); + + RequestMethodsRequestCondition result = condition1.combine(condition2); + assertEquals(2, result.getConditions().size()); + } + + +}