e8290ad871714a976e048b324c6f787de43e02ef
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / FieldsParameter.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.restconf.nb.rfc8040;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.base.MoreObjects;
15 import com.google.common.collect.ImmutableList;
16 import java.text.ParseException;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.opendaylight.restconf.nb.rfc8040.ApiPath.ApiIdentifier;
19 import org.opendaylight.yangtools.concepts.Immutable;
20
21 /**
22  * This class represents a "fields" parameter as defined in
23  * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.3">RFC8040 section 4.8.3</a>.
24  */
25 @Beta
26 @NonNullByDefault
27 public final class FieldsParameter implements Immutable {
28     /**
29      * A selector for a single node as identified by {@link #path()}. Individual child nodes are subject to further
30      * filtering based on {@link #subSelectors()}.
31      */
32     public static final class NodeSelector implements Immutable {
33         private final ImmutableList<ApiIdentifier> path;
34         private final ImmutableList<NodeSelector> subSelectors;
35
36         NodeSelector(final ImmutableList<ApiIdentifier> path, final ImmutableList<NodeSelector> subSelectors) {
37             this.path = requireNonNull(path);
38             this.subSelectors = requireNonNull(subSelectors);
39             checkArgument(!path.isEmpty(), "At least path segment is required");
40         }
41
42         NodeSelector(final ImmutableList<ApiIdentifier> path) {
43             this(path, ImmutableList.of());
44         }
45
46         /**
47          * Return the path to the selected node. Guaranteed to have at least one element.
48          *
49          * @return path to the selected node
50          */
51         public ImmutableList<ApiIdentifier> path() {
52             return path;
53         }
54
55         /**
56          * Selectors for single nodes which should be selected from the node found by interpreting {@link #path}. If
57          * there are no selectors, i.e. {@code subSelectors().isEmpty())}, all child nodes are meant to be selected.
58          *
59          * @return Selectors for nested nodes.
60          */
61         public ImmutableList<NodeSelector> subSelectors() {
62             return subSelectors;
63         }
64
65         @Override
66         public String toString() {
67             final var helper = MoreObjects.toStringHelper(this).add("path", path);
68             if (!subSelectors.isEmpty()) {
69                 helper.add("subSelectors", subSelectors);
70             }
71             return helper.toString();
72         }
73     }
74
75     private final ImmutableList<NodeSelector> nodeSelectors;
76
77     FieldsParameter(final ImmutableList<NodeSelector> nodeSelectors) {
78         this.nodeSelectors = requireNonNull(nodeSelectors);
79         checkArgument(!nodeSelectors.isEmpty(), "At least one selector is required");
80     }
81
82     /**
83      * Parse a {@code fields} parameter.
84      *
85      * @param str Unescaped URL string
86      * @return The contents of parameter
87      * @throws ParseException if {@code str} does not represent a valid {@code fields} parameter.
88      */
89     public static FieldsParameter parse(final String str) throws ParseException {
90         return new FieldsParameterParser().parse(str);
91     }
92
93     /**
94      * Selectors for nodes which should be reported. Guaranteed to have at least one element.
95      *
96      * @return selectors for nodes to be reported
97      */
98     public ImmutableList<NodeSelector> nodeSelectors() {
99         return nodeSelectors;
100     }
101
102     @Override
103     public String toString() {
104         return MoreObjects.toStringHelper(this).add("nodeSelectors", nodeSelectors).toString();
105     }
106 }