import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
-import java.net.URI;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.opendaylight.yangtools.util.TopologicalSort.Node;
import org.opendaylight.yangtools.util.TopologicalSort.NodeImpl;
import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.Submodule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ModuleDependencySort {
private static final Logger LOG = LoggerFactory.getLogger(ModuleDependencySort.class);
- /**
- * It is not desirable to instance this class.
- */
private ModuleDependencySort() {
- throw new UnsupportedOperationException();
+ // Hidden on purpose
}
/**
* @return Sorted list of Modules. Modules can be further processed in returned order.
* @throws IllegalArgumentException when provided modules are not consistent.
*/
- public static List<Module> sort(final Collection<Module> modules) {
- return sort((Iterable<Module>)modules);
+ public static List<Module> sort(final Module... modules) {
+ return sort(Arrays.asList(modules));
}
/**
* Topological sort of module dependency graph.
*
* @param modules YANG modules
- * @return Sorted list of Modules. Modules can be further processed in
- * returned order.
+ * @return Sorted list of Modules. Modules can be further processed in returned order.
* @throws IllegalArgumentException when provided modules are not consistent.
- *
- * @deprecated Use {@link #sort(Collection)} instead.
*/
- @Deprecated
- public static List<Module> sort(final Iterable<Module> modules) {
+ public static List<Module> sort(final Collection<? extends Module> modules) {
final List<Node> sorted = sortInternal(modules);
// Cast to Module from Node and return
return Lists.transform(sorted, input -> input == null ? null : ((ModuleNodeImpl) input).getReference());
}
- private static List<Node> sortInternal(final Iterable<Module> modules) {
+ private static List<Node> sortInternal(final Collection<? extends Module> modules) {
final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph = createModuleGraph(modules);
return TopologicalSort.sort(new HashSet<>(moduleGraph.values()));
}
private static Table<String, Optional<Revision>, ModuleNodeImpl> createModuleGraph(
- final Iterable<Module> builders) {
+ final Collection<? extends Module> builders) {
final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph = HashBasedTable.create();
processModules(moduleGraph, builders);
* Extract module:revision from modules.
*/
private static void processDependencies(final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph,
- final Iterable<Module> mmbs) {
- final Map<URI, Module> allNS = new HashMap<>();
+ final Collection<? extends Module> mmbs) {
+ final Map<XMLNamespace, Module> allNS = new HashMap<>();
// Create edges in graph
for (final Module module : mmbs) {
final Map<String, Optional<Revision>> imported = new HashMap<>();
final String fromName = module.getName();
- final URI ns = module.getNamespace();
+ final XMLNamespace ns = module.getNamespace();
final Optional<Revision> fromRevision = module.getRevision();
// check for existence of module with same namespace
}
// no need to check if other Type of object, check is performed in process modules
- for (final ModuleImport imprt : module.getImports()) {
+ for (final ModuleImport imprt : allImports(module)) {
final String toName = imprt.getModuleName();
final Optional<Revision> toRevision = imprt.getRevision();
}
}
+ private static Collection<? extends ModuleImport> allImports(final Module mod) {
+ if (mod.getSubmodules().isEmpty()) {
+ return mod.getImports();
+ }
+
+ final Collection<ModuleImport> concat = new LinkedHashSet<>();
+ concat.addAll(mod.getImports());
+ for (Submodule sub : mod.getSubmodules()) {
+ concat.addAll(sub.getImports());
+ }
+ return concat;
+ }
+
/**
* Get imported module by its name and revision from moduleGraph.
*/
}
// If revision is not specified in import, but module exists with different revisions, take first one
- if (toRevision == null) {
+ if (toRevision.isEmpty()) {
final Map<Optional<Revision>, ModuleNodeImpl> modulerevs = moduleGraph.row(toName);
if (!modulerevs.isEmpty()) {
* Extract dependencies from modules to fill dependency graph.
*/
private static void processModules(final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph,
- final Iterable<Module> modules) {
+ final Iterable<? extends Module> modules) {
// Process nodes
for (final Module momb : modules) {
return false;
}
final ModuleNodeImpl other = (ModuleNodeImpl) obj;
- if (name == null) {
- if (other.name != null) {
- return false;
- }
- } else if (!name.equals(other.name)) {
+ if (!Objects.equals(name, other.name)) {
return false;
}
- if (revision == null) {
- if (other.revision != null) {
- return false;
- }
- } else if (!revision.equals(other.revision)) {
+ if (!Objects.equals(revision, other.revision)) {
return false;
}
return true;