#137 - Improved TemplateVariables to combine variables.

Request parameters variables {?…} and continued ones {&…} are now combined by TemplateVariables. Improved detection of the base URI and adapted the rendering logic accordingly. UriTemplates can now be augmented with additional TemplateVariables.

Added equals(…) and hashCode() methods for TempalteVariables.
This commit is contained in:
Oliver Gierke
2014-01-23 14:09:35 +01:00
parent c790a5d834
commit 9caa352470
5 changed files with 142 additions and 12 deletions

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.hateoas;
import java.util.Arrays;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -109,8 +112,8 @@ public final class TemplateVariable {
* @param variable must not be {@literal null}.
* @return
*/
boolean isOfSameTypeAs(TemplateVariable variable) {
return this.type.equals(variable.type);
boolean isCombinable(TemplateVariable variable) {
return this.type.canBeCombinedWith(variable.type);
}
/*
@@ -171,6 +174,8 @@ public final class TemplateVariable {
SEGMENT("/", true), //
FRAGMENT("#", true);
private static final List<VariableType> combinableTypes = Arrays.asList(REQUEST_PARAM, REQUEST_PARAM_CONTINUED);
private final String key;
private final boolean optional;
@@ -188,6 +193,10 @@ public final class TemplateVariable {
return optional;
}
public boolean canBeCombinedWith(VariableType type) {
return this.equals(type) || combinableTypes.contains(this) && combinableTypes.contains(type);
}
/**
* Returns the {@link VariableType} for the given variable key.
*

View File

@@ -125,7 +125,7 @@ public final class TemplateVariables implements Iterable<TemplateVariable> {
if (previous == null) {
builder.append("{").append(variable.getType().toString());
} else if (!previous.isOfSameTypeAs(variable)) {
} else if (!previous.isCombinable(variable)) {
builder.append("}{").append(variable.getType().toString());
} else {
builder.append(",");
@@ -137,4 +137,33 @@ public final class TemplateVariables implements Iterable<TemplateVariable> {
return builder.append("}").toString();
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof TemplateVariables)) {
return false;
}
TemplateVariables that = (TemplateVariables) obj;
return this.variables.equals(that.variables);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return this.variables.hashCode();
}
}

View File

@@ -60,15 +60,17 @@ public class UriTemplate implements Iterable<TemplateVariable> {
int start = matcher.start(0);
if (start < baseUriEndIndex) {
baseUriEndIndex = start;
}
VariableType type = VariableType.from(matcher.group(1));
String[] names = matcher.group(2).split(",");
for (String name : names) {
variables.add(new TemplateVariable(name, type));
TemplateVariable variable = new TemplateVariable(name, type);
if (!variable.isRequired() && start < baseUriEndIndex) {
baseUriEndIndex = start;
}
variables.add(variable);
}
}
@@ -90,6 +92,21 @@ public class UriTemplate implements Iterable<TemplateVariable> {
this.variables = variables == null ? TemplateVariables.NONE : variables;
}
/**
* Creates a new {@link UriTemplate} with the current {@link TemplateVariable}s augmented with the given ones.
*
* @param variables can be {@literal null}.
* @return
*/
public UriTemplate with(TemplateVariables variables) {
if (variables == null) {
return this;
}
return new UriTemplate(baseUri, this.variables.concat(variables));
}
/**
* Returns whether the given candidate is a URI template.
*
@@ -193,7 +210,20 @@ public class UriTemplate implements Iterable<TemplateVariable> {
*/
@Override
public String toString() {
return baseUri + variables.toString();
return baseUri + getOptionalVariables().toString();
}
private TemplateVariables getOptionalVariables() {
List<TemplateVariable> result = new ArrayList<TemplateVariable>();
for (TemplateVariable variable : this) {
if (!variable.isRequired()) {
result.add(variable);
}
}
return new TemplateVariables(result);
}
/**