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

org.opendaylight.yangtools.yang.model.spi.DefaultSchemaTreeInference Maven / Gradle / Ivy

/*
 * Copyright (c) 2021 PANTHEON.tech, s.r.o. 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.model.spi;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.api.SchemaTreeInference;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.spi.AbstractEffectiveStatementInference.WithPath;
import org.slf4j.LoggerFactory;

/**
 * Default implementation of a {@link SchemaTreeInference}. Guaranteed to be consistent with its
 * {@link #modelContext()}.
 */
@Beta
@NonNullByDefault
public final class DefaultSchemaTreeInference extends WithPath>
        implements SchemaTreeInference {
    private static final String VERIFY_UNSAFE_PROP =
        "org.opendaylight.yangtools.yang.model.spi.DefaultSchemaTreeInference.verifyUnsafeOf";
    private static final boolean VERIFY_UNSAFE = Boolean.getBoolean(VERIFY_UNSAFE_PROP);

    static {
        if (VERIFY_UNSAFE) {
            LoggerFactory.getLogger(DefaultSchemaTreeInference.class)
                .info("DefaultSchemaTreeInference.unsafeOf() arguments are being verified");
        }
    }

    private DefaultSchemaTreeInference(final EffectiveModelContext modelContext,
            final ImmutableList> path) {
        super(modelContext, path);
    }

    /**
     * Create a new instance based on an {@link EffectiveModelContext} and an {@link Absolute} schema node identifier.
     *
     * @param modelContext Associated {@link EffectiveModelContext}
     * @param path An absolute schema node identifier
     * @return A new instance
     * @throws NullPointerException if any argument is null
     * @throws IllegalArgumentException if the provided {@code path} cannot be resolved in {@code modelContext}
     */
    public static DefaultSchemaTreeInference of(final EffectiveModelContext modelContext, final Absolute path) {
        return new DefaultSchemaTreeInference(modelContext, resolveSteps(modelContext, path.getNodeIdentifiers()));
    }

    /**
     * Create a new instance based on an {@link EffectiveModelContext} and a resolved sequence of statements. Provided
     * statements are expected to have been produced in a validated manner and are normally trusted to be accurate.
     *
     * 

* Run-time verification of {@code path} can be enabled by setting the {@value #VERIFY_UNSAFE_PROP} system property * to {@code true}. * * @param modelContext Associated {@link EffectiveModelContext} * @param path Resolved statement path * @return A new instance * @throws NullPointerException if any argument is null * @throws IllegalArgumentException if {@code path} is empty or when verification is enabled and the {@code path} * does not match the {@code modelContext}'s schema tree */ public static DefaultSchemaTreeInference unsafeOf(final EffectiveModelContext modelContext, final ImmutableList> path) { checkArgument(!path.isEmpty(), "Path must not be empty"); return VERIFY_UNSAFE ? verifiedOf(modelContext, path) : new DefaultSchemaTreeInference(modelContext, path); } @VisibleForTesting static DefaultSchemaTreeInference verifiedOf(final EffectiveModelContext modelContext, final ImmutableList> path) { final var resolved = resolveSteps(modelContext, Lists.transform(path, SchemaTreeEffectiveStatement::argument)); checkArgument(path.equals(resolved), "Provided path %s is not consistent with resolved path %s", path, resolved); return new DefaultSchemaTreeInference(modelContext, path); } private static ImmutableList> resolveSteps(final EffectiveModelContext modelContext, final List steps) { final var first = steps.get(0); final var module = modelContext.findModuleStatement(first.getModule()).orElseThrow( () -> new IllegalArgumentException("No module for " + first)); final var builder = ImmutableList.>builderWithExpectedSize(steps.size()); SchemaTreeAwareEffectiveStatement parent = module; final Iterator it = steps.iterator(); while (true) { final var qname = it.next(); final var found = parent.findSchemaTreeNode(qname).orElseThrow( () -> new IllegalArgumentException("Cannot resolve step " + qname + " in " + builder.build())); builder.add(found); if (!it.hasNext()) { break; } checkArgument(found instanceof SchemaTreeAwareEffectiveStatement, "Cannot resolve steps %s past %s", steps, found); parent = (SchemaTreeAwareEffectiveStatement) found; } return builder.build(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy