Fix various eclipse warnings
[mdsal.git] / binding / mdsal-binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / yang / types / UnionDependencySort.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.sal.binding.yang.types;
9
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;
15 import java.util.Map;
16 import java.util.Set;
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;
24
25 public class UnionDependencySort {
26     private static final Logger LOGGER = LoggerFactory.getLogger(UnionDependencySort.class);
27
28     /**
29      * Sorts union types by mutual dependencies.
30      *
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.
34      *
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>
40      */
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!");
45         }
46
47         final Set<ExtendedType> extUnionTypes = unionsFromTypeDefinitions(typeDefinitions);
48
49         final Set<Node> unsorted = unionTypesToNodes(extUnionTypes);
50
51         final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
52         return Lists.transform(sortedNodes, new Function<Node, ExtendedType>() {
53             @Override
54             public ExtendedType apply(final Node input) {
55                 return (ExtendedType) (((NodeWrappedType) input).getWrappedType());
56             }
57         });
58     }
59
60     /**
61      * Extracts only union types from <code>typeDefinitions</code> set.
62      *
63      * @param typeDefinitions
64      *            set of all type definitions
65      * @return set of extended type which are union type definition
66      */
67     private static Set<ExtendedType> unionsFromTypeDefinitions(final Set<TypeDefinition<?>> typeDefinitions) {
68         final Set<ExtendedType> unions = Sets.newHashSet();
69
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);
74             }
75         }
76         return unions;
77     }
78
79     /**
80      * Wraps every extended type which represents union to node type and adds to
81      * every node information about dependencies.
82      *
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
89      * nodeFrom to nodeTo.
90      *
91      *
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
96      */
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();
100
101         for (final ExtendedType unionType : extUnionTypes) {
102             final Node node = new NodeWrappedType(unionType);
103             nodeMap.put(unionType, node);
104             resultNodes.add(node);
105         }
106
107         for (final Node node : resultNodes) {
108             final NodeWrappedType nodeFrom = (NodeWrappedType) node;
109             final ExtendedType extUnionType = (ExtendedType) nodeFrom.getWrappedType();
110
111             final UnionTypeDefinition unionType = (UnionTypeDefinition) extUnionType.getBaseType();
112
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);
118                 }
119             }
120         }
121
122         return resultNodes;
123     }
124
125 }