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.restconf.common.context;
10 import static com.google.common.base.Verify.verify;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.VisibleForTesting;
14 import com.google.common.collect.Iterables;
15 import java.util.List;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
21 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
22 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
23 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
24 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
25 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
26 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
28 public abstract class InstanceIdentifierContext {
29 private static final class Root extends InstanceIdentifierContext {
30 private final @NonNull EffectiveModelContext context;
32 Root(final EffectiveModelContext context, final DOMMountPoint mountPoint) {
33 super(context, mountPoint);
34 this.context = requireNonNull(context);
38 public EffectiveModelContext getSchemaContext() {
43 public YangInstanceIdentifier getInstanceIdentifier() {
44 return YangInstanceIdentifier.of();
48 public Inference inference() {
49 return SchemaInferenceStack.of(context).toInference();
53 InstanceIdentifierContext createWithConcapt(final List<PathArgument> concatArgs) {
54 return new DataPath(context, getMountPoint(), SchemaInferenceStack.of(context),
55 YangInstanceIdentifier.of(concatArgs));
59 private static final class DataPath extends InstanceIdentifierContext {
60 private final @NonNull YangInstanceIdentifier path;
61 private final @NonNull SchemaInferenceStack stack;
63 private DataPath(final SchemaNode schemaNode, final DOMMountPoint mountPoint,
64 final SchemaInferenceStack stack, final YangInstanceIdentifier path) {
65 super(schemaNode, mountPoint);
66 this.stack = requireNonNull(stack);
67 this.path = requireNonNull(path);
70 static @NonNull DataPath of(final EffectiveModelContext context, final YangInstanceIdentifier path,
71 final DOMMountPoint mountPoint) {
72 final var nodeAndStack = DataSchemaContextTree.from(context).enterPath(path).orElseThrow();
73 return new DataPath(nodeAndStack.node().dataSchemaNode(), mountPoint, nodeAndStack.stack(), path);
77 public YangInstanceIdentifier getInstanceIdentifier() {
82 public Inference inference() {
83 return stack.toInference();
88 InstanceIdentifierContext createWithConcapt(final List<PathArgument> concatArgs) {
89 final var newInstanceIdentifier = YangInstanceIdentifier.of(
90 Iterables.concat(path.getPathArguments(), concatArgs));
91 return new DataPath(getSchemaNode(), getMountPoint(), stack, newInstanceIdentifier);
95 private static final class WithoutDataPath extends InstanceIdentifierContext {
96 private final @NonNull SchemaInferenceStack stack;
98 private WithoutDataPath(final SchemaNode schemaNode, final DOMMountPoint mountPoint,
99 final SchemaInferenceStack stack) {
100 super(schemaNode, mountPoint);
101 this.stack = requireNonNull(stack);
105 public Inference inference() {
106 return stack.toInference();
110 public @Nullable YangInstanceIdentifier getInstanceIdentifier() {
115 InstanceIdentifierContext createWithConcapt(final List<PathArgument> concatArgs) {
120 private final @NonNull SchemaNode schemaNode;
121 private final @Nullable DOMMountPoint mountPoint;
123 InstanceIdentifierContext(final SchemaNode schemaNode, final DOMMountPoint mountPoint) {
124 this.schemaNode = requireNonNull(schemaNode);
125 this.mountPoint = mountPoint;
128 public static @NonNull InstanceIdentifierContext ofLocalRoot(final EffectiveModelContext context) {
129 return new Root(context, null);
133 public static @NonNull InstanceIdentifierContext ofLocalPath(final EffectiveModelContext context,
134 final YangInstanceIdentifier path) {
135 return DataPath.of(context, path, null);
138 // Legacy bierman02 invokeRpc()
139 public static @NonNull InstanceIdentifierContext ofRpcInput(final EffectiveModelContext context,
140 // FIXME: this this method really needed?
141 final RpcDefinition rpc, final @Nullable DOMMountPoint mountPoint) {
142 final var stack = SchemaInferenceStack.of(context);
143 stack.enterSchemaTree(rpc.getQName());
144 stack.enterSchemaTree(rpc.getInput().getQName());
145 return new WithoutDataPath(rpc, mountPoint, stack);
148 public static @NonNull InstanceIdentifierContext ofRpcOutput(final EffectiveModelContext context,
149 // FIXME: this this method really needed?
150 final RpcDefinition rpc, final @Nullable DOMMountPoint mountPoint) {
151 final var stack = SchemaInferenceStack.of(context);
152 stack.enterSchemaTree(rpc.getQName());
153 stack.enterSchemaTree(rpc.getOutput().getQName());
154 return new WithoutDataPath(rpc, mountPoint, stack);
157 // Invocations of various identifier-less details
158 public static @NonNull InstanceIdentifierContext ofStack(final SchemaInferenceStack stack) {
159 return ofStack(stack, null);
162 // Invocations of various identifier-less details, potentially having a mount point
163 public static @NonNull InstanceIdentifierContext ofStack(final SchemaInferenceStack stack,
164 final @Nullable DOMMountPoint mountPoint) {
165 final SchemaNode schemaNode;
166 if (!stack.isEmpty()) {
167 final var stmt = stack.currentStatement();
168 verify(stmt instanceof SchemaNode, "Unexpected statement %s", stmt);
169 schemaNode = (SchemaNode) stmt;
171 schemaNode = stack.getEffectiveModelContext();
174 return new WithoutDataPath(schemaNode, mountPoint, stack);
177 public static @NonNull InstanceIdentifierContext ofLocalRpcInput(final EffectiveModelContext context,
178 // FIXME: this this method really needed?
179 final RpcDefinition rpc) {
180 final var stack = SchemaInferenceStack.of(context);
181 stack.enterSchemaTree(rpc.getQName());
182 stack.enterSchemaTree(rpc.getInput().getQName());
183 return new WithoutDataPath(rpc.getInput(), null, stack);
186 public static @NonNull InstanceIdentifierContext ofLocalRpcOutput(final EffectiveModelContext context,
187 // FIXME: we want to re-validate this, so might as well take a QName
188 final RpcDefinition rpc) {
189 final var stack = SchemaInferenceStack.of(context);
190 stack.enterSchemaTree(rpc.getQName());
191 stack.enterSchemaTree(rpc.getOutput().getQName());
192 return new WithoutDataPath(rpc, null, stack);
195 public static @NonNull InstanceIdentifierContext ofPath(final SchemaInferenceStack stack,
196 final SchemaNode schemaNode, final YangInstanceIdentifier path,
197 final @Nullable DOMMountPoint mountPoint) {
198 return new DataPath(schemaNode, mountPoint, stack, path);
201 public static @NonNull InstanceIdentifierContext ofMountPointRoot(final DOMMountPoint mountPoint,
202 final EffectiveModelContext mountContext) {
203 return new Root(mountContext, requireNonNull(mountPoint));
207 public static @NonNull InstanceIdentifierContext ofMountPointPath(final DOMMountPoint mountPoint,
208 final EffectiveModelContext context, final YangInstanceIdentifier path) {
209 return DataPath.of(context, path, requireNonNull(mountPoint));
212 public static @NonNull InstanceIdentifierContext ofMountPointRpcOutput(final DOMMountPoint mountPoint,
213 final EffectiveModelContext mountContext, final RpcDefinition rpc) {
214 final var stack = SchemaInferenceStack.of(mountContext);
215 stack.enterSchemaTree(rpc.getQName());
216 stack.enterSchemaTree(rpc.getOutput().getQName());
217 return new WithoutDataPath(rpc, requireNonNull(mountPoint), stack);
220 // FIXME: what the heck are the callers of this doing?!
221 public final @NonNull InstanceIdentifierContext withConcatenatedArgs(final List<PathArgument> concatArgs) {
222 return concatArgs.isEmpty() ? this : createWithConcapt(concatArgs);
225 abstract @NonNull InstanceIdentifierContext createWithConcapt(List<PathArgument> concatArgs);
227 public final @NonNull SchemaNode getSchemaNode() {
231 public final @Nullable DOMMountPoint getMountPoint() {
235 public @NonNull EffectiveModelContext getSchemaContext() {
236 return inference().getEffectiveModelContext();
239 public abstract @NonNull Inference inference();
241 public abstract @Nullable YangInstanceIdentifier getInstanceIdentifier();