All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.yangtools.yang.data.util.DataSchemaContext Maven / Gradle / Ivy

There is a newer version: 14.0.4
Show newest version
/*
 * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.yangtools.yang.data.util;

import static java.util.Objects.requireNonNull;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
import org.opendaylight.yangtools.yang.data.api.schema.ValueNode;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContext.Composite;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContext.SimpleValue;
import org.opendaylight.yangtools.yang.data.util.impl.context.AbstractCompositeContext;
import org.opendaylight.yangtools.yang.data.util.impl.context.AbstractContext;
import org.opendaylight.yangtools.yang.data.util.impl.context.AbstractPathMixinContext;
import org.opendaylight.yangtools.yang.data.util.impl.context.AbstractValueContext;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;

/**
 * Schema derived data providing necessary information for mapping between
 * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} and serialization format defined in RFC6020,
 * since the mapping is not one-to-one.
 */
public sealed interface DataSchemaContext permits AbstractContext, Composite, SimpleValue {
    /**
     * A {@link DataSchemaContext} containing other {@link DataSchemaContext}s.
     */
    sealed interface Composite extends DataSchemaContext permits PathMixin, AbstractCompositeContext {
        /**
         * Find a child node identifier by its {@link PathArgument}.
         *
         * @param arg Child path argument
         * @return A child node, or {@code null} if not found
         * @throws NullPointerException if {@code arg} is {@code null}
         */
        @Nullable DataSchemaContext childByArg(PathArgument arg);

        /**
         * Find a child node identifier by its {code data tree} {@link QName}. This method returns intermediate nodes
         * significant from {@link YangInstanceIdentifier} hierarchy of {@link PathArgument}s. If the returned node
         * indicates is also a {@link PathMixin}, it represents a {@link NormalizedNode} encapsulation which is not
         * visible in RFC7950 XML encoding, and a further call to this method with the same {@code child} argument will
         * provide the next step.
         *
         * @param qname Child data tree QName
         * @return A child node, or {@code null} if not found
         * @throws NullPointerException if {@code arg} is {@code null}
         */
        @Nullable DataSchemaContext childByQName(QName qname);

        /**
         * Find a child node as identified by a {@link YangInstanceIdentifier} relative to this node.
         *
         * @param path Path towards the child node
         * @return Child node if present, or empty when corresponding child is not found.
         * @throws NullPointerException if {@code path} is {@code null}
         */
        default @Nullable DataSchemaContext childByPath(final @NonNull YangInstanceIdentifier path) {
            final var it = path.getPathArguments().iterator();
            if (!it.hasNext()) {
                return this;
            }

            var current = this;
            while (true) {
                final var child = current.childByArg(it.next());
                if (child == null || !it.hasNext()) {
                    return child;
                }
                if (!(child instanceof Composite compositeChild)) {
                    return null;
                }
                current = compositeChild;
            }
        }

        /**
         * Attempt to enter a child {@link DataSchemaContext} towards the {@link DataSchemaNode} child identified by
         * specified {@code data tree} {@link QName}, adjusting provided {@code stack} with inference steps
         * corresponding to the transition to the returned node. The stack is expected to be correctly pointing at this
         * node's schema, otherwise the results of this method are undefined.
         *
         * @param stack {@link SchemaInferenceStack} to update
         * @param child Child QName
         * @return A DataSchemaContextNode on the path towards the specified child
         * @throws NullPointerException if any argument is {@code null}
         */
        @Nullable DataSchemaContext enterChild(SchemaInferenceStack stack, QName child);

        /**
         * Attempt to enter a child {@link DataSchemaContext} towards the {@link DataSchemaNode} child identified by
         * specified {@link PathArgument}, adjusting provided {@code stack} with inference steps corresponding to
         * the transition to the returned node. The stack is expected to be correctly pointing at this node's schema,
         * otherwise the results of this method are undefined.
         *
         * @param stack {@link SchemaInferenceStack} to update
         * @param child Child path argument
         * @return A DataSchemaContextNode for the specified child
         * @throws NullPointerException if any argument is {@code null}
         */
        @Nullable DataSchemaContext enterChild(SchemaInferenceStack stack, PathArgument child);
    }

    /**
    * This node is a {@link NormalizedNode} intermediate, not represented in RFC7950 XML encoding. This is typically
    * one of
    * 
    *
  • {@link ChoiceNode} backed by a {@link ChoiceSchemaNode}, or
  • *
  • {@link LeafSetNode} backed by a {@link LeafListSchemaNode}, or
  • *
  • {@link MapNode} backed by a {@link ListSchemaNode} with a non-empty * {@link ListSchemaNode#getKeyDefinition()}, or
  • *
  • {@link UnkeyedListNode} backed by a {@link ListSchemaNode} with an empty * {@link ListSchemaNode#getKeyDefinition()}
  • *
* *

* This trait is important for XML codec, but also for JSON encoding of {@link YangInstanceIdentifier}. */ sealed interface PathMixin extends Composite permits AbstractPathMixinContext { /** * The mixed-in {@link NodeIdentifier}. * * @return Mixed-in NodeIdentifier */ default @NonNull NodeIdentifier mixinPathStep() { return getPathStep(); } } /** * Marker interface for contexts which boil down to a simple, not-structured {@link ValueNode}. This can be one of *

    *
  • {@link LeafNode} backed by a {@link LeafSchemaNode}, or
  • *
  • {@link LeafSetNode} backed by a {@link LeafListSchemaNode}
  • *
* *

* This trait interface is exposed for determining that the corresponding {@link TypeDefinition} of the normalized * body. */ sealed interface SimpleValue extends DataSchemaContext permits AbstractValueContext { /** * Return the {@link TypeDefinition} of the type backing this context. * * @return A {@link TypeDefinition} */ // FIXME: YANGTOOLS-1528: return yang.data.api.type.NormalizedType @NonNull TypeDefinition type(); } /** * Get a {@link DataSchemaContext} for a particular {@link DataSchemaNode}. * * @param schema Backing DataSchemaNode * @return A {@link DataSchemaContext} * @throws NullPointerException if {@code schema} is {@code null} * @throws IllegalStateException if {@code schema} is not handled */ static @NonNull DataSchemaContext of(final DataSchemaNode schema) { return AbstractContext.of(requireNonNull(schema)); } @NonNull DataSchemaNode dataSchemaNode(); /** * Return the fixed {@link YangInstanceIdentifier} step, if available. This method returns {@code null} for contexts * like {@link MapEntryNode} and {@link LeafSetEntryNode}, where the step depends on the actual node value. * * @return A {@link NodeIdentifier}, or {@code null} */ @Nullable NodeIdentifier pathStep(); /** * Return the fixed {@link YangInstanceIdentifier} step. * * @return A {@link NodeIdentifier} * @throws UnsupportedOperationException if this node does not have fixed step */ default @NonNull NodeIdentifier getPathStep() { final var arg = pathStep(); if (arg != null) { return arg; } throw new UnsupportedOperationException(this + " does not have a fixed path step"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy