Merge "Bug 499: Initial implementation of supporting tree structures"
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / store / impl / tree / TreeNodeUtils.java
1 /*
2  * Copyright (c) 2014 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.controller.md.sal.dom.store.impl.tree;
9
10 import java.util.AbstractMap.SimpleEntry;
11 import java.util.Iterator;
12 import java.util.Map;
13
14 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
16
17 import com.google.common.base.Optional;
18
19 public class TreeNodeUtils {
20
21     /**
22      * Finds a node in tree
23      *
24      * @param tree Data Tree
25      * @param path Path to the node
26      * @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise.
27      *
28      */
29     public static <T extends StoreTreeNode<T>> Optional<T> findNode(final T tree, final InstanceIdentifier path) {
30         Optional<T> current = Optional.<T> of(tree);
31         Iterator<PathArgument> pathIter = path.getPath().iterator();
32         while (current.isPresent() && pathIter.hasNext()) {
33             current = current.get().getChild(pathIter.next());
34         }
35         return current;
36     }
37
38     /**
39      * Finds a node or closest parent in  the tree
40      *
41      * @param tree Data Tree
42      * @param path Path to the node
43      * @return Map.Entry Entry with key which is path to closest parent and value is parent node.
44      *
45      */
46     public static <T extends StoreTreeNode<T>> Map.Entry<InstanceIdentifier, T> findClosest(final T tree, final InstanceIdentifier path) {
47         Optional<T> parent = Optional.<T>of(tree);
48         Optional<T> current = Optional.<T> of(tree);
49
50         int nesting = 0;
51         Iterator<PathArgument> pathIter = path.getPath().iterator();
52         while (current.isPresent() && pathIter.hasNext()) {
53             parent = current;
54             current = current.get().getChild(pathIter.next());
55             nesting++;
56         }
57         if(current.isPresent()) {
58             final InstanceIdentifier currentPath = new InstanceIdentifier(path.getPath().subList(0, nesting));
59             return new SimpleEntry<InstanceIdentifier,T>(currentPath,current.get());
60         }
61         // Nesting minus one is safe, since current is allways present when nesting = 0
62         // so this prat of code is never triggered, in cases nesting == 0;
63         final InstanceIdentifier parentPath = new InstanceIdentifier(path.getPath().subList(0, nesting - 1));
64         return new SimpleEntry<InstanceIdentifier,T>(parentPath,parent.get());
65     }
66
67 }