X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fimpl%2FSchemaContextImpl.java;h=319f189043f4743daedc326834caeea4c2e12d1d;hb=9d50f7560aa1bf6e6f553ce592145c6671dfc356;hp=3eb87a9214e24bd84b7e51061f6e29e82aba4a87;hpb=5c1f875f69e35248aa4115c429bd962160beeef4;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/SchemaContextImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/SchemaContextImpl.java index 3eb87a9214..319f189043 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/SchemaContextImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/SchemaContextImpl.java @@ -7,28 +7,106 @@ */ package org.opendaylight.yangtools.yang.parser.impl; +import com.google.common.base.Optional; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableMap; +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.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.Date; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import javax.annotation.concurrent.Immutable; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; +@Immutable final class SchemaContextImpl implements SchemaContext { + private static final Comparator REVISION_COMPARATOR = new Comparator() { + @Override + public int compare(final Module o1, final Module o2) { + if (o2.getRevision() == null) { + return -1; + } + + return o2.getRevision().compareTo(o1.getRevision()); + } + }; + + private static final Supplier> MODULE_SET_SUPPLIER = new Supplier>() { + @Override + public TreeSet get() { + return new TreeSet<>(REVISION_COMPARATOR); + } + }; + + private final Map identifiersToSources; + private final SetMultimap namespaceToModules; + private final SetMultimap nameToModules; private final Set modules; - SchemaContextImpl(final Set modules) { - this.modules = modules; + SchemaContextImpl(final Set modules, final Map identifiersToSources) { + this.identifiersToSources = ImmutableMap.copyOf(identifiersToSources); + + /* + * Instead of doing this on each invocation of getModules(), pre-compute + * it once and keep it around -- better than the set we got in. + */ + this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules.toArray(new Module[modules.size()]))); + + /* + * 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>(), MODULE_SET_SUPPLIER); + final SetMultimap nameMap = Multimaps.newSetMultimap( + new TreeMap>(), MODULE_SET_SUPPLIER); + for (Module m : modules) { + nameMap.put(m.getName(), m); + nsMap.put(m.getNamespace(), m); + } + + namespaceToModules = ImmutableSetMultimap.copyOf(nsMap); + nameToModules = ImmutableSetMultimap.copyOf(nameMap); } @Override public Set getDataDefinitions() { - final Set dataDefs = new HashSet(); + final Set dataDefs = new HashSet<>(); for (Module m : modules) { dataDefs.addAll(m.getChildNodes()); } @@ -42,7 +120,7 @@ final class SchemaContextImpl implements SchemaContext { @Override public Set getNotifications() { - final Set notifications = new HashSet(); + final Set notifications = new HashSet<>(); for (Module m : modules) { notifications.addAll(m.getNotifications()); } @@ -51,7 +129,7 @@ final class SchemaContextImpl implements SchemaContext { @Override public Set getOperations() { - final Set rpcs = new HashSet(); + final Set rpcs = new HashSet<>(); for (Module m : modules) { rpcs.addAll(m.getRpcs()); } @@ -60,7 +138,7 @@ final class SchemaContextImpl implements SchemaContext { @Override public Set getExtensions() { - final Set extensions = new HashSet(); + final Set extensions = new HashSet<>(); for (Module m : modules) { extensions.addAll(m.getExtensionSchemaNodes()); } @@ -69,30 +147,168 @@ final class SchemaContextImpl implements SchemaContext { @Override public Module findModuleByName(final String name, final Date revision) { - if (name != null) { - for (final Module module : modules) { - if (revision == null) { - if (module.getName().equals(name)) { - return module; - } - } else if (module.getName().equals(name) && module.getRevision().equals(revision)) { - return module; - } + for (final Module module : nameToModules.get(name)) { + if (revision == null || revision.equals(module.getRevision())) { + return module; + } + } + + return null; + } + + @Override + public Set findModuleByNamespace(final URI namespace) { + final Set ret = namespaceToModules.get(namespace); + return ret == null ? Collections.emptySet() : ret; + } + + @Override + public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) { + if (namespace == null) { + return null; + } + for (Module module : findModuleByNamespace(namespace)) { + if (revision == null || revision.equals(module.getRevision())) { + return module; + } + } + return null; + } + + @Override + public boolean isAugmenting() { + return false; + } + + @Override + public boolean isAddedByUses() { + return false; + } + + @Override + public boolean isConfiguration() { + return false; + } + + @Override + public ConstraintDefinition getConstraints() { + return null; + } + + @Override + public QName getQName() { + return SchemaContext.NAME; + } + + @Override + public SchemaPath getPath() { + return null; + } + + @Override + public String getDescription() { + return null; + } + + @Override + public String getReference() { + return null; + } + + @Override + public Status getStatus() { + return Status.CURRENT; + } + + @Override + public List getUnknownSchemaNodes() { + final List result = new ArrayList<>(); + for (Module module : modules) { + result.addAll(module.getUnknownSchemaNodes()); + } + return Collections.unmodifiableList(result); + } + + @Override + public Set> getTypeDefinitions() { + final Set> result = new LinkedHashSet<>(); + for (Module module : modules) { + result.addAll(module.getTypeDefinitions()); + } + return Collections.unmodifiableSet(result); + } + + @Override + public Set getChildNodes() { + final Set result = new LinkedHashSet<>(); + for (Module module : modules) { + result.addAll(module.getChildNodes()); + } + return Collections.unmodifiableSet(result); + } + + @Override + public Set getGroupings() { + final Set result = new LinkedHashSet<>(); + for (Module module : modules) { + result.addAll(module.getGroupings()); + } + return Collections.unmodifiableSet(result); + } + + @Override + public DataSchemaNode getDataChildByName(final QName name) { + for (Module module : modules) { + final DataSchemaNode result = module.getDataChildByName(name); + if (result != null) { + return result; } } return null; } @Override - public Module findModuleByNamespace(final URI namespace) { - if (namespace != null) { - for (final Module module : modules) { - if (module.getNamespace().equals(namespace)) { - return module; - } + public DataSchemaNode getDataChildByName(final String name) { + for (Module module : modules) { + final DataSchemaNode result = module.getDataChildByName(name); + if (result != null) { + return result; } } return null; } + @Override + public Set getUses() { + return Collections.emptySet(); + } + + @Override + public boolean isPresenceContainer() { + return false; + } + + @Override + public Set getAvailableAugmentations() { + return Collections.emptySet(); + } + + //FIXME: should work for submodules too + @Override + public Set getAllModuleIdentifiers() { + return identifiersToSources.keySet(); + } + + @Override + public Optional getModuleSource(final ModuleIdentifier moduleIdentifier) { + String maybeSource = identifiersToSources.get(moduleIdentifier); + return Optional.fromNullable(maybeSource); + } + + @Override + public String toString() { + return "SchemaContextImpl{" + + "modules=" + modules + + '}'; + } }