Separate out ReadDataParams
[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.net.URI;
17 import java.text.ParseException;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.opendaylight.restconf.nb.rfc8040.ApiPath.ApiIdentifier;
20 import org.opendaylight.yangtools.concepts.Immutable;
21
22 /**
23  * This class represents a {@code fields} parameter as defined in
24  * <a href="https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.3">RFC8040 section 4.8.3</a>.
25  */
26 @Beta
27 @NonNullByDefault
28 public final class FieldsParameter implements Immutable {
29     /**
30      * A selector for a single node as identified by {@link #path()}. Individual child nodes are subject to further
31      * filtering based on {@link #subSelectors()}.
32      */
33     public static final class NodeSelector implements Immutable {
34         private final ImmutableList<ApiIdentifier> path;
35         private final ImmutableList<NodeSelector> subSelectors;
36
37         NodeSelector(final ImmutableList<ApiIdentifier> path, final ImmutableList<NodeSelector> subSelectors) {
38             this.path = requireNonNull(path);
39             this.subSelectors = requireNonNull(subSelectors);
40             checkArgument(!path.isEmpty(), "At least path segment is required");
41         }
42
43         NodeSelector(final ImmutableList<ApiIdentifier> path) {
44             this(path, ImmutableList.of());
45         }
46
47         /**
48          * Return the path to the selected node. Guaranteed to have at least one element.
49          *
50          * @return path to the selected node
51          */
52         public ImmutableList<ApiIdentifier> path() {
53             return path;
54         }
55
56         /**
57          * Selectors for single nodes which should be selected from the node found by interpreting {@link #path}. If
58          * there are no selectors, i.e. {@code subSelectors().isEmpty())}, all child nodes are meant to be selected.
59          *
60          * @return Selectors for nested nodes.
61          */
62         public ImmutableList<NodeSelector> subSelectors() {
63             return subSelectors;
64         }
65
66         @Override
67         public String toString() {
68             final var helper = MoreObjects.toStringHelper(this).add("path", path);
69             if (!subSelectors.isEmpty()) {
70                 helper.add("subSelectors", subSelectors);
71             }
72             return helper.toString();
73         }
74     }
75
76     private static final URI CAPABILITY = URI.create("urn:ietf:params:restconf:capability:fields:1.0");
77
78     private final ImmutableList<NodeSelector> nodeSelectors;
79     private final String uriValue;
80
81     private FieldsParameter(final ImmutableList<NodeSelector> nodeSelectors, final String uriValue) {
82         this.nodeSelectors = requireNonNull(nodeSelectors);
83         checkArgument(!nodeSelectors.isEmpty(), "At least one selector is required");
84         this.uriValue = requireNonNull(uriValue);
85     }
86
87     /**
88      * Parse a {@code fields} parameter.
89      *
90      * @param str Unescaped URL string
91      * @return The contents of parameter
92      * @throws ParseException if {@code str} does not represent a valid {@code fields} parameter.
93      */
94     public static FieldsParameter parse(final String str) throws ParseException {
95         return new FieldsParameter(new FieldsParameterParser().parseNodeSelectors(str), str);
96     }
97
98     public static String uriName() {
99         return "fields";
100     }
101
102     public static URI capabilityUri() {
103         return CAPABILITY;
104     }
105
106     /**
107      * Selectors for nodes which should be reported. Guaranteed to have at least one element.
108      *
109      * @return selectors for nodes to be reported
110      */
111     public ImmutableList<NodeSelector> nodeSelectors() {
112         return nodeSelectors;
113     }
114
115     // FIXME: for migration only
116     public String uriValue() {
117         return uriValue;
118     }
119
120     @Override
121     public String toString() {
122         return MoreObjects.toStringHelper(this).add("nodeSelectors", nodeSelectors).toString();
123     }
124 }