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.controller.sal.binding.yang.types;
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Function;
12 import com.google.common.collect.Lists;
13 import com.google.common.collect.Maps;
14 import com.google.common.collect.Sets;
15 import org.opendaylight.controller.yang.model.api.TypeDefinition;
16 import org.opendaylight.controller.yang.model.api.type.UnionTypeDefinition;
17 import org.opendaylight.controller.yang.model.util.ExtendedType;
18 import org.opendaylight.controller.yang.parser.util.TopologicalSort;
19 import org.opendaylight.controller.yang.parser.util.TopologicalSort.Node;
20 import org.opendaylight.controller.yang.parser.util.TopologicalSort.NodeImpl;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 import java.util.List;
28 public class UnionDependencySort {
29 private static final Logger logger = LoggerFactory
30 .getLogger(UnionDependencySort.class);
32 public static List<ExtendedType> sort(
33 final Set<TypeDefinition<?>> typeDefinitions) {
34 if (typeDefinitions == null) {
35 logger.error("Set of Type Definitions cannot be NULL!");
36 throw new IllegalArgumentException("Set of Type Definitions " +
40 final Set<ExtendedType> extUnionTypes =
41 unionsFromTypeDefinitions(typeDefinitions);
43 final Set<Node> unsorted = unionTypesToUnionNodes(extUnionTypes);
45 final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
46 return Lists.transform(sortedNodes, new Function<Node, ExtendedType>() {
48 public ExtendedType apply(Node input) {
49 return ((UnionNode) input).getUnionType();
54 private static Set<ExtendedType> unionsFromTypeDefinitions(
55 final Set<TypeDefinition<?>> typeDefinitions) {
56 final Set<ExtendedType> unions = Sets.newHashSet();
58 for (final TypeDefinition<?> typedef : typeDefinitions) {
59 if ((typedef != null) && (typedef.getBaseType() != null)) {
60 if (typedef instanceof ExtendedType
61 && typedef.getBaseType() instanceof UnionTypeDefinition) {
62 unions.add((ExtendedType) typedef);
69 private static Set<Node> unionTypesToUnionNodes(
70 final Set<ExtendedType> extUnionTypes) {
71 final Map<ExtendedType, Node> nodeMap = Maps.newHashMap();
72 final Set<Node> resultNodes = Sets.newHashSet();
74 for (final ExtendedType unionType : extUnionTypes) {
75 final Node node = new UnionNode(unionType);
76 nodeMap.put(unionType, node);
77 resultNodes.add(node);
80 for (final Node node : resultNodes) {
81 final UnionNode unionNode = (UnionNode) node;
82 final ExtendedType extUnionType = unionNode.getUnionType();
84 final UnionTypeDefinition unionType = (UnionTypeDefinition)
85 extUnionType.getBaseType();
87 final List<TypeDefinition<?>> innerTypes = unionType.getTypes();
88 for (final TypeDefinition<?> typedef : innerTypes) {
89 if (extUnionTypes.contains(typedef)) {
90 final Node toNode = nodeMap.get(typedef);
91 unionNode.addEdge(toNode);
99 private static UnionNode unionTypeToUnionNode(
100 final ExtendedType extUnionType,
101 final Set<ExtendedType> extUnionTypes) {
102 final UnionNode node = new UnionNode(extUnionType);
104 if (extUnionType.getBaseType() instanceof UnionTypeDefinition) {
105 final UnionTypeDefinition unionType = (UnionTypeDefinition)
106 extUnionType.getBaseType();
108 final List<TypeDefinition<?>> innerTypes = unionType.getTypes();
109 for (final TypeDefinition<?> typedef : innerTypes) {
110 if ((typedef != null) && (typedef instanceof ExtendedType)
111 && (typedef.getBaseType() instanceof UnionTypeDefinition)) {
112 if (extUnionTypes.contains(typedef)) {
113 node.addEdge(new UnionNode((ExtendedType) typedef));
123 static final class UnionNode extends NodeImpl {
124 private final ExtendedType unionType;
126 UnionNode(ExtendedType unionType) {
127 this.unionType = unionType;
130 ExtendedType getUnionType() {
135 public boolean equals(Object o) {
139 if (!(o instanceof UnionNode)) {
142 UnionNode unionNode = (UnionNode) o;
143 if (!unionType.equals(unionNode.unionType)) {
150 public int hashCode() {
151 return unionType.hashCode();
155 public String toString() {
156 return "UnionNode{" +
157 "unionType=" + unionType +