Add RestconfQueryParam
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / WriteDataParams.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 com.google.common.base.MoreObjects;
11 import org.eclipse.jdt.annotation.NonNull;
12 import org.eclipse.jdt.annotation.Nullable;
13 import org.opendaylight.yangtools.concepts.Immutable;
14
15 /**
16  * Parser and holder of query parameters from uriInfo for data and datastore modification operations.
17  */
18 // FIXME: this should be a record with JDK17+
19 public final class WriteDataParams implements Immutable {
20     private static final @NonNull WriteDataParams EMPTY = new WriteDataParams(null, null);
21
22     private final PointParam point;
23     private final InsertParam insert;
24
25     private WriteDataParams(final InsertParam insert, final PointParam point) {
26         this.insert = insert;
27         this.point = point;
28     }
29
30     public static @NonNull WriteDataParams empty() {
31         return EMPTY;
32     }
33
34     public static @NonNull WriteDataParams of(final InsertParam insert, final PointParam point) {
35         if (point == null) {
36             if (insert == null) {
37                 return empty();
38             }
39
40             // https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.5:
41             //        If the values "before" or "after" are used, then a "point" query
42             //        parameter for the "insert" query parameter MUST also be present, or a
43             //        "400 Bad Request" status-line is returned.
44             if (insert == InsertParam.BEFORE || insert == InsertParam.AFTER) {
45                 throw new IllegalArgumentException(
46                     "Insert parameter " + insert.paramValue() + " cannot be used without a Point parameter.");
47             }
48         } else {
49             // https://datatracker.ietf.org/doc/html/rfc8040#section-4.8.6:
50             // [when "point" parameter is present and]
51             //        If the "insert" query parameter is not present or has a value other
52             //        than "before" or "after", then a "400 Bad Request" status-line is
53             //        returned.
54             if (insert != InsertParam.BEFORE && insert != InsertParam.AFTER) {
55                 throw new IllegalArgumentException(
56                     "Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
57             }
58         }
59
60         return new WriteDataParams(insert, point);
61     }
62
63     public @Nullable InsertParam insert() {
64         return insert;
65     }
66
67     public @Nullable PointParam point() {
68         return point;
69     }
70
71     @Override
72     public String toString() {
73         final var helper = MoreObjects.toStringHelper(this).omitNullValues();
74         if (insert != null) {
75             helper.add("insert", insert.paramValue());
76         }
77         if (point != null) {
78             helper.add("point", point.value());
79         }
80         return helper.toString();
81     }
82 }