#1460 - Parsing Link instances now supports unquoted attribute values.
Switched from using regular expressions to a simple manual parsing algorithm for the attributes attached to a link. Adapt a couple of broken tests that previously erroneously worked.
This commit is contained in:
@@ -47,11 +47,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
public class Link implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -9037755944661782121L;
|
||||
private static final String URI_PATTERN = "(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
|
||||
|
||||
private static final Pattern URI_AND_ATTRIBUTES_PATTERN = Pattern.compile("<(.*)>;(.*)");
|
||||
private static final Pattern KEY_AND_VALUE_PATTERN = Pattern
|
||||
.compile("(\\w+)=\"(\\p{Lower}[\\p{Lower}\\p{Digit}.\\-\\s]*|" + URI_PATTERN + ")\"");
|
||||
|
||||
public static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom";
|
||||
|
||||
@@ -515,11 +511,20 @@ public class Link implements Serializable {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
String[] parts = source.split(";");
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
Matcher matcher = KEY_AND_VALUE_PATTERN.matcher(source);
|
||||
|
||||
while (matcher.find()) {
|
||||
attributes.put(matcher.group(1), matcher.group(2));
|
||||
for (String part : parts) {
|
||||
|
||||
int delimiter = part.indexOf('=');
|
||||
|
||||
String key = part.substring(0, delimiter).trim();
|
||||
String value = part.substring(delimiter + 1).trim();
|
||||
|
||||
// Potentially unquote value
|
||||
value = value.startsWith("\"") ? value.substring(1, value.length() - 1) : value;
|
||||
|
||||
attributes.put(key, value);
|
||||
}
|
||||
|
||||
return attributes;
|
||||
|
||||
@@ -44,7 +44,7 @@ import com.fasterxml.jackson.annotation.JsonValue;
|
||||
public class Links implements Iterable<Link> {
|
||||
|
||||
public static final Links NONE = new Links(Collections.emptyList());
|
||||
private static final Pattern LINK_HEADER_PATTERN = Pattern.compile("(<[^>]*>(;\\s*\\w+=\"[^\"]*\")+)");
|
||||
private static final Pattern LINK_HEADER_PATTERN = Pattern.compile("(<[^>]*>(;\\s*\\w+=\"?[^\"]*\"?)+)");
|
||||
|
||||
private final List<Link> links;
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ class LinkUnitTest {
|
||||
|
||||
softly.assertThat(Link.valueOf("</something>;rel=\"foo\"")).isEqualTo(Link.of("/something", "foo"));
|
||||
softly.assertThat(Link.valueOf("</something>;rel=\"foo\";title=\"Some title\""))
|
||||
.isEqualTo(Link.of("/something", "foo"));
|
||||
.isEqualTo(Link.of("/something", "foo").withTitle("Some title"));
|
||||
softly.assertThat(Link.valueOf("</customer/1>;" //
|
||||
+ "rel=\"self\";" //
|
||||
+ "hreflang=\"en\";" //
|
||||
|
||||
@@ -135,4 +135,11 @@ class LinksUnitTest {
|
||||
assertThat(Links.of(first, second).containsSameLinksAs(Links.of(first))).isFalse();
|
||||
assertThat(Links.of(first, second).containsSameLinksAs(Links.of(first, second))).isTrue();
|
||||
}
|
||||
|
||||
@Test // #1460
|
||||
void supportsUnquotedAttributes() {
|
||||
|
||||
assertThat(Links.parse("<https://url.com?page=1>; rel=first").getRequiredLink("first").getHref())
|
||||
.isEqualTo("https://url.com?page=1");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class HalLinkDiscovererUnitTest extends LinkDiscovererUnitTest {
|
||||
+ "title=\"pdf customer copy\";" //
|
||||
+ "type=\"portable document\";" //
|
||||
+ "deprecation=\"https://example.com/customers/deprecated\";" //
|
||||
+ "profile=\"my-profile\"" //
|
||||
+ "profile=\"my-profile\";" //
|
||||
+ "name=\"my-name\"");
|
||||
|
||||
assertThat(getDiscoverer().findLinkWithRel(IanaLinkRelations.SELF.value(), linkText)) //
|
||||
|
||||
@@ -59,7 +59,7 @@ class HalFormsLinkDiscovererUnitTest extends LinkDiscovererUnitTest {
|
||||
+ "title=\"pdf customer copy\";" //
|
||||
+ "type=\"portable document\";" //
|
||||
+ "deprecation=\"https://example.com/customers/deprecated\";" //
|
||||
+ "profile=\"my-profile\"" //
|
||||
+ "profile=\"my-profile\";" //
|
||||
+ "name=\"my-name\"");
|
||||
|
||||
assertThat(getDiscoverer().findLinkWithRel(IanaLinkRelations.SELF, linkText)) //
|
||||
|
||||
Reference in New Issue
Block a user