Merge "BUG-1687, BUG-1689 FIx belongs-to resolution in dependency resolver"
authorTony Tkacik <ttkacik@cisco.com>
Thu, 4 Sep 2014 09:58:15 +0000 (09:58 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 4 Sep 2014 09:58:15 +0000 (09:58 +0000)
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolver.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/DependencyResolverTest.java

index d9b74fe93aff48079fc33dc3660d8dd83da79da4..972f4689d547e2c491f1c774183946fe5d5f94d0 100644 (file)
@@ -7,7 +7,13 @@
  */
 package org.opendaylight.yangtools.yang.parser.repo;
 
-import com.google.common.collect.Sets;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ArrayListMultimap;
+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;
@@ -15,7 +21,6 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
@@ -23,12 +28,6 @@ import org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Multimap;
-
 /**
  * Inter-module dependency resolved. Given a set of schema source identifiers and their
  * corresponding dependency information, the {@link #create(Map)} method creates a
@@ -53,7 +52,7 @@ final class DependencyResolver {
     }
 
     private static SourceIdentifier findWildcard(final Iterable<SourceIdentifier> haystack, final String needle) {
-        for (SourceIdentifier r : haystack) {
+        for (final SourceIdentifier r : haystack) {
             if (r.getName().equals(needle)) {
                 return r;
             }
@@ -77,9 +76,10 @@ final class DependencyResolver {
 
 
 
-    public static final DependencyResolver create(final Map<SourceIdentifier, YangModelDependencyInfo> depInfo) {
+    public static DependencyResolver create(final Map<SourceIdentifier, YangModelDependencyInfo> depInfo) {
         final Collection<SourceIdentifier> resolved = new ArrayList<>(depInfo.size());
         final Collection<SourceIdentifier> pending = new ArrayList<>(depInfo.keySet());
+        final Map<SourceIdentifier, BelongsToDependency> submodules = Maps.newHashMap();
 
         boolean progress;
         do {
@@ -92,16 +92,15 @@ final class DependencyResolver {
 
                 boolean okay = true;
 
-                Set<ModuleImport> dependencies = dep.getDependencies();
+                final Set<ModuleImport> dependencies = dep.getDependencies();
 
-                // in case of submodule, make its parent also a dependency
+                // in case of submodule, remember belongs to
                 if(dep instanceof YangModelDependencyInfo.SubmoduleDependencyInfo) {
                     final String parent = ((YangModelDependencyInfo.SubmoduleDependencyInfo) dep).getParentModule();
-                    dependencies = Sets.newHashSet(dependencies);
-                    dependencies.add(new BelongsToDependency(parent));
+                    submodules.put(id, new BelongsToDependency(parent));
                 }
 
-                for (ModuleImport mi : dependencies) {
+                for (final ModuleImport mi : dependencies) {
                     if (!isKnown(resolved, mi)) {
                         LOG.debug("Source {} is missing import {}", id, mi);
                         okay = false;
@@ -118,11 +117,21 @@ final class DependencyResolver {
             }
         } while (progress);
 
+        /// Additional check only for belongs-to statement
+        for (final SourceIdentifier sourceIdentifier : submodules.keySet()) {
+            final BelongsToDependency belongs = submodules.get(sourceIdentifier);
+            if (!isKnown(resolved, belongs)) {
+                LOG.debug("Source {} is missing parent {}", sourceIdentifier, belongs);
+                pending.add(sourceIdentifier);
+                resolved.remove(sourceIdentifier);
+            }
+        }
+
         if (!pending.isEmpty()) {
             final Multimap<SourceIdentifier, ModuleImport> imports = ArrayListMultimap.create();
-            for (SourceIdentifier id : pending) {
+            for (final SourceIdentifier id : pending) {
                 final YangModelDependencyInfo dep = depInfo.get(id);
-                for (ModuleImport mi : dep.getDependencies()) {
+                for (final ModuleImport mi : dep.getDependencies()) {
                     if (!isKnown(pending, mi) && !isKnown(resolved, mi)) {
                         imports.put(id, mi);
                     }
@@ -196,5 +205,12 @@ final class DependencyResolver {
         public String getPrefix() {
             return null;
         }
+
+        @Override
+        public String toString() {
+            return Objects.toStringHelper(this)
+                    .add("parent", parent)
+                    .toString();
+        }
     }
 }
index 3f1265b0e1c63acd99cc36e55ee1b74dcf6e535d..a8aef6984b964177e98270b7492b31b254fb4e40 100644 (file)
@@ -44,10 +44,27 @@ public class DependencyResolverTest {
 
         final DependencyResolver resolved = DependencyResolver.create(map);
 
+        assertEquals(2, resolved.getResolvedSources().size());
         assertEquals(1, resolved.getUnresolvedSources().size());
         assertEquals(0, resolved.getUnsatisfiedImports().size());
     }
 
+    @Test
+    public void testSubmodule() throws Exception {
+        final Map<SourceIdentifier, YangModelDependencyInfo> map = new HashMap<>();
+
+        addToMap(map, YangModelDependencyInfo.ModuleDependencyInfo.fromInputStream(getClass().getResourceAsStream("/model/subfoo.yang")));
+        addToMap(map, YangModelDependencyInfo.ModuleDependencyInfo.fromInputStream(getClass().getResourceAsStream("/model/foo.yang")));
+        addToMap(map, YangModelDependencyInfo.ModuleDependencyInfo.fromInputStream(getClass().getResourceAsStream("/model/bar.yang")));
+        addToMap(map, YangModelDependencyInfo.ModuleDependencyInfo.fromInputStream(getClass().getResourceAsStream("/model/baz.yang")));
+
+        final DependencyResolver resolved = DependencyResolver.create(map);
+
+        assertEquals(4, resolved.getResolvedSources().size());
+        assertEquals(0, resolved.getUnresolvedSources().size());
+        assertEquals(0, resolved.getUnsatisfiedImports().size());
+    }
+
     private void addToMap(final Map<SourceIdentifier, YangModelDependencyInfo> map, final YangModelDependencyInfo yangModelDependencyInfo) {
         map.put(getSourceId(yangModelDependencyInfo), yangModelDependencyInfo);
     }