BUG-3263: return a Collection for path arguments
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / StackedReversePathArguments.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
3  * This program and the accompanying materials are made available under the
4  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/epl-v10.html
6  */
7 package org.opendaylight.yangtools.yang.data.api;
8
9 import com.google.common.base.Preconditions;
10 import com.google.common.base.Verify;
11 import com.google.common.collect.Iterators;
12 import com.google.common.collect.UnmodifiableIterator;
13 import java.util.Collection;
14 import java.util.Iterator;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
16
17 final class StackedReversePathArguments extends PathArgumentCollection {
18     private final StackedYangInstanceIdentifier identifier;
19     private int size;
20     private volatile boolean haveSize;
21
22     StackedReversePathArguments(final StackedYangInstanceIdentifier identifier) {
23         this.identifier = Preconditions.checkNotNull(identifier);
24     }
25
26     private static int calculateSize(final YangInstanceIdentifier parent) {
27         YangInstanceIdentifier current = parent;
28         for (int i = 1;; ++i) {
29             final Collection<PathArgument> args = current.tryReversePathArguments();
30             if (args != null) {
31                 return i + args.size();
32             }
33
34             Verify.verify(current instanceof StackedYangInstanceIdentifier);
35             current = ((StackedYangInstanceIdentifier)current).getParent();
36         }
37     }
38
39     @Override
40     public int size() {
41         int ret = size;
42         if (!haveSize) {
43             ret = calculateSize(identifier.getParent());
44             size = ret;
45             haveSize = true;
46         }
47
48         return ret;
49     }
50
51
52     @Override
53     public boolean contains(final Object o) {
54         final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o);
55         return Iterators.contains(iterator(), srch);
56     }
57
58     @Override
59     public UnmodifiableIterator<PathArgument> iterator() {
60         return new IteratorImpl(identifier);
61     }
62
63     private static final class IteratorImpl extends UnmodifiableIterator<PathArgument> {
64         private StackedYangInstanceIdentifier identifier;
65         private Iterator<PathArgument> tail;
66
67         IteratorImpl(final StackedYangInstanceIdentifier identifier) {
68             this.identifier = Preconditions.checkNotNull(identifier);
69         }
70
71         @Override
72         public boolean hasNext() {
73             return tail == null || tail.hasNext();
74         }
75
76         @Override
77         public PathArgument next() {
78             if (tail != null) {
79                 return tail.next();
80             }
81
82             final PathArgument ret = identifier.getLastPathArgument();
83             final YangInstanceIdentifier next = identifier.getParent();
84             final Iterable<PathArgument> args = next.tryReversePathArguments();
85             if (args != null) {
86                 tail = args.iterator();
87                 identifier = null;
88             } else {
89                 Verify.verify(next instanceof StackedYangInstanceIdentifier);
90                 identifier = (StackedYangInstanceIdentifier) next;
91             }
92
93             return ret;
94         }
95     }
96 }