2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.dom.spi;
10 import static java.util.Objects.requireNonNull;
12 import org.eclipse.jdt.annotation.NonNull;
13 import org.opendaylight.yangtools.concepts.Identifiable;
14 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceEffectiveStatement;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
17 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
18 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
20 public abstract sealed class RpcRoutingStrategy implements Identifiable<QName> {
21 private final @NonNull QName identifier;
23 private RpcRoutingStrategy(final QName identifier) {
24 this.identifier = requireNonNull(identifier);
28 * Returns leaf QName in which RPC Route is stored.
29 * @return leaf QName in which RPC Route is stored
30 * @throws UnsupportedOperationException If RPC is not content routed.
31 * ({@link #isContextBasedRouted()} returned <code>false</code>)
33 public abstract QName getLeaf();
36 * Returns identity QName which represents RPC Routing context.
37 * @return identity QName which represents RPC Routing context
38 * @throws UnsupportedOperationException If RPC is not content routed.
39 * ({@link #isContextBasedRouted()} returned <code>false</code>)
41 public abstract QName getContext();
44 public final QName getIdentifier() {
49 * Returns true if RPC is routed by context.
51 * @return true if RPC is routed by content.
53 public abstract boolean isContextBasedRouted();
55 public static @NonNull RpcRoutingStrategy from(final RpcEffectiveStatement rpc) {
56 // FIXME: deprecate context-reference
57 return of(rpc.argument(), rpc.findFirstEffectiveSubstatement(InputEffectiveStatement.class)
58 .orElseThrow(() -> new IllegalArgumentException("Cannot find input in " + rpc)));
61 private static @NonNull RpcRoutingStrategy of(final QName rpcName, final InputEffectiveStatement input) {
62 for (var stmt : input.effectiveSubstatements()) {
63 if (stmt instanceof SchemaTreeEffectiveStatement<?> schemaStmt) {
65 stmt.findFirstEffectiveSubstatementArgument(ContextReferenceEffectiveStatement.class);
66 if (context.isPresent()) {
67 return new RoutedRpcStrategy(rpcName, context.orElseThrow(), schemaStmt.argument());
71 return new GlobalRpcStrategy(rpcName);
74 private static final class RoutedRpcStrategy extends RpcRoutingStrategy {
75 private final QName context;
76 private final QName leaf;
78 private RoutedRpcStrategy(final QName identifier, final QName ctx, final QName leaf) {
80 context = requireNonNull(ctx);
81 this.leaf = requireNonNull(leaf);
85 public QName getContext() {
90 public QName getLeaf() {
95 public boolean isContextBasedRouted() {
100 private static final class GlobalRpcStrategy extends RpcRoutingStrategy {
101 GlobalRpcStrategy(final QName identifier) {
106 public boolean isContextBasedRouted() {
111 public QName getContext() {
112 throw new UnsupportedOperationException("Non-routed strategy does not have a context");
116 public QName getLeaf() {
117 throw new UnsupportedOperationException("Non-routed strategy does not have a context");