GH-2335 - Remove deprecations introduced until 2.0.

This commit is contained in:
Oliver Drotbohm
2025-06-04 18:51:43 +02:00
parent 7527d2eea3
commit 68b3c19eda
15 changed files with 305 additions and 231 deletions

View File

@@ -204,15 +204,6 @@ public abstract class AffordanceModel {
*/
Stream<PropertyMetadata> stream();
/**
* @deprecated since 1.4, for removal in 1.5. Prefer {@link #stream()} and selecting individual
* {@code PropertyMetadata} instances yourself.
*/
@Deprecated
default Optional<PropertyMetadata> getPropertyMetadata(String name) {
return stream().filter(it -> it.hasName(name)).findFirst();
}
@Nullable
default Class<?> getType() {
return null;
@@ -235,23 +226,6 @@ public abstract class AffordanceModel {
: DelegatingInputPayloadMetadata.of(metadata);
}
/**
* Applies the {@link InputPayloadMetadata} to the given target.
*
* @param <T>
* @param target
* @return
* @deprecated since 1.3, prefer setting up the model types via
* {@link AffordanceModel#createProperties(BiFunction)}.
*/
@Deprecated
default <T extends PropertyMetadataConfigured<T> & Named> T applyTo(T target) {
return getPropertyMetadata(target.getName()) //
.map(it -> target.apply(it)) //
.orElse(target);
}
<T extends Named> T customize(T target, Function<PropertyMetadata, T> customizer);
/**
@@ -321,15 +295,6 @@ public abstract class AffordanceModel {
return metadata.stream();
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.AffordanceModel.InputPayloadMetadata#customize(org.springframework.hateoas.AffordanceModel.PropertyMetadataConfigured)
*/
@Override
public <T extends PropertyMetadataConfigured<T> & Named> T applyTo(T target) {
return target;
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.AffordanceModel.InputPayloadMetadata#customize(org.springframework.hateoas.AffordanceModel.Named, java.util.function.Function)

View File

@@ -95,18 +95,29 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
* Static helper to fashion {@link VariableType#PATH_VARIABLE} variables.
*
* @param variable must not be {@literal null} or empty.
* @return
* @return will never be {@literal null}.
* @since 1.1
*/
public static TemplateVariable pathVariable(String variable) {
return new TemplateVariable(variable, VariableType.PATH_VARIABLE);
return new TemplateVariable(variable, VariableType.SIMPLE);
}
/**
* Alias of {@link #pathVariable(String)}.
*
* @param variable must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 3.0
*/
public static TemplateVariable simple(String variable) {
return new TemplateVariable(variable, VariableType.SIMPLE);
}
/**
* Static helper to fashion {@link VariableType#REQUEST_PARAM} variables.
*
* @param parameter must not be {@literal null} or empty.
* @return
* @return will never be {@literal null}.
* @since 1.1
*/
public static TemplateVariable requestParameter(String parameter) {
@@ -117,7 +128,7 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
* Static helper to fashion {@link VariableType#REQUEST_PARAM_CONTINUED} variables.
*
* @param parameter must not be {@literal null} or empty.
* @return
* @return will never be {@literal null}.
* @since 1.1
*/
public static TemplateVariable requestParameterContinued(String parameter) {
@@ -128,41 +139,35 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
* Static helper to fashion {@link VariableType#SEGMENT} variables.
*
* @param segment must not be {@literal null} or empty.
* @return
* @return will never be {@literal null}.
* @since 1.1
*/
public static TemplateVariable segment(String segment) {
return new TemplateVariable(segment, VariableType.SEGMENT);
return new TemplateVariable(segment, VariableType.PATH_SEGMENT);
}
/**
* Static helper to fashion {@link VariableType#FRAGMENT} variables.
*
* @param name must not be {@literal null} or empty.
* @return
* @return will never be {@literal null}.
* @since 1.1
*/
public static TemplateVariable fragment(String name) {
return new TemplateVariable(name, VariableType.FRAGMENT);
}
/**
* Static helper to fashion {@link VariableType#RESERVED_STRING} variables.
*
* @param name must not be {@literal null} or empty.
* @return will never be {@literal null}.
* @since 1.1
*/
public static TemplateVariable reservedString(String name) {
return new TemplateVariable(name, VariableType.RESERVED_STRING);
}
/**
* Static helper to fashion {@link VariableType#COMPOSITE_PARAM} variables.
*
* @param parameter must not be {@literal null} or empty.
* @return
* @since 1.1
* @deprecated since 1.4, use actual parameter type and call {@link #composite()} on the instance instead.
*/
@Deprecated
public static TemplateVariable compositeParameter(String parameter) {
return new TemplateVariable(parameter, VariableType.COMPOSITE_PARAM);
}
/**
* Marks the current template variable as composite value.
*
@@ -220,18 +225,6 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
return StringUtils.hasText(description);
}
/**
* Returns whether the template variable is optional, which means the template can be expanded to a URI without a
* value given for that variable.
*
* @return
* @deprecated since 1.4. No replacement as template variables are never required actually.
*/
@Deprecated
boolean isRequired() {
return !type.isOptional();
}
/**
* Returns whether the given {@link TemplateVariable} is of the same type as the current one.
*
@@ -285,7 +278,6 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
}
public String asString() {
return "{" + type.toString() + essence() + "}";
}
@@ -474,32 +466,13 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
public enum VariableType {
SIMPLE("", ",", false), //
/**
* @deprecated since 1.4, use {@link #SIMPLE} instead.
*/
@Deprecated
PATH_VARIABLE("", ",", true), //
RESERVED_STRING("+", ",", true), //
DOT(".", ".", true), //
REQUEST_PARAM("?", "&", true), //
REQUEST_PARAM_CONTINUED("&", "&", true), //
PATH_SEGMENT("/", "/", true), //
/**
* @deprecated since 1.4, use {@link #PATH_SEGMENT} instead.
*/
@Deprecated
SEGMENT("/", "/", true), //
PATH_STYLE_PARAMETER(";", ";", true), //
FRAGMENT("#", ",", true), //
/**
* @deprecated since 1.4. Use the actual type and call {@link TemplateVariable#composite()}.
*/
@Deprecated
COMPOSITE_PARAM("*", "", true);
FRAGMENT("#", ",", true);
private static final EnumSet<VariableType> COMBINABLE_TYPES = EnumSet.of(REQUEST_PARAM, REQUEST_PARAM_CONTINUED);
static final String DEFAULT_SEPARATOR = ",";
@@ -518,7 +491,6 @@ public final class TemplateVariable implements Serializable, UriTemplate.Expanda
switch (this) {
case DOT:
case SEGMENT:
case PATH_SEGMENT:
case PATH_STYLE_PARAMETER:
case REQUEST_PARAM:

View File

@@ -114,16 +114,6 @@ public @interface EnableHypermediaSupport {
return this.mediaTypes;
}
/**
* @deprecated since 2.5, in favor of {@link #getMediaTypes()} as a logical media type might have been associated
* with multiple media type identifiers (see {@link #HAL}).
* @return will never be {@literal null}.
*/
@Deprecated(since = "2.5", forRemoval = true)
public MediaType getMediaType() {
return this.mediaTypes.get(0);
}
public String getLocalPackageName() {
return localPackageName;
}

View File

@@ -42,7 +42,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
* @author Greg Turnquist
* @author Réda Housni Alaoui
*/
public class AnnotationMappingDiscoverer implements MappingDiscoverer {
public class AnnotationMappingDiscoverer implements MappingDiscoverer, RawMappingDiscoverer {
private final Class<? extends Annotation> annotationType;
private final @Nullable String mappingAttributeName;
@@ -73,50 +73,59 @@ public class AnnotationMappingDiscoverer implements MappingDiscoverer {
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.Class)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.Class)
*/
@Override
@Nullable
public String getMapping(Class<?> type) {
Assert.notNull(type, "Type must not be null!");
String[] mapping = getMappingFrom(findMergedAnnotation(type, annotationType));
return mapping.length == 0 ? null : mapping[0];
public UriMapping getUriMapping(Class<?> type) {
return UriMapping.of(getMapping(type));
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.reflect.Method)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.reflect.Method)
*/
@Override
@Nullable
public String getMapping(Method method) {
public UriMapping getUriMapping(Method method) {
Assert.notNull(method, "Method must not be null!");
return getMapping(method.getDeclaringClass(), method);
return getUriMapping(method.getDeclaringClass(), method);
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.Class, java.lang.reflect.Method)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.Class, java.lang.reflect.Method)
*/
@Override
@Nullable
public String getMapping(Class<?> type, Method method) {
public UriMapping getUriMapping(Class<?> type, Method method) {
Assert.notNull(type, "Type must not be null!");
Assert.notNull(method, "Method must not be null!");
var mapping = getMapping(type, method);
String[] mapping = getMappingFrom(findMergedAnnotation(method, annotationType));
return mapping == null ? null : UriMapping.of(cleanup(mapping));
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.server.core.RawMappingDiscoverer#getMapping(java.lang.Class, java.lang.reflect.Method)
*/
@Override
public @Nullable String getMapping(@Nullable Class<?> type, @Nullable Method method) {
String[] mapping = method == null ? new String[0] : getMappingFrom(findMergedAnnotation(method, annotationType));
String typeMapping = getMapping(type);
if (mapping.length == 0) {
return typeMapping;
}
return cleanup(typeMapping == null || "/".equals(typeMapping) ? mapping[0] : join(typeMapping, mapping[0]));
var result = typeMapping == null || "/".equals(typeMapping)
? mapping[0]
: join(typeMapping, mapping[0]);
return cleanup(result);
}
/**
@@ -179,6 +188,17 @@ public class AnnotationMappingDiscoverer implements MappingDiscoverer {
return params == null ? new String[0] : params;
}
private @Nullable String getMapping(@Nullable Class<?> type) {
if (type == null) {
return null;
}
String[] mapping = getMappingFrom(findMergedAnnotation(type, annotationType));
return mapping.length == 0 ? null : mapping[0];
}
private String[] getMappingFrom(@Nullable Annotation annotation) {
if (annotation == null) {

View File

@@ -35,7 +35,7 @@ import org.springframework.util.StringUtils;
*/
public class CachingMappingDiscoverer implements MappingDiscoverer {
private static final Map<String, String> MAPPINGS = new ConcurrentReferenceHashMap<>();
private static final Map<String, UriMapping> MAPPINGS = new ConcurrentReferenceHashMap<>();
private static final Map<String, Collection<HttpMethod>> METHODS = new ConcurrentReferenceHashMap<>();
private static final Map<String, String[]> PARAMS = new ConcurrentReferenceHashMap<>();
private static final Map<String, List<MediaType>> CONSUMES = new ConcurrentReferenceHashMap<>();
@@ -52,38 +52,38 @@ public class CachingMappingDiscoverer implements MappingDiscoverer {
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.Class)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.Class)
*/
@Nullable
@Override
public String getMapping(Class<?> type) {
public UriMapping getUriMapping(Class<?> type) {
String key = key(type, null);
return MAPPINGS.computeIfAbsent(key, __ -> delegate.getMapping(type));
return MAPPINGS.computeIfAbsent(key, __ -> delegate.getUriMapping(type));
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.reflect.Method)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.reflect.Method)
*/
@Nullable
@Override
public String getMapping(Method method) {
return MAPPINGS.computeIfAbsent(key(method), __ -> delegate.getMapping(method));
public UriMapping getUriMapping(Method method) {
return MAPPINGS.computeIfAbsent(key(method), __ -> delegate.getUriMapping(method));
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.Class, java.lang.reflect.Method)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.Class, java.lang.reflect.Method)
*/
@Nullable
@Override
public String getMapping(Class<?> type, Method method) {
public UriMapping getUriMapping(Class<?> type, Method method) {
String key = key(type, method);
return MAPPINGS.computeIfAbsent(key, __ -> delegate.getMapping(type, method));
return MAPPINGS.computeIfAbsent(key, __ -> delegate.getUriMapping(type, method));
}
/*

View File

@@ -33,17 +33,6 @@ import org.springframework.http.MediaType;
*/
public interface MappingDiscoverer {
/**
* Returns the mapping associated with the given type.
*
* @param type must not be {@literal null}.
* @return the type-level mapping or {@literal null} in case none is present.
* @deprecated since 2.0, prefer {@link #getUriMapping(Class)}
*/
@Nullable
@Deprecated
String getMapping(Class<?> type);
/**
* Returns the mapping associated with the given type.
*
@@ -52,20 +41,7 @@ public interface MappingDiscoverer {
* @since 2.0
*/
@Nullable
default UriMapping getUriMapping(Class<?> type) {
return UriMapping.of(getMapping(type));
}
/**
* Returns the mapping associated with the given {@link Method}. This will include the type-level mapping.
*
* @param method must not be {@literal null}.
* @return the method mapping including the type-level one or {@literal null} if neither of them present.
* @deprecated since 2.0, use {@link #getUriMapping(Method)} instead
*/
@Nullable
@Deprecated
String getMapping(Method method);
UriMapping getUriMapping(Class<?> type);
/**
* Returns the mapping associated with the given {@link Method}. This will include the type-level mapping.
@@ -75,22 +51,7 @@ public interface MappingDiscoverer {
* @since 2.0
*/
@Nullable
default UriMapping getUriMapping(Method method) {
return UriMapping.of(getMapping(method));
}
/**
* Returns the mapping for the given {@link Method} invoked on the given type. This can be used to calculate the
* mapping for a super type method being invoked on a sub-type with a type mapping.
*
* @param type must not be {@literal null}.
* @param method must not be {@literal null}.
* @return the method mapping including the type-level one or {@literal null} if neither of them present.
* @deprecated since 2.0, use {@link #getUriMapping(Class, Method)} instead
*/
@Nullable
@Deprecated
String getMapping(Class<?> type, Method method);
UriMapping getUriMapping(Method method);
/**
* Returns the mapping for the given {@link Method} invoked on the given type. This can be used to calculate the
@@ -102,9 +63,7 @@ public interface MappingDiscoverer {
* @since 2.0
*/
@Nullable
default UriMapping getUriMapping(Class<?> type, Method method) {
return UriMapping.of(getMapping(type, method));
}
UriMapping getUriMapping(Class<?> type, Method method);
/**
* Returns the HTTP verbs for the given {@link Method} invoked on the given type. This can be used to build hypermedia

View File

@@ -35,9 +35,9 @@ import org.springframework.web.context.WebApplicationContext;
*/
class PropertyResolvingMappingDiscoverer implements MappingDiscoverer {
private final MappingDiscoverer delegate;
private final RawMappingDiscoverer delegate;
PropertyResolvingMappingDiscoverer(MappingDiscoverer delegate) {
PropertyResolvingMappingDiscoverer(RawMappingDiscoverer delegate) {
Assert.notNull(delegate, "Delegate MappingDiscoverer must not be null!");
@@ -46,32 +46,41 @@ class PropertyResolvingMappingDiscoverer implements MappingDiscoverer {
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.Class)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.Class)
*/
@Nullable
@Override
public String getMapping(Class<?> type) {
return resolveProperties(delegate.getMapping(type));
public UriMapping getUriMapping(Class<?> type) {
var mapping = delegate.getMapping(type, null);
return mapping == null ? null : UriMapping.of(resolveProperties(mapping));
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.reflect.Method)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.reflect.Method)
*/
@Nullable
@Override
public String getMapping(Method method) {
return resolveProperties(delegate.getMapping(method));
public UriMapping getUriMapping(Method method) {
var mapping = delegate.getMapping(method.getDeclaringClass(), method);
return mapping == null ? null : UriMapping.of(resolveProperties(mapping));
}
/*
* (non-Javadoc)
* @see org.springframework.hateoas.core.MappingDiscoverer#getMapping(java.lang.Class, java.lang.reflect.Method)
* @see org.springframework.hateoas.server.core.MappingDiscoverer#getUriMapping(java.lang.Class, java.lang.reflect.Method)
*/
@Nullable
@Override
public String getMapping(Class<?> type, Method method) {
return resolveProperties(delegate.getMapping(type, method));
public UriMapping getUriMapping(Class<?> type, Method method) {
var mapping = delegate.getMapping(type, method);
return mapping == null ? null : UriMapping.of(resolveProperties(mapping));
}
/*

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2025 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
*
* https://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.hateoas.server.core;
import java.lang.reflect.Method;
import org.jspecify.annotations.Nullable;
/**
* An extension of {@link MappingDiscoverer} that allows access to the raw {@link String}-based mapping before turning
* it into a {@link UriMapping}.
*
* @author Oliver Drotbohm
* @since 3.0
*/
interface RawMappingDiscoverer extends MappingDiscoverer {
/**
* Returns the raw URI mapping associated with the given method of the given class.
*
* @param type can be {@literal null}.
* @param method can be {@literal null}.
* @return can be {@literal null}.
*/
@Nullable
String getMapping(@Nullable Class<?> type, @Nullable Method method);
}

View File

@@ -70,20 +70,6 @@ public class SpringAffordanceBuilder {
.apply(Affordances.of(affordanceLink));
}
/**
* Returns the mapping for the given type's method.
*
* @param type must not be {@literal null}.
* @param method must not be {@literal null}.
* @return
* @deprecated since 2.0, use {@link #getUriMapping(Class, Method)} instead.
*/
@Nullable
@Deprecated
public static String getMapping(Class<?> type, Method method) {
return DISCOVERER.getMapping(type, method);
}
/**
* Returns the mapping for the given type's method.
*

View File

@@ -17,8 +17,10 @@ package org.springframework.hateoas.server.core;
import static org.springframework.web.util.UriComponents.UriTemplateVariables.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -95,6 +97,43 @@ public class UriMapping {
return this.variables;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return mapping + " " + variables;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof UriMapping that)) {
return false;
}
return Objects.equals(this.mapping, that.mapping)
&& Objects.equals(this.variables, that.variables);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return Objects.hash(this.mapping, this.variables);
}
/**
* All {@link MappingVariable}s contained in a {@link UriTemplate}.
*
@@ -105,7 +144,14 @@ public class UriMapping {
private final List<MappingVariable> variables;
public MappingVariables(UriTemplate template) {
this.variables = template.getVariableNames().stream().map(MappingVariable::of).collect(Collectors.toList());
this.variables = template.getVariableNames().stream()
.map(MappingVariable::of)
.collect(Collectors.toList());
}
private MappingVariables(List<MappingVariable> variables) {
this.variables = variables;
}
public boolean hasCapturingVariable() {
@@ -129,6 +175,19 @@ public class UriMapping {
.orElseThrow(() -> new IllegalArgumentException("No variable named " + name + " found!"));
}
public MappingVariables and(MappingVariables other) {
List<MappingVariable> result = new ArrayList<>(variables);
for (MappingVariable variable : other) {
if (!result.contains(variable)) {
result.add(variable);
}
}
return new MappingVariables(result);
}
/*
* (non-Javadoc)
* @see java.lang.Iterable#iterator()
@@ -137,6 +196,42 @@ public class UriMapping {
public Iterator<MappingVariable> iterator() {
return variables.iterator();
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return variables.toString();
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof MappingVariables that)) {
return false;
}
return Objects.equals(this.variables, that.variables);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return Objects.hash(variables);
}
}
/**
@@ -226,6 +321,43 @@ public class UriMapping {
public Object getAbsentValue() {
return composite ? TemplateVariable.segment(name).composite().toString() : SKIP_VALUE;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return name + (composite ? "*" : "");
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof MappingVariable that)) {
return false;
}
return Objects.equals(this.name, that.name)
&& this.composite == that.composite;
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return Objects.hash(name, composite);
}
}
/**
@@ -258,7 +390,6 @@ public class UriMapping {
* @see java.util.function.Function#apply(java.lang.Object)
*/
@Override
@SuppressWarnings("null")
public String apply(String source) {
Matcher matcher = PATH_CAPTURE.matcher(source);

View File

@@ -84,8 +84,8 @@ public class WebMvcLinkBuilder extends TemplateVariableAwareLinkBuilderSupport<W
Assert.notNull(controller, "Controller must not be null!");
Assert.notNull(parameters, "Parameters must not be null!");
var mapping = SpringAffordanceBuilder.DISCOVERER.getMapping(controller);
var defaulted = mapping == null ? "/" : mapping;
var mapping = SpringAffordanceBuilder.DISCOVERER.getUriMapping(controller);
var defaulted = mapping == null ? "/" : mapping.getMapping();
var uri = URI_FACTORY.expand(defaulted, parameters);
var uriComponents = UriComponentsBuilder.fromUri(uri).build();
@@ -107,8 +107,8 @@ public class WebMvcLinkBuilder extends TemplateVariableAwareLinkBuilderSupport<W
Assert.notNull(controller, "Controller must not be null!");
Assert.notNull(parameters, "Parameters must not be null!");
var mapping = SpringAffordanceBuilder.DISCOVERER.getMapping(controller);
var defaulted = mapping == null ? "/" : mapping;
var mapping = SpringAffordanceBuilder.DISCOVERER.getUriMapping(controller);
var defaulted = mapping == null ? "/" : mapping.getMapping();
var uri = URI_FACTORY.expand(defaulted, parameters);
var uriComponents = UriComponentsBuilder.fromUri(uri).build();

View File

@@ -332,9 +332,9 @@ class UriTemplateUnitTest {
.isEqualTo("/foo{#var}");
assertThat(UriTemplate.of("/foo") //
.with(compositeParameter("var")) //
.with(simple("var").composite()) //
.toString()) //
.isEqualTo("/foo{*var}");
.isEqualTo("/foo{var*}");
}
@Test // #227

View File

@@ -45,32 +45,32 @@ class AnnotationMappingDiscovererUnitTest {
@Test
void discoversTypeLevelMapping() {
assertThat(discoverer.getMapping(MyController.class)).isEqualTo("/type");
assertThat(discoverer.getUriMapping(MyController.class)).isEqualTo(UriMapping.of("/type"));
}
@Test
void discoversMethodLevelMapping() throws Exception {
Method method = MyController.class.getMethod("method");
assertThat(discoverer.getMapping(method)).isEqualTo("/type/method");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/type/method"));
}
@Test
void returnsNullForNonExistentTypeLevelMapping() {
assertThat(discoverer.getMapping(ControllerWithoutTypeLevelMapping.class)).isNull();
assertThat(discoverer.getUriMapping(ControllerWithoutTypeLevelMapping.class)).isNull();
}
@Test
void resolvesMethodLevelMappingWithoutTypeLevelMapping() throws Exception {
Method method = ControllerWithoutTypeLevelMapping.class.getMethod("method");
assertThat(discoverer.getMapping(method)).isEqualTo("/method");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/method"));
}
@Test
void resolvesMethodLevelMappingWithSlashRootMapping() throws Exception {
Method method = SlashRootMapping.class.getMethod("method");
assertThat(discoverer.getMapping(method)).isEqualTo("/method");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/method"));
}
/**
@@ -80,7 +80,7 @@ class AnnotationMappingDiscovererUnitTest {
void treatsMissingMethodMappingAsEmptyMapping() throws Exception {
Method method = MyController.class.getMethod("noMethodMapping");
assertThat(discoverer.getMapping(method)).isEqualTo("/type");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/type"));
}
/**
@@ -90,7 +90,7 @@ class AnnotationMappingDiscovererUnitTest {
void detectsClassMappingOnSuperType() throws Exception {
Method method = ChildController.class.getMethod("mapping");
assertThat(discoverer.getMapping(method)).isEqualTo("/parent/child");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/parent/child"));
}
/**
@@ -100,7 +100,7 @@ class AnnotationMappingDiscovererUnitTest {
void includesTypeMappingFromChildClass() throws Exception {
Method method = ParentWithMethod.class.getMethod("mapping");
assertThat(discoverer.getMapping(ChildWithTypeMapping.class, method)).isEqualTo("/child/parent");
assertThat(discoverer.getUriMapping(ChildWithTypeMapping.class, method)).isEqualTo(UriMapping.of("/child/parent"));
}
/**
@@ -110,16 +110,16 @@ class AnnotationMappingDiscovererUnitTest {
void handlesSlashes() throws Exception {
Method method = ControllerWithoutSlashes.class.getMethod("noslash");
assertThat(discoverer.getMapping(method)).isEqualTo("slashes/noslash");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("slashes/noslash"));
method = ControllerWithoutSlashes.class.getMethod("withslash");
assertThat(discoverer.getMapping(method)).isEqualTo("slashes/withslash");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("slashes/withslash"));
method = ControllerWithTrailingSlashes.class.getMethod("noslash");
assertThat(discoverer.getMapping(method)).isEqualTo("trailing/noslash");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("trailing/noslash"));
method = ControllerWithTrailingSlashes.class.getMethod("withslash");
assertThat(discoverer.getMapping(method)).isEqualTo("trailing/withslash");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("trailing/withslash"));
}
/**
@@ -130,7 +130,7 @@ class AnnotationMappingDiscovererUnitTest {
Method method = ControllerWithMultipleSlashes.class.getMethod("withslash");
assertThat(discoverer.getMapping(method)).isEqualTo("trailing/withslash");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("trailing/withslash"));
}
/**
@@ -141,7 +141,7 @@ class AnnotationMappingDiscovererUnitTest {
Method method = MultipleMappingsController.class.getMethod("method");
assertThat(discoverer.getMapping(method)).isEqualTo("/type/method");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/type/method"));
}
/**
@@ -151,14 +151,14 @@ class AnnotationMappingDiscovererUnitTest {
void discoversMethodLevelMappingUsingComposedAnnotation() throws Exception {
Method method = MyController.class.getMethod("methodWithComposedAnnotation");
assertThat(discoverer.getMapping(method)).isEqualTo("/type/otherMethod");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/type/otherMethod"));
}
@Test // #1412
void removesMatchingExpressionFromTemplateVariable() throws Exception {
Method method = MyController.class.getMethod("mappingWithMatchingExpression");
assertThat(discoverer.getMapping(method)).isEqualTo("/type/foo/{bar}");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/type/foo/{bar}"));
}
@Test // #1442
@@ -176,7 +176,8 @@ class AnnotationMappingDiscovererUnitTest {
Method method = MyController.class.getMethod("multipleRegularExpressions");
assertThat(discoverer.getMapping(method)).isEqualTo("/type/spring-web/{symbolicName}-{version}{extension}");
assertThat(discoverer.getUriMapping(method))
.isEqualTo(UriMapping.of("/type/spring-web/{symbolicName}-{version}{extension}"));
}
@Test // #1468
@@ -184,7 +185,7 @@ class AnnotationMappingDiscovererUnitTest {
Method method = TrailingSlashes.class.getMethod("trailingSlash");
assertThat(discoverer.getMapping(method)).isEqualTo("/api/myentities/");
assertThat(discoverer.getUriMapping(method)).isEqualTo(UriMapping.of("/api/myentities/"));
}
@RequestMapping("/type")

View File

@@ -58,18 +58,20 @@ class PropertyResolvingMappingDiscovererUnitTest extends TestUtils {
AnnotationMappingDiscoverer annotationMappingDiscoverer = new AnnotationMappingDiscoverer(RequestMapping.class);
// Test plain AnnotationMappingDiscoverer first
assertThat(annotationMappingDiscoverer.getMapping(ResolveEndpointController.class)).isEqualTo("/${test.parent}");
assertThat(annotationMappingDiscoverer.getMapping(ResolveMethodEndpointController.class, method))
.isEqualTo("/${test.parent}/${test.child}");
assertThat(annotationMappingDiscoverer.getUriMapping(ResolveEndpointController.class))
.isEqualTo(UriMapping.of("/${test.parent}"));
assertThat(annotationMappingDiscoverer.getUriMapping(ResolveMethodEndpointController.class, method))
.isEqualTo(UriMapping.of("/${test.parent}/${test.child}"));
PropertyResolvingMappingDiscoverer propertyResolvingMappingDiscoverer = new PropertyResolvingMappingDiscoverer(
annotationMappingDiscoverer);
assertThat(propertyResolvingMappingDiscoverer.getMapping(ResolveEndpointController.class))
.isEqualTo("/resolvedparent");
assertThat(propertyResolvingMappingDiscoverer.getMapping(method)).isEqualTo("/resolvedparent/resolvedchild");
assertThat(propertyResolvingMappingDiscoverer.getMapping(ResolveMethodEndpointController.class, method))
.isEqualTo("/resolvedparent/resolvedchild");
assertThat(propertyResolvingMappingDiscoverer.getUriMapping(ResolveEndpointController.class))
.isEqualTo(UriMapping.of("/resolvedparent"));
assertThat(propertyResolvingMappingDiscoverer.getUriMapping(method))
.isEqualTo(UriMapping.of("/resolvedparent/resolvedchild"));
assertThat(propertyResolvingMappingDiscoverer.getUriMapping(ResolveMethodEndpointController.class, method))
.isEqualTo(UriMapping.of("/resolvedparent/resolvedchild"));
}
@RequestMapping("/${test.parent}")

View File

@@ -34,7 +34,6 @@ import java.util.stream.Stream;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.jspecify.annotations.NonNull;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Named;
import org.junit.jupiter.api.Test;