From: Robert Varga Date: Wed, 10 Feb 2021 10:43:47 +0000 (+0100) Subject: Convert SchemaTracker to use SchemaInferenceStack X-Git-Tag: v7.0.0~161 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F11%2F95111%2F4;p=yangtools.git Convert SchemaTracker to use SchemaInferenceStack SchemaTracker's users always expect an instantiated path, for which SchemaInferenceStack is much more efficient than SchemaNodeUtils. JIRA: YANGTOOLS-1230 Change-Id: I24edb3595b5dab936790d4f5d77ecdcded1a1b1e Signed-off-by: Robert Varga --- diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/SchemaTracker.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/SchemaTracker.java index 4c6ad2013f..cbe0516211 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/SchemaTracker.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/SchemaTracker.java @@ -14,9 +14,7 @@ import com.google.common.annotations.Beta; import com.google.common.collect.Iterables; import java.io.IOException; import java.util.ArrayDeque; -import java.util.Collection; import java.util.Deque; -import java.util.List; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; @@ -44,18 +42,22 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema; +import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Utility class for tracking the underlying state of the underlying - * schema node. + * Utility class for tracking the underlying state of the underlying schema node. */ @Beta public final class SchemaTracker { private static final Logger LOG = LoggerFactory.getLogger(SchemaTracker.class); + private final Deque schemaStack = new ArrayDeque<>(); private final DataNodeContainer root; @@ -63,11 +65,22 @@ public final class SchemaTracker { this.root = requireNonNull(root); } + private static @NonNull SchemaTracker create(final SchemaInferenceStack root) { + if (root.isEmpty()) { + return new SchemaTracker(root.getEffectiveModelContext()); + } + + final EffectiveStatement current = root.currentStatement(); + checkArgument(current instanceof DataNodeContainer, "Cannot instantiate on %s", current); + return new SchemaTracker((DataNodeContainer) current); + } + /** * Create a new writer with the specified node as its root. * * @param root Root node * @return A new {@link NormalizedNodeStreamWriter} + * @throws NullPointerException if {@code root} is null */ public static @NonNull SchemaTracker create(final DataNodeContainer root) { return new SchemaTracker(root); @@ -78,10 +91,12 @@ public final class SchemaTracker { * * @param context Associated {@link EffectiveModelContext} * @param path schema path - * @return A new {@link NormalizedNodeStreamWriter} + * @return A new {@link SchemaTracker} + * @throws NullPointerException if any argument is null + * @throws IllegalArgumentException if {@code path} does not point to a valid root */ public static @NonNull SchemaTracker create(final EffectiveModelContext context, final Absolute path) { - return create(context, path.getNodeIdentifiers()); + return create(SchemaInferenceStack.of(context, path)); } /** @@ -89,25 +104,12 @@ public final class SchemaTracker { * * @param context Associated {@link EffectiveModelContext} * @param path schema path - * @return A new {@link NormalizedNodeStreamWriter} + * @return A new {@link SchemaTracker} + * @throws NullPointerException if any argument is null + * @throws IllegalArgumentException if {@code path} does not point to a valid root */ public static @NonNull SchemaTracker create(final EffectiveModelContext context, final SchemaPath path) { - return create(context, path.getPathFromRoot()); - } - - private static @NonNull SchemaTracker create(final EffectiveModelContext context, final Iterable path) { - final Collection schemaNodes = SchemaUtils.findParentSchemaNodesOnPath(context, path); - checkArgument(!schemaNodes.isEmpty(), "Unable to find schema node for supplied schema path: %s", path); - if (schemaNodes.size() > 1) { - LOG.warn("More possible schema nodes {} for supplied schema path {}", schemaNodes, path); - } - final Optional current = schemaNodes.stream() - .filter(node -> node instanceof DataNodeContainer).map(DataNodeContainer.class::cast) - .findFirst(); - checkArgument(current.isPresent(), - "Schema path must point to container or list or an rpc input/output. Supplied path %s pointed to: %s", - path, current); - return new SchemaTracker(current.get()); + return create(SchemaInferenceStack.ofInstantiatedPath(context, path)); } /** @@ -117,10 +119,18 @@ public final class SchemaTracker { * @param operation Operation schema path * @param qname Input/Output container QName * @return A new {@link NormalizedNodeStreamWriter} + * @throws NullPointerException if any argument is null + * @throws IllegalArgumentException if {@code operation} does not point to an actual operation or if {@code qname} + * does not identify a valid root underneath it. */ public static @NonNull SchemaTracker forOperation(final EffectiveModelContext context, final Absolute operation, final QName qname) { - return create(context, Iterables.concat(operation.getNodeIdentifiers(), List.of(qname))); + final SchemaInferenceStack stack = SchemaInferenceStack.of(context, operation); + final EffectiveStatement current = stack.currentStatement(); + checkArgument(current instanceof RpcEffectiveStatement || current instanceof ActionEffectiveStatement, + "Path %s resolved into non-operation %s", operation, current); + stack.enterSchemaTree(qname); + return create(stack); } public Object getParent() {