Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / schema / DuplicateFinder.java
1 /*
2  * Copyright (c) 2015 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.yang.data.api.schema;
9
10 import java.util.HashMap;
11 import java.util.IdentityHashMap;
12 import java.util.Map;
13 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
14
15 final class DuplicateFinder {
16     private final Map<NormalizedNode<?, ?>, DuplicateEntry> identities = new IdentityHashMap<>();
17     private final Map<NormalizedNode<?, ?>, DuplicateEntry> duplicates = new HashMap<>();
18
19     private DuplicateFinder() {
20         // Hidden on purpose
21     }
22
23     private void findDuplicates(final YangInstanceIdentifier path, final NormalizedNode<?, ?> node) {
24         final DuplicateEntry i = identities.get(node);
25         if (i == null) {
26             final DuplicateEntry d = duplicates.get(node);
27             if (d == null) {
28                 final DuplicateEntry n = new DuplicateEntry(path);
29                 identities.put(node, n);
30                 duplicates.put(node, n);
31             } else {
32                 d.addDuplicate(path);
33             }
34
35             if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
36                 final NormalizedNodeContainer<?, ?, ?> container = (NormalizedNodeContainer<?, ?, ?>) node;
37
38                 for (NormalizedNode<?, ?> c : container.getValue()) {
39                     findDuplicates(path.node(c.getIdentifier()), c);
40                 }
41             }
42         } else {
43             i.addHardLink(path);
44         }
45     }
46
47     /**
48      * Recursively scan a {@link NormalizedNode} instance and its children and
49      * produce a collection of {@link DuplicateEntry} objects. Each holds the
50      * original definition path and a list of hard/softlinks.
51      *
52      * @param node Root node, may not be null.
53      * @return List of entries
54      */
55     static Map<NormalizedNode<?, ?>, DuplicateEntry> findDuplicates(final NormalizedNode<?, ?> node) {
56         final DuplicateFinder finder = new DuplicateFinder();
57         finder.findDuplicates(YangInstanceIdentifier.empty(), node);
58         return finder.identities;
59     }
60 }