2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.sal.binding.yang.types;
10 import com.google.common.base.Function;
11 import com.google.common.collect.Lists;
12 import com.google.common.collect.Maps;
13 import com.google.common.collect.Sets;
14 import java.util.List;
17 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
18 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
19 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
20 import org.opendaylight.yangtools.yang.parser.util.TopologicalSort;
21 import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 public class UnionDependencySort {
26 private static final Logger LOGGER = LoggerFactory.getLogger(UnionDependencySort.class);
29 * Sorts union types by mutual dependencies.
31 * At the beginning the union types are selected from
32 * <code>typeDefinitions</code> and wrapped to nodes. The nodes are sorted
33 * and then the wrapped payload is extracted.
35 * @param typeDefinitions
36 * set of type definitions.
37 * @return list of extended type which are sorted by mutual dependencies
38 * @throws IllegalArgumentException
39 * if <code>typeDefinitions</code> equals <code>null</code>
41 public List<ExtendedType> sort(final Set<TypeDefinition<?>> typeDefinitions) {
42 if (typeDefinitions == null) {
43 LOGGER.error("Set of Type Definitions cannot be NULL!");
44 throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!");
47 final Set<ExtendedType> extUnionTypes = unionsFromTypeDefinitions(typeDefinitions);
49 final Set<Node> unsorted = unionTypesToNodes(extUnionTypes);
51 final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
52 return Lists.transform(sortedNodes, new Function<Node, ExtendedType>() {
54 public ExtendedType apply(final Node input) {
55 return (ExtendedType) (((NodeWrappedType) input).getWrappedType());
61 * Extracts only union types from <code>typeDefinitions</code> set.
63 * @param typeDefinitions
64 * set of all type definitions
65 * @return set of extended type which are union type definition
67 private static Set<ExtendedType> unionsFromTypeDefinitions(final Set<TypeDefinition<?>> typeDefinitions) {
68 final Set<ExtendedType> unions = Sets.newHashSet();
70 for (final TypeDefinition<?> typedef : typeDefinitions) {
71 if ((typedef != null) && (typedef.getBaseType() != null) && (typedef instanceof ExtendedType)
72 && (typedef.getBaseType() instanceof UnionTypeDefinition)) {
73 unions.add((ExtendedType) typedef);
80 * Wraps every extended type which represents union to node type and adds to
81 * every node information about dependencies.
83 * The mapping from union type to node is created. For every created node
84 * (next <i>nodeFrom</i>) is for its wrapped union type passed the list of
85 * inner types through and only those inner types which represent union type
86 * are next considered. For every inner union type is found its wrapping
87 * node (next as <i>nodeTo</i>). This dependency relationship between
88 * nodeFrom and all found nodesTo is modeled with creating of one edge from
92 * @param extUnionTypes
93 * set of extended types which represents union types
94 * @return set of nodes which contains wrapped union types set of node where
95 * each one contains wrapped one union type
97 private static Set<Node> unionTypesToNodes(final Set<ExtendedType> extUnionTypes) {
98 final Map<ExtendedType, Node> nodeMap = Maps.newHashMap();
99 final Set<Node> resultNodes = Sets.newHashSet();
101 for (final ExtendedType unionType : extUnionTypes) {
102 final Node node = new NodeWrappedType(unionType);
103 nodeMap.put(unionType, node);
104 resultNodes.add(node);
107 for (final Node node : resultNodes) {
108 final NodeWrappedType nodeFrom = (NodeWrappedType) node;
109 final ExtendedType extUnionType = (ExtendedType) nodeFrom.getWrappedType();
111 final UnionTypeDefinition unionType = (UnionTypeDefinition) extUnionType.getBaseType();
113 final List<TypeDefinition<?>> innerTypes = unionType.getTypes();
114 for (final TypeDefinition<?> typedef : innerTypes) {
115 if (extUnionTypes.contains(typedef)) {
116 final Node toNode = nodeMap.get(typedef);
117 nodeFrom.addEdge(toNode);