*/
package org.opendaylight.yangtools.yang.model.util;
-import static org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil.DEFAULT_DATE_REV;
-
import com.google.common.annotations.Beta;
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.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import org.opendaylight.yangtools.util.TopologicalSort;
import org.opendaylight.yangtools.util.TopologicalSort.Node;
import org.opendaylight.yangtools.util.TopologicalSort.NodeImpl;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
private ModuleDependencySort() {
throw new UnsupportedOperationException();
}
-
/**
* Topological sort of module dependency graph.
*
* @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<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) {
- final Table<String, Date, ModuleNodeImpl> moduleGraph = createModuleGraph(modules);
+ private static List<Node> sortInternal(final Collection<Module> modules) {
+ final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph = createModuleGraph(modules);
return TopologicalSort.sort(new HashSet<>(moduleGraph.values()));
}
- private static Table<String, Date, ModuleNodeImpl> createModuleGraph(final Iterable<Module> builders) {
- final Table<String, Date, ModuleNodeImpl> moduleGraph = HashBasedTable.create();
+ private static Table<String, Optional<Revision>, ModuleNodeImpl> createModuleGraph(
+ final Collection<Module> builders) {
+ final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph = HashBasedTable.create();
processModules(moduleGraph, builders);
processDependencies(moduleGraph, builders);
/**
* Extract module:revision from modules.
*/
- private static void processDependencies(final Table<String, Date, ModuleNodeImpl> moduleGraph,
- final Iterable<Module> mmbs) {
+ private static void processDependencies(final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph,
+ final Collection<Module> mmbs) {
final Map<URI, Module> allNS = new HashMap<>();
// Create edges in graph
for (final Module module : mmbs) {
- final Map<String, Date> imported = new HashMap<>();
+ final Map<String, Optional<Revision>> imported = new HashMap<>();
final String fromName = module.getName();
final URI ns = module.getNamespace();
- Date fromRevision = module.getRevision();
+ final Optional<Revision> fromRevision = module.getRevision();
// check for existence of module with same namespace
final Module prev = allNS.putIfAbsent(ns, module);
}
}
- // no need to check if other Type of object, check is performed in
- // process modules
-
- if (fromRevision == null) {
- fromRevision = DEFAULT_DATE_REV;
- }
-
+ // no need to check if other Type of object, check is performed in process modules
for (final ModuleImport imprt : module.getImports()) {
final String toName = imprt.getModuleName();
- final Date toRevision = imprt.getRevision() == null ? DEFAULT_DATE_REV : imprt.getRevision();
+ final Optional<Revision> toRevision = imprt.getRevision();
final ModuleNodeImpl from = moduleGraph.get(fromName, fromRevision);
-
final ModuleNodeImpl to = getModuleByNameAndRevision(moduleGraph, fromName, fromRevision, toName,
toRevision);
* If it is an yang 1 module, check imports: If module is imported twice with different
* revisions then throw exception
*/
- if (YangVersion.VERSION_1.toString().equals(module.getYangVersion())) {
- final Date impRevision = imported.get(toName);
- if (impRevision != null && !impRevision.equals(toRevision)
- && !DEFAULT_DATE_REV.equals(impRevision) && !DEFAULT_DATE_REV.equals(toRevision)) {
+ if (module.getYangVersion() == YangVersion.VERSION_1) {
+ final Optional<Revision> impRevision = imported.get(toName);
+ if (impRevision != null && impRevision.isPresent() && !impRevision.equals(toRevision)
+ && toRevision.isPresent()) {
throw new IllegalArgumentException(String.format(
"Module:%s imported twice with different revisions:%s, %s", toName,
formatRevDate(impRevision), formatRevDate(toRevision)));
/**
* Get imported module by its name and revision from moduleGraph.
*/
- private static ModuleNodeImpl getModuleByNameAndRevision(final Table<String, Date, ModuleNodeImpl> moduleGraph,
- final String fromName, final Date fromRevision, final String toName, final Date toRevision) {
+ private static ModuleNodeImpl getModuleByNameAndRevision(
+ final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph, final String fromName,
+ final Optional<Revision> fromRevision, final String toName, final Optional<Revision> toRevision) {
final ModuleNodeImpl exact = moduleGraph.get(toName, toRevision);
if (exact != null) {
}
// If revision is not specified in import, but module exists with different revisions, take first one
- if (DEFAULT_DATE_REV.equals(toRevision)) {
- final Map<Date, ModuleNodeImpl> modulerevs = moduleGraph.row(toName);
+ if (!toRevision.isPresent()) {
+ final Map<Optional<Revision>, ModuleNodeImpl> modulerevs = moduleGraph.row(toName);
if (!modulerevs.isEmpty()) {
final ModuleNodeImpl first = modulerevs.values().iterator().next();
/**
* Extract dependencies from modules to fill dependency graph.
*/
- private static void processModules(final Table<String, Date, ModuleNodeImpl> moduleGraph,
+ private static void processModules(final Table<String, Optional<Revision>, ModuleNodeImpl> moduleGraph,
final Iterable<Module> modules) {
// Process nodes
for (final Module momb : modules) {
final String name = momb.getName();
- Date rev = momb.getRevision();
- if (rev == null) {
- rev = DEFAULT_DATE_REV;
- }
-
- final Map<Date, ModuleNodeImpl> revs = moduleGraph.row(name);
+ final Optional<Revision> rev = momb.getRevision();
+ final Map<Optional<Revision>, ModuleNodeImpl> revs = moduleGraph.row(name);
if (revs.containsKey(rev)) {
throw new IllegalArgumentException(String.format("Module:%s with revision:%s declared twice", name,
formatRevDate(rev)));
}
- revs.put(rev, new ModuleNodeImpl(name, rev, momb));
+ revs.put(rev, new ModuleNodeImpl(name, rev.orElse(null), momb));
}
}
- private static String formatRevDate(final Date rev) {
- return rev.equals(DEFAULT_DATE_REV) ? "default" : SimpleDateFormatUtil.getRevisionFormat().format(rev);
+ private static String formatRevDate(final Optional<Revision> rev) {
+ return rev.map(Revision::toString).orElse("default");
}
private static final class ModuleNodeImpl extends NodeImpl {
private final String name;
- private final Date revision;
+ private final Revision revision;
private final Module originalObject;
- ModuleNodeImpl(final String name, final Date revision, final Module module) {
+ ModuleNodeImpl(final String name, final Revision revision, final Module module) {
this.name = name;
this.revision = revision;
this.originalObject = module;
return name;
}
- Date getRevision() {
- return revision;
+ Optional<Revision> getRevision() {
+ return Optional.ofNullable(revision);
}
@Override
@Override
public String toString() {
- return "Module [name=" + name + ", revision=" + formatRevDate(revision) + "]";
+ return "Module [name=" + name + ", revision=" + formatRevDate(getRevision()) + "]";
}
public Module getReference() {