2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.v3po.translate.util.read.registry;
19 import static com.google.common.base.Preconditions.checkArgument;
21 import com.google.common.collect.Iterables;
22 import java.util.HashSet;
23 import java.util.LinkedList;
24 import java.util.List;
26 import java.util.stream.Collectors;
27 import javax.annotation.Nonnull;
28 import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 final class TypeHierarchy {
32 private final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent> hierarchy;
34 private TypeHierarchy(@Nonnull final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent> hierarchy) {
35 this.hierarchy = hierarchy;
38 Set<InstanceIdentifier<?>> getAllChildren(InstanceIdentifier<?> id) {
39 final HashSet<InstanceIdentifier<?>> instanceIdentifiers = new HashSet<>();
40 for (InstanceIdentifier<?> childId : getDirectChildren(id)) {
41 instanceIdentifiers.add(childId);
42 instanceIdentifiers.addAll(getAllChildren(childId));
44 return instanceIdentifiers;
47 Set<InstanceIdentifier<?>> getDirectChildren(InstanceIdentifier<?> id) {
48 checkArgument(hierarchy.vertexSet().contains(id),
49 "Unknown reader: %s. Known readers: %s", id, hierarchy.vertexSet());
51 return hierarchy.outgoingEdgesOf(id).stream()
52 .map(hierarchy::getEdgeTarget)
53 .collect(Collectors.toSet());
56 Set<InstanceIdentifier<?>> getRoots() {
57 return hierarchy.vertexSet().stream()
58 .filter(vertex -> hierarchy.incomingEdgesOf(vertex).size() == 0)
59 .collect(Collectors.toSet());
63 * Create reader hierarchy from a flat set of instance identifiers.
65 * @param allIds Set of unkeyed instance identifiers
67 static TypeHierarchy create(@Nonnull Set<InstanceIdentifier<?>> allIds) {
68 final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent>
69 readersHierarchy = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new Parent());
71 for (InstanceIdentifier<?> allId : allIds) {
72 checkArgument(!Iterables.isEmpty(allId.getPathArguments()), "Empty ID detected");
74 if (Iterables.size(allId.getPathArguments()) == 1) {
75 readersHierarchy.addVertex(allId);
78 List<InstanceIdentifier.PathArgument> pathArgs = new LinkedList<>();
79 pathArgs.add(allId.getPathArguments().iterator().next());
81 for (InstanceIdentifier.PathArgument pathArgument : Iterables.skip(allId.getPathArguments(), 1)) {
82 final InstanceIdentifier<?> previous = InstanceIdentifier.create(pathArgs);
83 pathArgs.add(pathArgument);
84 final InstanceIdentifier<?> current = InstanceIdentifier.create(pathArgs);
86 readersHierarchy.addVertex(previous);
87 readersHierarchy.addVertex(current);
90 readersHierarchy.addDagEdge(previous, current);
91 } catch (DirectedAcyclicGraph.CycleFoundException e) {
92 throw new IllegalArgumentException("Loop in hierarchy detected", e);
97 return new TypeHierarchy(readersHierarchy);
100 private static final class Parent{}