Skip to content

Commit 8c48242

Browse files
committed
#1583 - Full support for level 4 URI templates.
Significant rewrite of UriTemplate to bring it up to level for template variables. We now additionally support: * Composite values correctly * Prefix values * Multi-value template variables * Path-style parameters * Label expansion with dot-prefix * Reserved expansion Unit tests have been enriched with all examples given in the corresponding RFC [0]. Template variable types have been aligned with the terminology used in the RFC. Currently differently named types have been deprecated in favor of the new ones. The commit slightly changes the behavior in two different aspects: 1. Query parameter values are now encoded as described in the RFC. Previously, special characters like comma (,) have not been percent encoded but now are. To create comma-separated values, expand an array of values instead of a prepared String. I.e. instead of expanding {?sort} with "foo,asc", expand it with [ "foo", "asc" ]. 2. The aspect of variable optionality has been deprecated as it doesn't actually exist for template variables. This causes expansions that were previously rejected (e.g. ones using {foo} in paths) are now not rejected anymore. This is due to the way that the expansions are defined in the RFC. [0] https://datatracker.ietf.org/doc/html/rfc6570
1 parent fff452c commit 8c48242

File tree

8 files changed

+734
-232
lines changed

8 files changed

+734
-232
lines changed

src/main/java/org/springframework/hateoas/TemplateVariable.java

Lines changed: 311 additions & 20 deletions
Large diffs are not rendered by default.

src/main/java/org/springframework/hateoas/TemplateVariables.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.List;
2727
import java.util.Objects;
2828
import java.util.stream.Collectors;
29+
import java.util.stream.Stream;
2930

3031
import org.springframework.hateoas.TemplateVariable.VariableType;
3132
import org.springframework.util.Assert;
@@ -61,7 +62,21 @@ public TemplateVariables(List<TemplateVariable> variables) {
6162
Assert.notNull(variables, "Template variables must not be null!");
6263
Assert.noNullElements(variables.toArray(), "Variables must not contain null values!");
6364

64-
this.variables = Collections.unmodifiableList(variables);
65+
boolean requestParameterFound = false;
66+
List<TemplateVariable> processed = new ArrayList<>(variables.size());
67+
68+
for (TemplateVariable variable : variables) {
69+
70+
processed.add(variable.isRequestParameterVariable() && requestParameterFound
71+
? variable.withType(REQUEST_PARAM_CONTINUED)
72+
: variable);
73+
74+
if (variable.isRequestParameterVariable()) {
75+
requestParameterFound = true;
76+
}
77+
}
78+
79+
this.variables = Collections.unmodifiableList(processed);
6580
}
6681

6782
/**
@@ -112,6 +127,10 @@ public List<TemplateVariable> asList() {
112127
return this.variables;
113128
}
114129

130+
public Stream<TemplateVariable> stream() {
131+
return this.variables.stream();
132+
}
133+
115134
private boolean containsEquivalentFor(TemplateVariable candidate) {
116135

117136
return this.variables.stream() //
@@ -165,7 +184,7 @@ String toString(boolean appended) {
165184
}
166185

167186
previous = variable;
168-
builder.append(variable.getName());
187+
builder.append(variable.essence());
169188
}
170189

171190
return builder.append("}").toString();
@@ -174,10 +193,12 @@ String toString(boolean appended) {
174193
@Override
175194
public boolean equals(Object o) {
176195

177-
if (this == o)
196+
if (this == o) {
178197
return true;
179-
if (o == null || getClass() != o.getClass())
198+
}
199+
if (o == null || getClass() != o.getClass()) {
180200
return false;
201+
}
181202
TemplateVariables that = (TemplateVariables) o;
182203
return Objects.equals(this.variables, that.variables);
183204
}

0 commit comments

Comments
 (0)