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 java.util.List;
14 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
15 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
16 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
17 import org.opendaylight.yangtools.yang.parser.util.TopologicalSort;
18 import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node;
19 import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.NodeImpl;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
23 import com.google.common.annotations.VisibleForTesting;
24 import com.google.common.base.Function;
25 import com.google.common.collect.Lists;
26 import com.google.common.collect.Maps;
27 import com.google.common.collect.Sets;
29 public class UnionDependencySort {
30 private static final Logger logger = LoggerFactory
31 .getLogger(UnionDependencySort.class);
33 public static List<ExtendedType> sort(
34 final Set<TypeDefinition<?>> typeDefinitions) {
35 if (typeDefinitions == null) {
36 logger.error("Set of Type Definitions cannot be NULL!");
37 throw new IllegalArgumentException("Set of Type Definitions " +
41 final Set<ExtendedType> extUnionTypes =
42 unionsFromTypeDefinitions(typeDefinitions);
44 final Set<Node> unsorted = unionTypesToUnionNodes(extUnionTypes);
46 final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
47 return Lists.transform(sortedNodes, new Function<Node, ExtendedType>() {
49 public ExtendedType apply(Node input) {
50 return ((UnionNode) input).getUnionType();
55 private static Set<ExtendedType> unionsFromTypeDefinitions(
56 final Set<TypeDefinition<?>> typeDefinitions) {
57 final Set<ExtendedType> unions = Sets.newHashSet();
59 for (final TypeDefinition<?> typedef : typeDefinitions) {
60 if ((typedef != null) && (typedef.getBaseType() != null)) {
61 if (typedef instanceof ExtendedType
62 && typedef.getBaseType() instanceof UnionTypeDefinition) {
63 unions.add((ExtendedType) typedef);
70 private static Set<Node> unionTypesToUnionNodes(
71 final Set<ExtendedType> extUnionTypes) {
72 final Map<ExtendedType, Node> nodeMap = Maps.newHashMap();
73 final Set<Node> resultNodes = Sets.newHashSet();
75 for (final ExtendedType unionType : extUnionTypes) {
76 final Node node = new UnionNode(unionType);
77 nodeMap.put(unionType, node);
78 resultNodes.add(node);
81 for (final Node node : resultNodes) {
82 final UnionNode unionNode = (UnionNode) node;
83 final ExtendedType extUnionType = unionNode.getUnionType();
85 final UnionTypeDefinition unionType = (UnionTypeDefinition)
86 extUnionType.getBaseType();
88 final List<TypeDefinition<?>> innerTypes = unionType.getTypes();
89 for (final TypeDefinition<?> typedef : innerTypes) {
90 if (extUnionTypes.contains(typedef)) {
91 final Node toNode = nodeMap.get(typedef);
92 unionNode.addEdge(toNode);
100 private static UnionNode unionTypeToUnionNode(
101 final ExtendedType extUnionType,
102 final Set<ExtendedType> extUnionTypes) {
103 final UnionNode node = new UnionNode(extUnionType);
105 if (extUnionType.getBaseType() instanceof UnionTypeDefinition) {
106 final UnionTypeDefinition unionType = (UnionTypeDefinition)
107 extUnionType.getBaseType();
109 final List<TypeDefinition<?>> innerTypes = unionType.getTypes();
110 for (final TypeDefinition<?> typedef : innerTypes) {
111 if ((typedef != null) && (typedef instanceof ExtendedType)
112 && (typedef.getBaseType() instanceof UnionTypeDefinition)) {
113 if (extUnionTypes.contains(typedef)) {
114 node.addEdge(new UnionNode((ExtendedType) typedef));
124 static final class UnionNode extends NodeImpl {
125 private final ExtendedType unionType;
127 UnionNode(ExtendedType unionType) {
128 this.unionType = unionType;
131 ExtendedType getUnionType() {
136 public boolean equals(Object o) {
140 if (!(o instanceof UnionNode)) {
143 UnionNode unionNode = (UnionNode) o;
144 if (!unionType.equals(unionNode.unionType)) {
151 public int hashCode() {
152 return unionType.hashCode();
156 public String toString() {
157 return "UnionNode{" +
158 "unionType=" + unionType +