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

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

/*
 * Copyright (c) 2017 Pantheon Technologies, 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 java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.rfc7952.model.api.AnnotationSchemaNode;
import org.opendaylight.yangtools.rfc7952.model.api.AnnotationSchemaNodeAwareSchemaContext;
import org.opendaylight.yangtools.yang.common.AnnotationName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.yangtools.yang.model.api.Module;

/**
 * Simple subclass of {@link AbstractSchemaContext} which performs some amount of indexing to speed up common
 * SchemaContext operations. This implementation assumes input modules are consistent and does not perform
 * any extensive analysis to ensure the resulting object complies to SchemaContext interface.
 */
@Beta
public class SimpleSchemaContext extends AbstractSchemaContext implements AnnotationSchemaNodeAwareSchemaContext {
    private final ImmutableSetMultimap namespaceToModules;
    private final ImmutableSetMultimap nameToModules;
    private final ImmutableMap moduleMap;
    private final ImmutableSet modules;
    private final ImmutableMap annotations;

    protected SimpleSchemaContext(final Collection modules) {
        /*
         * Instead of doing this on each invocation of getModules(), pre-compute it once and keep it around -- better
         * than the set we got in.
         *
         * Note we are performing two sort operations: the dependency sort takes care of detecting multiple imports,
         * performing sorting as a side-effect, but we really want the modules sorted to comply with getModules().
         */
        final List sortedModules = new ArrayList<>(ModuleDependencySort.sort(modules));
        sortedModules.sort(NAME_REVISION_COMPARATOR);
        this.modules = ImmutableSet.copyOf(sortedModules);

        /*
         * The most common lookup is from Namespace->Module.
         *
         * RESTCONF performs lookups based on module name only, where it wants
         * to receive the latest revision
         *
         * Invest some quality time in building up lookup tables for both.
         */
        final SetMultimap nsMap = Multimaps.newSetMultimap(new TreeMap<>(),
            AbstractSchemaContext::createModuleSet);
        final SetMultimap nameMap = Multimaps.newSetMultimap(new TreeMap<>(),
            AbstractSchemaContext::createModuleSet);
        final Builder moduleMapBuilder = ImmutableMap.builder();
        for (Module m : modules) {
            nameMap.put(m.getName(), m);
            nsMap.put(m.getNamespace(), m);
            moduleMapBuilder.put(m.getQNameModule(), m);
        }

        namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
        nameToModules = ImmutableSetMultimap.copyOf(nameMap);
        moduleMap = moduleMapBuilder.build();
        annotations = ImmutableMap.copyOf(AnnotationSchemaNode.findAll(this));
    }

    /**
     * Create a new instance from specified modules. Note that no module validation is done and hence the consistency
     * of the resulting SchemaContext is completely in hands of the caller.
     */
    public static SimpleSchemaContext forModules(final Collection modules) {
        return new SimpleSchemaContext(modules);
    }

    @Override
    public final Set getModules() {
        return modules;
    }

    @Override
    public final Optional findAnnotation(final AnnotationName qname) {
        return Optional.ofNullable(annotations.get(requireNonNull(qname)));
    }

    @Override
    protected Map getModuleMap() {
        return moduleMap;
    }

    @Override
    protected final SetMultimap getNamespaceToModules() {
        return namespaceToModules;
    }

    @Override
    protected final SetMultimap getNameToModules() {
        return nameToModules;
    }

    @Override
    public final String toString() {
        return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
    }

    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
        return toStringHelper.add("modules", modules);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy