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 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.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 import com.google.common.base.Function;
23 import com.google.common.collect.Lists;
24 import com.google.common.collect.Maps;
25 import com.google.common.collect.Sets;
27 public class UnionDependencySort {
28 private static final Logger LOGGER = LoggerFactory.getLogger(UnionDependencySort.class);
31 * Sorts union types by mutual dependencies.
33 * At the beginning the union types are selected from
34 * <code>typeDefinitions</code> and wrapped to nodes. The nodes are sorted
35 * and then the wrapped payload is extracted.
37 * @param typeDefinitions
38 * set of type definitions.
39 * @return list of extended type which are sorted by mutual dependencies
40 * @throws IllegalArgumentException
41 * if <code>typeDefinitions</code> equals <code>null</code>
43 public List<ExtendedType> sort(final Set<TypeDefinition<?>> typeDefinitions) {
44 if (typeDefinitions == null) {
45 LOGGER.error("Set of Type Definitions cannot be NULL!");
46 throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!");
49 final Set<ExtendedType> extUnionTypes = unionsFromTypeDefinitions(typeDefinitions);
51 final Set<Node> unsorted = unionTypesToNodes(extUnionTypes);
53 final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
54 return Lists.transform(sortedNodes, new Function<Node, ExtendedType>() {
56 public ExtendedType apply(Node input) {
57 return (ExtendedType) (((NodeWrappedType) input).getWrappedType());
63 * Extracts only union types from <code>typeDefinitions</code> set.
65 * @param typeDefinitions
66 * set of all type definitions
67 * @return set of extended type which are union type definition
69 private Set<ExtendedType> unionsFromTypeDefinitions(final Set<TypeDefinition<?>> typeDefinitions) {
70 final Set<ExtendedType> unions = Sets.newHashSet();
72 for (final TypeDefinition<?> typedef : typeDefinitions) {
73 if ((typedef != null) && (typedef.getBaseType() != null) && (typedef instanceof ExtendedType)
74 && (typedef.getBaseType() instanceof UnionTypeDefinition)) {
75 unions.add((ExtendedType) typedef);
82 * Wraps every extended type which represents union to node type and adds to
83 * every node information about dependencies.
85 * The mapping from union type to node is created. For every created node
86 * (next <i>nodeFrom</i>) is for its wrapped union type passed the list of
87 * inner types through and only those inner types which represent union type
88 * are next considered. For every inner union type is found its wrapping
89 * node (next as <i>nodeTo</i>). This dependency relationship between
90 * nodeFrom and all found nodesTo is modeled with creating of one edge from
94 * @param extUnionTypes
95 * set of extended types which represents union types
96 * @return set of nodes which contains wrapped union types set of node where
97 * each one contains wrapped one union type
99 private Set<Node> unionTypesToNodes(final Set<ExtendedType> extUnionTypes) {
100 final Map<ExtendedType, Node> nodeMap = Maps.newHashMap();
101 final Set<Node> resultNodes = Sets.newHashSet();
103 for (final ExtendedType unionType : extUnionTypes) {
104 final Node node = new NodeWrappedType(unionType);
105 nodeMap.put(unionType, node);
106 resultNodes.add(node);
109 for (final Node node : resultNodes) {
110 final NodeWrappedType nodeFrom = (NodeWrappedType) node;
111 final ExtendedType extUnionType = (ExtendedType) nodeFrom.getWrappedType();
113 final UnionTypeDefinition unionType = (UnionTypeDefinition) extUnionType.getBaseType();
115 final List<TypeDefinition<?>> innerTypes = unionType.getTypes();
116 for (final TypeDefinition<?> typedef : innerTypes) {
117 if (extUnionTypes.contains(typedef)) {
118 final Node toNode = nodeMap.get(typedef);
119 nodeFrom.addEdge(toNode);