X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frepo%2FDependencyResolver.java;h=bc339f7f54932488dc77211a9372424a1376a370;hb=e403e34bcb508c48aa606a1cd81a386fb73c5db6;hp=45ad366285af4c7f5244ebed4ff22c6b3429e336;hpb=b8ac1a71bb9b2f950f8b55c8357aac777a63a83c;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolver.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolver.java index 45ad366285..bc339f7f54 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolver.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolver.java @@ -7,18 +7,20 @@ */ package org.opendaylight.yangtools.yang.parser.repo; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; +import com.google.common.base.MoreObjects; import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Maps; import com.google.common.collect.Multimap; - import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; +import java.util.Date; import java.util.Iterator; import java.util.Map; - +import java.util.Map.Entry; +import java.util.Set; +import org.opendaylight.yangtools.concepts.SemVer; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo; @@ -35,45 +37,16 @@ import org.slf4j.LoggerFactory; * That information will allow us to track "damage" to dependency resolution * as new models are added to a schema context. */ -final class DependencyResolver { +abstract class DependencyResolver { private static final Logger LOG = LoggerFactory.getLogger(DependencyResolver.class); private final Collection resolvedSources; private final Collection unresolvedSources; private final Multimap unsatisfiedImports; - public DependencyResolver(final Collection resolvedSources, - final Collection unresolvedSources, final Multimap unsatisfiedImports) { - this.resolvedSources = Preconditions.checkNotNull(resolvedSources); - this.unresolvedSources = Preconditions.checkNotNull(unresolvedSources); - this.unsatisfiedImports = Preconditions.checkNotNull(unsatisfiedImports); - } - - private static SourceIdentifier findWildcard(final Iterable haystack, final String needle) { - for (SourceIdentifier r : haystack) { - if (r.getName().equals(needle)) { - return r; - } - } - - return null; - } - - private static boolean isKnown(final Collection haystack, final ModuleImport mi) { - final String rev = mi.getRevision() != null ? mi.getRevision().toString() : null; - final SourceIdentifier msi = SourceIdentifier.create(mi.getModuleName(), Optional.fromNullable(rev)); - - // Quick lookup - if (haystack.contains(msi)) { - return true; - } - - // Slow revision-less walk - return rev == null && findWildcard(haystack, mi.getModuleName()) != null; - } - - public static final DependencyResolver create(final Map depInfo) { + protected DependencyResolver(final Map depInfo) { final Collection resolved = new ArrayList<>(depInfo.size()); final Collection pending = new ArrayList<>(depInfo.keySet()); + final Map submodules = Maps.newHashMap(); boolean progress; do { @@ -85,7 +58,16 @@ final class DependencyResolver { final YangModelDependencyInfo dep = depInfo.get(id); boolean okay = true; - for (ModuleImport mi : dep.getDependencies()) { + + final Set dependencies = dep.getDependencies(); + + // in case of submodule, remember belongs to + if (dep instanceof YangModelDependencyInfo.SubmoduleDependencyInfo) { + final String parent = ((YangModelDependencyInfo.SubmoduleDependencyInfo) dep).getParentModule(); + submodules.put(id, new BelongsToDependency(parent)); + } + + for (final ModuleImport mi : dependencies) { if (!isKnown(resolved, mi)) { LOG.debug("Source {} is missing import {}", id, mi); okay = false; @@ -102,23 +84,34 @@ final class DependencyResolver { } } while (progress); - if (!pending.isEmpty()) { - final Multimap imports = ArrayListMultimap.create(); - for (SourceIdentifier id : pending) { - final YangModelDependencyInfo dep = depInfo.get(id); - for (ModuleImport mi : dep.getDependencies()) { - if (!isKnown(pending, mi) && !isKnown(resolved, mi)) { - imports.put(id, mi); - } - } + /// Additional check only for belongs-to statement + for (final Entry submodule : submodules.entrySet()) { + final BelongsToDependency belongs = submodule.getValue(); + final SourceIdentifier sourceIdentifier = submodule.getKey(); + if (!isKnown(resolved, belongs)) { + LOG.debug("Source {} is missing parent {}", sourceIdentifier, belongs); + pending.add(sourceIdentifier); + resolved.remove(sourceIdentifier); } + } - return new DependencyResolver(resolved, pending, imports); - } else { - return new DependencyResolver(resolved, Collections.emptyList(), ImmutableMultimap.of()); + final Multimap imports = ArrayListMultimap.create(); + for (final SourceIdentifier id : pending) { + final YangModelDependencyInfo dep = depInfo.get(id); + for (final ModuleImport mi : dep.getDependencies()) { + if (!isKnown(pending, mi) && !isKnown(resolved, mi)) { + imports.put(id, mi); + } + } } + + this.resolvedSources = ImmutableList.copyOf(resolved); + this.unresolvedSources = ImmutableList.copyOf(pending); + this.unsatisfiedImports = ImmutableMultimap.copyOf(imports); } + abstract protected boolean isKnown(final Collection haystack, final ModuleImport mi); + /** * Collection of sources which have been resolved. * @@ -158,4 +151,39 @@ final class DependencyResolver { Multimap getUnsatisfiedImports() { return unsatisfiedImports; } + + private static class BelongsToDependency implements ModuleImport { + private final String parent; + + public BelongsToDependency(final String parent) { + this.parent = parent; + } + + @Override + public String getModuleName() { + return parent; + } + + @Override + public Date getRevision() { + return null; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public SemVer getSemanticVersion() { + return null; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("parent", parent) + .toString(); + } + } }