Optimize RestconfStrategy.postData()
[netconf.git] / restconf / restconf-nb / 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.restconf.api.query.InsertParam;
14 import org.opendaylight.restconf.api.query.PointParam;
15 import org.opendaylight.yangtools.concepts.Immutable;
16
17 /**
18  * Parser and holder of query parameters from uriInfo for data and datastore modification operations.
19  */
20 // FIXME: this should be a record with JDK17+
21 public final class WriteDataParams implements Immutable {
22     private static final @NonNull WriteDataParams EMPTY = new WriteDataParams(null, null);
23
24     private final PointParam point;
25     private final InsertParam insert;
26
27     private WriteDataParams(final InsertParam insert, final PointParam point) {
28         this.insert = insert;
29         this.point = point;
30     }
31
32     public static @NonNull WriteDataParams empty() {
33         return EMPTY;
34     }
35
36     public static @NonNull WriteDataParams of(final InsertParam insert, final PointParam point) {
37         if (point == null) {
38             if (insert == null) {
39                 return empty();
40             }
41
42             // https://www.rfc-editor.org/rfc/rfc8040#section-4.8.5:
43             //        If the values "before" or "after" are used, then a "point" query
44             //        parameter for the "insert" query parameter MUST also be present, or a
45             //        "400 Bad Request" status-line is returned.
46             if (insert == InsertParam.BEFORE || insert == InsertParam.AFTER) {
47                 throw new IllegalArgumentException(
48                     "Insert parameter " + insert.paramValue() + " cannot be used without a Point parameter.");
49             }
50         } else if (insert != InsertParam.BEFORE && insert != InsertParam.AFTER) {
51             // https://www.rfc-editor.org/rfc/rfc8040#section-4.8.6:
52             // [when "point" parameter is present and]
53             //        If the "insert" query parameter is not present or has a value other
54             //        than "before" or "after", then a "400 Bad Request" status-line is
55             //        returned.
56             throw new IllegalArgumentException(
57                 "Point parameter can be used only with 'after' or 'before' values of Insert parameter.");
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 }