Rename DOMDataTreeChangeService
[mdsal.git] / dom / mdsal-dom-spi / src / main / java / org / opendaylight / mdsal / dom / spi / ContentRoutedRpcContext.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  * Copyright (c) 2022 PANTHEON.tech, s.r.o.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9 package org.opendaylight.mdsal.dom.spi;
10
11 import static java.util.Objects.requireNonNull;
12
13 import org.eclipse.jdt.annotation.NonNull;
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceEffectiveStatement;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
18 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
19
20 /**
21  * Information pertaining to the concept of {@code Routed RPCs}. "Routed" in this context means being bound to a certain
22  * data tree node, identified by a {@code leaf} within the RPC input. This is very much similar to a RFC7950
23  * {@code action}, except it operates strictly within the confines of RFC6020.
24  *
25  * @param identity QName which refers RPC Routing context {@code identity}
26  * @param leaf QName of the leaf in which RPC Route is stored
27  */
28 public record ContentRoutedRpcContext(@NonNull QName identity, @NonNull QName leaf) {
29     public ContentRoutedRpcContext {
30         requireNonNull(identity);
31         requireNonNull(identity);
32     }
33
34     /**
35      * Attempt to construct a {@link ContentRoutedRpcContext} for a particular {@code rpc}.
36      *
37      * @param rpc RPC statement
38      * @return A {@link ContentRoutedRpcContext}, or {@code null} if the RPC does not contain context information
39      */
40     public static @Nullable ContentRoutedRpcContext forRpc(final RpcEffectiveStatement rpc) {
41         for (var stmt : rpc.input().effectiveSubstatements()) {
42             // TODO: LeafEffectiveStatement instead? Because that is what we are promising for #leaf()'s QName
43             if (stmt instanceof SchemaTreeEffectiveStatement<?> schemaStmt) {
44                 final var context =
45                     stmt.findFirstEffectiveSubstatementArgument(ContextReferenceEffectiveStatement.class);
46                 if (context.isPresent()) {
47                     return new ContentRoutedRpcContext(context.orElseThrow(), schemaStmt.argument());
48                 }
49             }
50         }
51         return null;
52     }
53 }