checkArgument(!path.isEmpty(), "At least path segment is required");
}
- NodeSelector(final ImmutableList<ApiIdentifier> path) {
- this(path, ImmutableList.of());
- }
-
/**
* Return the path to the selected node. Guaranteed to have at least one element.
*
}
return helper.toString();
}
+
+ void appendTo(final StringBuilder sb) {
+ final var it = path.iterator();
+ appendStep(sb, it.next());
+ while (it.hasNext()) {
+ appendStep(sb.append('/'), it.next());
+ }
+
+ if (!subSelectors.isEmpty()) {
+ appendSelectors(sb.append('('), subSelectors).append(')');
+ }
+ }
+
+ private static void appendStep(final StringBuilder sb, final ApiIdentifier step) {
+ final var mod = step.module();
+ if (mod != null) {
+ sb.append(mod).append(':');
+ }
+ sb.append(step.identifier().getLocalName());
+ }
}
// API consistency: must not be confused with enum constants
private static final URI CAPABILITY = URI.create("urn:ietf:params:restconf:capability:fields:1.0");
private final ImmutableList<NodeSelector> nodeSelectors;
- private final String paramValue;
- private FieldsParam(final ImmutableList<NodeSelector> nodeSelectors, final String uriValue) {
+ FieldsParam(final ImmutableList<NodeSelector> nodeSelectors) {
this.nodeSelectors = requireNonNull(nodeSelectors);
checkArgument(!nodeSelectors.isEmpty(), "At least one selector is required");
- paramValue = requireNonNull(uriValue);
}
/**
* @throws ParseException if {@code str} does not represent a valid {@code fields} parameter.
*/
public static FieldsParam parse(final String str) throws ParseException {
- return new FieldsParam(new FieldsParameterParser().parseNodeSelectors(str), str);
+ return new FieldsParameterParser().parse(str);
}
@Override
@Override
public String paramValue() {
- return paramValue;
+ return appendSelectors(new StringBuilder(), nodeSelectors).toString();
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("nodeSelectors", nodeSelectors).toString();
}
+
+ private static StringBuilder appendSelectors(final StringBuilder sb, final ImmutableList<NodeSelector> selectors) {
+ final var it = selectors.iterator();
+ it.next().appendTo(sb);
+ while (it.hasNext()) {
+ it.next().appendTo(sb.append(';'));
+ }
+ return sb;
+ }
}
// parsers instead of ten.
private Deque<NodeSelectorParser> parsers;
- @NonNull ImmutableList<NodeSelector> parseNodeSelectors(final String str) throws ParseException {
+ @NonNull FieldsParam parse(final String str) throws ParseException {
final var nodeSelectors = ImmutableList.<NodeSelector>builder();
int idx = 0;
if (next == str.length()) {
// We have reached the end, we are done
- return nodeSelectors.build();
+ return new FieldsParam(nodeSelectors.build());
}
final char ch = str.charAt(next);
import org.opendaylight.restconf.nb.rfc8040.ApiPath.ApiIdentifier;
import org.opendaylight.restconf.nb.rfc8040.FieldsParam.NodeSelector;
-public class FieldsParameterTest {
+public class FieldsParamTest {
// https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.3:
// ";" is used to select multiple nodes. For example, to retrieve only
// the "genre" and "year" of an album, use "fields=genre;year".
}
private static List<NodeSelector> assertValidFields(final String str) {
+ final FieldsParam param;
try {
- return FieldsParam.parse(str).nodeSelectors();
+ param = FieldsParam.parse(str);
} catch (ParseException e) {
throw new AssertionError(e);
}
+
+ assertEquals(str, param.paramValue());
+ return param.nodeSelectors();
}
}