Move InstanceIdentifierContext
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / legacy / InstanceIdentifierContext.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.legacy;
9
10 import static com.google.common.base.Verify.verify;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.VisibleForTesting;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
19 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
20 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
21 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
22 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
23
24 public abstract class InstanceIdentifierContext {
25     private static final class Root extends InstanceIdentifierContext {
26         private final @NonNull EffectiveModelContext context;
27
28         Root(final EffectiveModelContext context, final DOMMountPoint mountPoint) {
29             super(context, mountPoint);
30             this.context = requireNonNull(context);
31         }
32
33         @Override
34         public EffectiveModelContext getSchemaContext() {
35             return context;
36         }
37
38         @Override
39         public YangInstanceIdentifier getInstanceIdentifier() {
40             return YangInstanceIdentifier.of();
41         }
42
43         @Override
44         public Inference inference() {
45             return SchemaInferenceStack.of(context).toInference();
46         }
47     }
48
49     private static final class DataPath extends InstanceIdentifierContext {
50         private final @NonNull YangInstanceIdentifier path;
51         private final @NonNull SchemaInferenceStack stack;
52
53         private DataPath(final SchemaNode schemaNode, final DOMMountPoint mountPoint,
54                 final SchemaInferenceStack stack, final YangInstanceIdentifier path) {
55             super(schemaNode, mountPoint);
56             this.stack = requireNonNull(stack);
57             this.path = requireNonNull(path);
58         }
59
60         static @NonNull DataPath of(final EffectiveModelContext context, final YangInstanceIdentifier path,
61                 final DOMMountPoint mountPoint) {
62             final var nodeAndStack = DataSchemaContextTree.from(context).enterPath(path).orElseThrow();
63             return new DataPath(nodeAndStack.node().dataSchemaNode(), mountPoint, nodeAndStack.stack(), path);
64         }
65
66         @Override
67         public YangInstanceIdentifier getInstanceIdentifier() {
68             return path;
69         }
70
71         @Override
72         public Inference inference() {
73             return stack.toInference();
74         }
75     }
76
77     private static final class WithoutDataPath extends InstanceIdentifierContext {
78         private final @NonNull SchemaInferenceStack stack;
79
80         private WithoutDataPath(final SchemaNode schemaNode, final DOMMountPoint mountPoint,
81                 final SchemaInferenceStack stack) {
82             super(schemaNode, mountPoint);
83             this.stack = requireNonNull(stack);
84         }
85
86         @Override
87         public Inference inference() {
88             return stack.toInference();
89         }
90
91         @Override
92         public @Nullable YangInstanceIdentifier getInstanceIdentifier() {
93             return null;
94         }
95     }
96
97     private final @NonNull SchemaNode schemaNode;
98     private final @Nullable DOMMountPoint mountPoint;
99
100     InstanceIdentifierContext(final SchemaNode schemaNode, final DOMMountPoint mountPoint) {
101         this.schemaNode = requireNonNull(schemaNode);
102         this.mountPoint = mountPoint;
103     }
104
105     public static @NonNull InstanceIdentifierContext ofLocalRoot(final EffectiveModelContext context) {
106         return new Root(context, null);
107     }
108
109     @VisibleForTesting
110     public static @NonNull InstanceIdentifierContext ofLocalPath(final EffectiveModelContext context,
111             final YangInstanceIdentifier path) {
112         return DataPath.of(context, path, null);
113     }
114
115     // Invocations of various identifier-less details
116     public static @NonNull InstanceIdentifierContext ofStack(final SchemaInferenceStack stack) {
117         return ofStack(stack, null);
118     }
119
120     // Invocations of various identifier-less details, potentially having a mount point
121     public static @NonNull InstanceIdentifierContext ofStack(final SchemaInferenceStack stack,
122             final @Nullable DOMMountPoint mountPoint) {
123         final SchemaNode schemaNode;
124         if (!stack.isEmpty()) {
125             final var stmt = stack.currentStatement();
126             verify(stmt instanceof SchemaNode, "Unexpected statement %s", stmt);
127             schemaNode = (SchemaNode) stmt;
128         } else {
129             schemaNode = stack.getEffectiveModelContext();
130         }
131
132         return new WithoutDataPath(schemaNode, mountPoint, stack);
133     }
134
135     public static @NonNull InstanceIdentifierContext ofPath(final SchemaInferenceStack stack,
136             final SchemaNode schemaNode, final YangInstanceIdentifier path,
137             final @Nullable DOMMountPoint mountPoint) {
138         return new DataPath(schemaNode, mountPoint, stack, path);
139     }
140
141     public static @NonNull InstanceIdentifierContext ofMountPointRoot(final DOMMountPoint mountPoint,
142             final EffectiveModelContext mountContext) {
143         return new Root(mountContext, requireNonNull(mountPoint));
144     }
145
146     @VisibleForTesting
147     public static @NonNull InstanceIdentifierContext ofMountPointPath(final DOMMountPoint mountPoint,
148             final EffectiveModelContext context, final YangInstanceIdentifier path) {
149         return DataPath.of(context, path, requireNonNull(mountPoint));
150     }
151
152     public final @NonNull SchemaNode getSchemaNode() {
153         return schemaNode;
154     }
155
156     public final @Nullable DOMMountPoint getMountPoint() {
157         return mountPoint;
158     }
159
160     public @NonNull EffectiveModelContext getSchemaContext() {
161         return inference().getEffectiveModelContext();
162     }
163
164     public abstract @NonNull Inference inference();
165
166     public abstract @Nullable YangInstanceIdentifier getInstanceIdentifier();
167 }