import org.opendaylight.yangtools.yang.model.api.UsesNode;
import org.opendaylight.yangtools.yang.parser.util.TopologicalSort;
import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node;
-import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.NodeImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-//import org.opendaylight.yangtools.yang.model.util.GroupingDefinition;
-
public class GroupingDefinitionDependencySort {
- private static final Logger logger = LoggerFactory.getLogger(GroupingDefinitionDependencySort.class);
- public static List<GroupingDefinition> sort(final Set<GroupingDefinition> groupingDefinitions) {
+ /**
+ * Sorts set <code>groupingDefinitions</code> according to the mutual
+ * dependencies.<br />
+ *
+ * Elements of <code>groupingDefinitions</code> are firstly transformed to
+ * {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node
+ * Node} interfaces and then are sorted by
+ * {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort#sort(Set)
+ * sort()} method of <code>TopologicalSort</code>.<br />
+ * <br />
+ *
+ *
+ * <i>Definition of dependency relation:<br />
+ * The first <code>GroupingDefinition</code> object (in this context)
+ * depends on second <code>GroupingDefinition</code> object if the first one
+ * contains in its set of <code>UsesNode</code> (obtained through
+ * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer#getUses()
+ * getUses} method) reference to the second one.</i>
+ *
+ * @param groupingDefinitions
+ * set of grouping definition which should be sorted according to
+ * mutual dependencies
+ * @return list of grouping definitiond which are sorted by mutual
+ * dependencies
+ * @throws IllegalArgumentException
+ * if <code>groupingDefinitions</code>
+ *
+ */
+ public List<GroupingDefinition> sort(final Set<GroupingDefinition> groupingDefinitions) {
if (groupingDefinitions == null) {
- logger.error("Set of grouping definitions cannot be NULL!");
throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!");
}
final List<GroupingDefinition> resultGroupingDefinitions = new ArrayList<GroupingDefinition>();
- final Set<Node> unsorted = groupingDefinitionsToGroupingNodes(groupingDefinitions);
+ final Set<Node> unsorted = groupingDefinitionsToNodes(groupingDefinitions);
final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
for (Node node : sortedNodes) {
- resultGroupingDefinitions.add(((GroupingNode) node).getGroupingDefinition());
+ NodeWrappedType nodeWrappedType = (NodeWrappedType) node;
+ resultGroupingDefinitions.add((GroupingDefinition) (nodeWrappedType.getWrappedType()));
}
return resultGroupingDefinitions;
}
- private static Set<Node> groupingDefinitionsToGroupingNodes(final Set<GroupingDefinition> groupingDefinitions) {
+ /**
+ * Wraps every grouping definition to node type and adds to every node
+ * information about dependencies.
+ *
+ * The map with mapping from schema path (represents grouping definition) to
+ * node is created. For every created node (next <i>nodeFrom</i>) is for its
+ * wrapped grouping definition passed the set of its <i>uses nodes</i>
+ * through. For every uses node is found its wrapping node (next as
+ * <i>nodeTo</i>). This dependency relationship between nodeFrom and all
+ * found nodesTo is modeled with creating of one edge from nodeFrom to
+ * nodeTo.
+ *
+ *
+ * @param groupingDefinitions
+ * set of goruping definition which will be wrapped to nodes
+ *
+ * @return set of nodes where every one contains wrapped grouping definition
+ */
+ private Set<Node> groupingDefinitionsToNodes(final Set<GroupingDefinition> groupingDefinitions) {
final Map<SchemaPath, Node> nodeMap = Maps.newHashMap();
final Set<Node> resultNodes = Sets.newHashSet();
for (final GroupingDefinition groupingDefinition : groupingDefinitions) {
- final Node node = new GroupingNode(groupingDefinition);
+ final Node node = new NodeWrappedType(groupingDefinition);
nodeMap.put(groupingDefinition.getPath(), node);
resultNodes.add(node);
}
for (final Node node : resultNodes) {
- final GroupingNode groupingNode = (GroupingNode) node;
- final GroupingDefinition groupingDefinition = groupingNode.getGroupingDefinition();
+ final NodeWrappedType nodeWrappedType = (NodeWrappedType) node;
+ final GroupingDefinition groupingDefinition = (GroupingDefinition) nodeWrappedType.getWrappedType();
+
+ Set<UsesNode> usesNodes = getAllUsesNodes(groupingDefinition);
- Set<UsesNode> usesNodes =getAllUsesNodes(groupingDefinition);
for (UsesNode usesNode : usesNodes) {
SchemaPath schemaPath = usesNode.getGroupingPath();
if (schemaPath != null) {
Node nodeTo = nodeMap.get(schemaPath);
- groupingNode.addEdge(nodeTo);
+ if (nodeTo != null) {
+ nodeWrappedType.addEdge(nodeTo);
+ }
}
}
}
return resultNodes;
}
- private static Set<UsesNode> getAllUsesNodes(DataNodeContainer container) {
- Set<UsesNode> ret = new HashSet<>();
- ret.addAll(container.getUses());
-
- Set<GroupingDefinition> groupings = container.getGroupings();
- for (GroupingDefinition groupingDefinition : groupings) {
- ret.addAll(getAllUsesNodes(groupingDefinition));
- }
- Set<DataSchemaNode> children = container.getChildNodes();
- for (DataSchemaNode dataSchemaNode : children) {
- if(dataSchemaNode instanceof DataNodeContainer) {
- ret.addAll(getAllUsesNodes((DataNodeContainer) dataSchemaNode));
- } else if (dataSchemaNode instanceof ChoiceNode) {
- Set<ChoiceCaseNode> cases = ((ChoiceNode) dataSchemaNode).getCases();
- for (ChoiceCaseNode choiceCaseNode : cases) {
- ret.addAll(getAllUsesNodes(choiceCaseNode));
- }
-
- }
- }
-
- return ret;
-
- }
-
-
- private static final class GroupingNode extends NodeImpl {
- private final GroupingDefinition groupingDefinition;
-
- GroupingNode(GroupingDefinition groupingDefinition) {
- this.groupingDefinition = groupingDefinition;
+ /**
+ * Returns the set of the uses nodes which are get from uses in
+ * <code>container</code>, from uses in groupings inside
+ * <code>container</code> and from uses inside child nodes of the
+ * <code>container</code>.
+ *
+ * @param container
+ * data node container which can contain some uses of grouping
+ * @return set of uses nodes which were find in <code>container</code>.
+ */
+ private Set<UsesNode> getAllUsesNodes(DataNodeContainer container) {
+ Set<UsesNode> ret = new HashSet<>();
+ ret.addAll(container.getUses());
+
+ Set<GroupingDefinition> groupings = container.getGroupings();
+ for (GroupingDefinition groupingDefinition : groupings) {
+ ret.addAll(getAllUsesNodes(groupingDefinition));
}
-
- GroupingDefinition getGroupingDefinition() {
- return groupingDefinition;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof GroupingNode)) {
- return false;
- }
- GroupingNode groupingNode = (GroupingNode) o;
- if (!groupingDefinition.equals(groupingNode.groupingDefinition)) {
- return false;
+ Set<DataSchemaNode> childNodes = container.getChildNodes();
+ for (DataSchemaNode childNode : childNodes) {
+ if (childNode instanceof DataNodeContainer) {
+ ret.addAll(getAllUsesNodes((DataNodeContainer) childNode));
+ } else if (childNode instanceof ChoiceNode) {
+ Set<ChoiceCaseNode> cases = ((ChoiceNode) childNode).getCases();
+ for (ChoiceCaseNode choiceCaseNode : cases) {
+ ret.addAll(getAllUsesNodes(choiceCaseNode));
+ }
}
- return true;
- }
-
- @Override
- public int hashCode() {
- return groupingDefinition.hashCode();
- }
-
- @Override
- public String toString() {
- return "GroupingNode{" + "groupingType=" + groupingDefinition + '}';
}
+ return ret;
}
+
}