|
|
@ -41,12 +41,14 @@ import reactor.core.publisher.Mono; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.ParameterizedTypeReference; |
|
|
|
import org.springframework.core.ParameterizedTypeReference; |
|
|
|
import org.springframework.http.HttpCookie; |
|
|
|
import org.springframework.http.HttpCookie; |
|
|
|
|
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
import org.springframework.http.HttpMethod; |
|
|
|
import org.springframework.http.HttpMethod; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.codec.HttpMessageReader; |
|
|
|
import org.springframework.http.codec.HttpMessageReader; |
|
|
|
import org.springframework.http.codec.multipart.Part; |
|
|
|
import org.springframework.http.codec.multipart.Part; |
|
|
|
import org.springframework.http.server.PathContainer; |
|
|
|
import org.springframework.http.server.PathContainer; |
|
|
|
import org.springframework.http.server.reactive.ServerHttpRequest; |
|
|
|
import org.springframework.http.server.reactive.ServerHttpRequest; |
|
|
|
|
|
|
|
import org.springframework.lang.NonNull; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.MultiValueMap; |
|
|
|
import org.springframework.util.MultiValueMap; |
|
|
@ -146,24 +148,7 @@ public abstract class RequestPredicates { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static RequestPredicate contentType(MediaType... mediaTypes) { |
|
|
|
public static RequestPredicate contentType(MediaType... mediaTypes) { |
|
|
|
Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty"); |
|
|
|
Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty"); |
|
|
|
Set<MediaType> mediaTypeSet = new HashSet<>(Arrays.asList(mediaTypes)); |
|
|
|
return new ContentTypePredicate(mediaTypes); |
|
|
|
|
|
|
|
|
|
|
|
return headers(new Predicate<ServerRequest.Headers>() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean test(ServerRequest.Headers headers) { |
|
|
|
|
|
|
|
MediaType contentType = |
|
|
|
|
|
|
|
headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); |
|
|
|
|
|
|
|
boolean match = mediaTypeSet.stream() |
|
|
|
|
|
|
|
.anyMatch(mediaType -> mediaType.includes(contentType)); |
|
|
|
|
|
|
|
traceMatch("Content-Type", mediaTypeSet, contentType, match); |
|
|
|
|
|
|
|
return match; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("Content-Type: %s", mediaTypeSet); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -175,29 +160,7 @@ public abstract class RequestPredicates { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static RequestPredicate accept(MediaType... mediaTypes) { |
|
|
|
public static RequestPredicate accept(MediaType... mediaTypes) { |
|
|
|
Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty"); |
|
|
|
Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty"); |
|
|
|
Set<MediaType> mediaTypeSet = new HashSet<>(Arrays.asList(mediaTypes)); |
|
|
|
return new AcceptPredicate(mediaTypes); |
|
|
|
|
|
|
|
|
|
|
|
return headers(new Predicate<ServerRequest.Headers>() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean test(ServerRequest.Headers headers) { |
|
|
|
|
|
|
|
List<MediaType> acceptedMediaTypes = headers.accept(); |
|
|
|
|
|
|
|
if (acceptedMediaTypes.isEmpty()) { |
|
|
|
|
|
|
|
acceptedMediaTypes = Collections.singletonList(MediaType.ALL); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
MediaType.sortBySpecificityAndQuality(acceptedMediaTypes); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
boolean match = acceptedMediaTypes.stream() |
|
|
|
|
|
|
|
.anyMatch(acceptedMediaType -> mediaTypeSet.stream() |
|
|
|
|
|
|
|
.anyMatch(acceptedMediaType::isCompatibleWith)); |
|
|
|
|
|
|
|
traceMatch("Accept", mediaTypeSet, acceptedMediaTypes, match); |
|
|
|
|
|
|
|
return match; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("Accept: %s", mediaTypeSet); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -284,18 +247,7 @@ public abstract class RequestPredicates { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static RequestPredicate pathExtension(String extension) { |
|
|
|
public static RequestPredicate pathExtension(String extension) { |
|
|
|
Assert.notNull(extension, "'extension' must not be null"); |
|
|
|
Assert.notNull(extension, "'extension' must not be null"); |
|
|
|
return pathExtension(new Predicate<String>() { |
|
|
|
return new PathExtensionPredicate(extension); |
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean test(String pathExtension) { |
|
|
|
|
|
|
|
boolean match = extension.equalsIgnoreCase(pathExtension); |
|
|
|
|
|
|
|
traceMatch("Extension", extension, pathExtension, match); |
|
|
|
|
|
|
|
return match; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("*.%s", extension); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -319,16 +271,7 @@ public abstract class RequestPredicates { |
|
|
|
* @see ServerRequest#queryParam(String) |
|
|
|
* @see ServerRequest#queryParam(String) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static RequestPredicate queryParam(String name, String value) { |
|
|
|
public static RequestPredicate queryParam(String name, String value) { |
|
|
|
return queryParam(name, new Predicate<String>() { |
|
|
|
return new QueryParamPredicate(name, value); |
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean test(String s) { |
|
|
|
|
|
|
|
return s.equals(value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("== %s", value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -379,6 +322,100 @@ public abstract class RequestPredicates { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receives notifications from the logical structure of request predicates. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public interface Visitor { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive notification of an HTTP method predicate. |
|
|
|
|
|
|
|
* @param methods the HTTP methods that make up the predicate |
|
|
|
|
|
|
|
* @see RequestPredicates#method(HttpMethod) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void method(Set<HttpMethod> methods); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive notification of an path predicate. |
|
|
|
|
|
|
|
* @param pattern the path pattern that makes up the predicate |
|
|
|
|
|
|
|
* @see RequestPredicates#path(String) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void path(String pattern); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive notification of an path extension predicate. |
|
|
|
|
|
|
|
* @param extension the path extension that makes up the predicate |
|
|
|
|
|
|
|
* @see RequestPredicates#pathExtension(String) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void pathExtension(String extension); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive notification of a HTTP header predicate. |
|
|
|
|
|
|
|
* @param name the name of the HTTP header to check |
|
|
|
|
|
|
|
* @param value the desired value of the HTTP header |
|
|
|
|
|
|
|
* @see RequestPredicates#headers(Predicate) |
|
|
|
|
|
|
|
* @see RequestPredicates#contentType(MediaType...) |
|
|
|
|
|
|
|
* @see RequestPredicates#accept(MediaType...) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void header(String name, String value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive notification of a query parameter predicate. |
|
|
|
|
|
|
|
* @param name the name of the query parameter |
|
|
|
|
|
|
|
* @param value the desired value of the parameter |
|
|
|
|
|
|
|
* @see RequestPredicates#queryParam(String, String) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void queryParam(String name, String value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive first notification of a logical AND predicate. |
|
|
|
|
|
|
|
* The first subsequent notification will contain the left-hand side of the AND-predicate; |
|
|
|
|
|
|
|
* the second notification contains the right-hand side, followed by {@link #endAnd()}. |
|
|
|
|
|
|
|
* @see RequestPredicate#and(RequestPredicate) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void startAnd(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive last notification of a logical AND predicate. |
|
|
|
|
|
|
|
* @see RequestPredicate#and(RequestPredicate) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void endAnd(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive first notification of a logical OR predicate. |
|
|
|
|
|
|
|
* The first subsequent notification will contain the left-hand side of the OR-predicate; |
|
|
|
|
|
|
|
* the second notification contains the right-hand side, followed by {@link #endOr()}. |
|
|
|
|
|
|
|
* @see RequestPredicate#or(RequestPredicate) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void startOr(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive last notification of a logical OR predicate. |
|
|
|
|
|
|
|
* @see RequestPredicate#or(RequestPredicate) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void endOr(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive first notification of a negated predicate. |
|
|
|
|
|
|
|
* The first subsequent notification will contain the negated predicated, followed |
|
|
|
|
|
|
|
* by {@link #endNegate()}. |
|
|
|
|
|
|
|
* @see RequestPredicate#negate() |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void startNegate(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive last notification of a negated predicate. |
|
|
|
|
|
|
|
* @see RequestPredicate#negate() |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void endNegate(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Receive first notification of an unknown predicate. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void unknown(RequestPredicate predicate); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class HttpMethodPredicate implements RequestPredicate { |
|
|
|
private static class HttpMethodPredicate implements RequestPredicate { |
|
|
|
|
|
|
|
|
|
|
|
private final Set<HttpMethod> httpMethods; |
|
|
|
private final Set<HttpMethod> httpMethods; |
|
|
@ -401,6 +438,11 @@ public abstract class RequestPredicates { |
|
|
|
return match; |
|
|
|
return match; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.method(Collections.unmodifiableSet(this.httpMethods)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
if (this.httpMethods.size() == 1) { |
|
|
|
if (this.httpMethods.size() == 1) { |
|
|
@ -454,6 +496,11 @@ public abstract class RequestPredicates { |
|
|
|
.map(info -> new SubPathServerRequestWrapper(request, info, this.pattern)); |
|
|
|
.map(info -> new SubPathServerRequestWrapper(request, info, this.pattern)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.path(this.pattern.getPatternString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return this.pattern.getPatternString(); |
|
|
|
return this.pattern.getPatternString(); |
|
|
@ -481,14 +528,115 @@ public abstract class RequestPredicates { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ContentTypePredicate extends HeadersPredicate { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Set<MediaType> mediaTypes; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public ContentTypePredicate(MediaType... mediaTypes) { |
|
|
|
|
|
|
|
this(new HashSet<>(Arrays.asList(mediaTypes))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ContentTypePredicate(Set<MediaType> mediaTypes) { |
|
|
|
|
|
|
|
super(headers -> { |
|
|
|
|
|
|
|
MediaType contentType = |
|
|
|
|
|
|
|
headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); |
|
|
|
|
|
|
|
boolean match = mediaTypes.stream() |
|
|
|
|
|
|
|
.anyMatch(mediaType -> mediaType.includes(contentType)); |
|
|
|
|
|
|
|
traceMatch("Content-Type", mediaTypes, contentType, match); |
|
|
|
|
|
|
|
return match; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
this.mediaTypes = mediaTypes; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.header(HttpHeaders.CONTENT_TYPE, |
|
|
|
|
|
|
|
(this.mediaTypes.size() == 1) ? |
|
|
|
|
|
|
|
this.mediaTypes.iterator().next().toString() : |
|
|
|
|
|
|
|
this.mediaTypes.toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("Content-Type: %s", |
|
|
|
|
|
|
|
(this.mediaTypes.size() == 1) ? |
|
|
|
|
|
|
|
this.mediaTypes.iterator().next().toString() : |
|
|
|
|
|
|
|
this.mediaTypes.toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class AcceptPredicate extends HeadersPredicate { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Set<MediaType> mediaTypes; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AcceptPredicate(MediaType... mediaTypes) { |
|
|
|
|
|
|
|
this(new HashSet<>(Arrays.asList(mediaTypes))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private AcceptPredicate(Set<MediaType> mediaTypes) { |
|
|
|
|
|
|
|
super(headers -> { |
|
|
|
|
|
|
|
List<MediaType> acceptedMediaTypes = acceptedMediaTypes(headers); |
|
|
|
|
|
|
|
boolean match = acceptedMediaTypes.stream() |
|
|
|
|
|
|
|
.anyMatch(acceptedMediaType -> mediaTypes.stream() |
|
|
|
|
|
|
|
.anyMatch(acceptedMediaType::isCompatibleWith)); |
|
|
|
|
|
|
|
traceMatch("Accept", mediaTypes, acceptedMediaTypes, match); |
|
|
|
|
|
|
|
return match; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
this.mediaTypes = mediaTypes; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@NonNull |
|
|
|
|
|
|
|
private static List<MediaType> acceptedMediaTypes(ServerRequest.Headers headers) { |
|
|
|
|
|
|
|
List<MediaType> acceptedMediaTypes = headers.accept(); |
|
|
|
|
|
|
|
if (acceptedMediaTypes.isEmpty()) { |
|
|
|
|
|
|
|
acceptedMediaTypes = Collections.singletonList(MediaType.ALL); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
MediaType.sortBySpecificityAndQuality(acceptedMediaTypes); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return acceptedMediaTypes; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.header(HttpHeaders.ACCEPT, |
|
|
|
|
|
|
|
(this.mediaTypes.size() == 1) ? |
|
|
|
|
|
|
|
this.mediaTypes.iterator().next().toString() : |
|
|
|
|
|
|
|
this.mediaTypes.toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("Accept: %s", |
|
|
|
|
|
|
|
(this.mediaTypes.size() == 1) ? |
|
|
|
|
|
|
|
this.mediaTypes.iterator().next().toString() : |
|
|
|
|
|
|
|
this.mediaTypes.toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class PathExtensionPredicate implements RequestPredicate { |
|
|
|
private static class PathExtensionPredicate implements RequestPredicate { |
|
|
|
|
|
|
|
|
|
|
|
private final Predicate<String> extensionPredicate; |
|
|
|
private final Predicate<String> extensionPredicate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
private final String extension; |
|
|
|
|
|
|
|
|
|
|
|
public PathExtensionPredicate(Predicate<String> extensionPredicate) { |
|
|
|
public PathExtensionPredicate(Predicate<String> extensionPredicate) { |
|
|
|
Assert.notNull(extensionPredicate, "Predicate must not be null"); |
|
|
|
Assert.notNull(extensionPredicate, "Predicate must not be null"); |
|
|
|
this.extensionPredicate = extensionPredicate; |
|
|
|
this.extensionPredicate = extensionPredicate; |
|
|
|
|
|
|
|
this.extension = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public PathExtensionPredicate(String extension) { |
|
|
|
|
|
|
|
Assert.notNull(extension, "Extension must not be null"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.extensionPredicate = s -> { |
|
|
|
|
|
|
|
boolean match = extension.equalsIgnoreCase(s); |
|
|
|
|
|
|
|
traceMatch("Extension", extension, s, match); |
|
|
|
|
|
|
|
return match; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
this.extension = extension; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
@ -497,9 +645,20 @@ public abstract class RequestPredicates { |
|
|
|
return this.extensionPredicate.test(pathExtension); |
|
|
|
return this.extensionPredicate.test(pathExtension); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.pathExtension( |
|
|
|
|
|
|
|
(this.extension != null) ? |
|
|
|
|
|
|
|
this.extension : |
|
|
|
|
|
|
|
this.extensionPredicate.toString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return this.extensionPredicate.toString(); |
|
|
|
return String.format("*.%s", |
|
|
|
|
|
|
|
(this.extension != null) ? |
|
|
|
|
|
|
|
this.extension : |
|
|
|
|
|
|
|
this.extensionPredicate); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
@ -509,24 +668,47 @@ public abstract class RequestPredicates { |
|
|
|
|
|
|
|
|
|
|
|
private final String name; |
|
|
|
private final String name; |
|
|
|
|
|
|
|
|
|
|
|
private final Predicate<String> predicate; |
|
|
|
private final Predicate<String> valuePredicate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
|
|
|
|
private final String value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public QueryParamPredicate(String name, Predicate<String> valuePredicate) { |
|
|
|
|
|
|
|
Assert.notNull(name, "Name must not be null"); |
|
|
|
|
|
|
|
Assert.notNull(valuePredicate, "Predicate must not be null"); |
|
|
|
|
|
|
|
this.name = name; |
|
|
|
|
|
|
|
this.valuePredicate = valuePredicate; |
|
|
|
|
|
|
|
this.value = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public QueryParamPredicate(String name, Predicate<String> predicate) { |
|
|
|
public QueryParamPredicate(String name, String value) { |
|
|
|
Assert.notNull(name, "Name must not be null"); |
|
|
|
Assert.notNull(name, "Name must not be null"); |
|
|
|
Assert.notNull(predicate, "Predicate must not be null"); |
|
|
|
Assert.notNull(value, "Value must not be null"); |
|
|
|
this.name = name; |
|
|
|
this.name = name; |
|
|
|
this.predicate = predicate; |
|
|
|
this.valuePredicate = value::equals; |
|
|
|
|
|
|
|
this.value = value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public boolean test(ServerRequest request) { |
|
|
|
public boolean test(ServerRequest request) { |
|
|
|
Optional<String> s = request.queryParam(this.name); |
|
|
|
Optional<String> s = request.queryParam(this.name); |
|
|
|
return s.filter(this.predicate).isPresent(); |
|
|
|
return s.filter(this.valuePredicate).isPresent(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.queryParam(this.name, |
|
|
|
|
|
|
|
(this.value != null) ? |
|
|
|
|
|
|
|
this.value : |
|
|
|
|
|
|
|
this.valuePredicate.toString()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return String.format("?%s %s", this.name, this.predicate); |
|
|
|
return String.format("?%s %s", this.name, |
|
|
|
|
|
|
|
(this.value != null) ? |
|
|
|
|
|
|
|
this.value : |
|
|
|
|
|
|
|
this.valuePredicate); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -564,6 +746,14 @@ public abstract class RequestPredicates { |
|
|
|
return this.left.nest(request).flatMap(this.right::nest); |
|
|
|
return this.left.nest(request).flatMap(this.right::nest); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.startAnd(); |
|
|
|
|
|
|
|
this.left.accept(visitor); |
|
|
|
|
|
|
|
this.right.accept(visitor); |
|
|
|
|
|
|
|
visitor.endAnd(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return String.format("(%s && %s)", this.left, this.right); |
|
|
|
return String.format("(%s && %s)", this.left, this.right); |
|
|
@ -591,6 +781,13 @@ public abstract class RequestPredicates { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.startNegate(); |
|
|
|
|
|
|
|
this.delegate.accept(visitor); |
|
|
|
|
|
|
|
visitor.endNegate(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return "!" + this.delegate.toString(); |
|
|
|
return "!" + this.delegate.toString(); |
|
|
@ -642,6 +839,15 @@ public abstract class RequestPredicates { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void accept(Visitor visitor) { |
|
|
|
|
|
|
|
visitor.startOr(); |
|
|
|
|
|
|
|
this.left.accept(visitor); |
|
|
|
|
|
|
|
this.right.accept(visitor); |
|
|
|
|
|
|
|
visitor.endOr(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return String.format("(%s || %s)", this.left, this.right); |
|
|
|
return String.format("(%s || %s)", this.left, this.right); |
|
|
|