Skip to content

Commit

Permalink
#1413 - Discovered mappings now get regex matchers removed.
Browse files Browse the repository at this point in the history
We now remove potentially used regular expression matchers from template variables to avoid the to show up in links generated for the templates.

Backport of #1412.
  • Loading branch information
odrotbohm committed Dec 12, 2020
1 parent 35b853c commit f008e75
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.http.HttpMethod;
Expand All @@ -43,6 +44,7 @@
public class AnnotationMappingDiscoverer implements MappingDiscoverer {

private static final Pattern MULTIPLE_SLASHES = Pattern.compile("/{2,}");
private static final Pattern TEMPLATE_VARIABLE_NAME = Pattern.compile("\\{(.*)\\}");

private final Class<? extends Annotation> annotationType;
private final String mappingAttributeName;
Expand Down Expand Up @@ -116,7 +118,7 @@ public String getMapping(Class<?> type, Method method) {
return typeMapping;
}

return typeMapping == null || "/".equals(typeMapping) ? mapping[0] : join(typeMapping, mapping[0]);
return cleanup(typeMapping == null || "/".equals(typeMapping) ? mapping[0] : join(typeMapping, mapping[0]));
}

/**
Expand Down Expand Up @@ -179,6 +181,49 @@ private String[] getMappingFrom(@Nullable Annotation annotation) {
* @return
*/
private static String join(String typeMapping, String mapping) {
return MULTIPLE_SLASHES.matcher(typeMapping.concat("/").concat(mapping)).replaceAll("/");
return typeMapping.concat("/").concat(mapping);
}

/**
* @param mapping
* @return
*/
private static String cleanup(String mapping) {

String[] parts = mapping.split("/");
StringBuilder result = new StringBuilder();

for (int i = 0; i < parts.length; i++) {

String part = parts[i];

if (i != 0) {
result.append("/");
}

result.append(part.contains(":") ? cleanupPart(part) : part);
}

return MULTIPLE_SLASHES.matcher(result.toString()).replaceAll("/");
}

private static String cleanupPart(String variable) {

if (!variable.contains("{")) {
return variable;
}

Matcher matcher = TEMPLATE_VARIABLE_NAME.matcher(variable);

if (!matcher.find()) {
return variable;
}

String rawName = matcher.group(1);
int colonIndex = rawName.indexOf(':');

return colonIndex < 0
? variable
: variable.replace(matcher.group(0), "{" + rawName.substring(0, colonIndex) + "}");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

/**
* Unit tests for {@link AnnotationMappingDiscoverer}.
*
*
* @author Oliver Gierke
* @author Kevin Conaway
* @author Mark Paluch
Expand Down Expand Up @@ -153,6 +153,13 @@ void discoversMethodLevelMappingUsingComposedAnnotation() throws Exception {
assertThat(discoverer.getMapping(method)).isEqualTo("/type/otherMethod");
}

@Test // #1412
void removesMatchingExpressionFromTemplateVariable() throws Exception {

Method method = MyController.class.getMethod("mappingWithMatchingExpression");
assertThat(discoverer.getMapping(method)).isEqualTo("/type/foo/{bar}");
}

@RequestMapping("/type")
interface MyController {

Expand All @@ -164,6 +171,9 @@ interface MyController {

@RequestMapping
void noMethodMapping();

@RequestMapping("/foo/{bar:[ABC]{1}}")
void mappingWithMatchingExpression();
}

interface ControllerWithoutTypeLevelMapping {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.TestUtils;
import org.springframework.hateoas.server.core.AnnotationMappingDiscoverer;
import org.springframework.hateoas.server.core.PropertyResolvingMappingDiscoverer;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
Expand Down

0 comments on commit f008e75

Please sign in to comment.