382e1aaa1dd61c117c7a02f2e933bac39d07f5bc
[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  *
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;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Verify;
12 import com.google.common.collect.Iterators;
13 import com.google.common.collect.UnmodifiableIterator;
14 import java.util.Collection;
15 import java.util.Iterator;
16 import javax.annotation.Nonnull;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
18
19 final class StackedReversePathArguments extends PathArgumentList {
20     private final StackedYangInstanceIdentifier identifier;
21     private int size;
22     private volatile boolean haveSize;
23
24     StackedReversePathArguments(final StackedYangInstanceIdentifier identifier) {
25         this.identifier = Preconditions.checkNotNull(identifier);
26     }
27
28     private static int calculateSize(final YangInstanceIdentifier parent) {
29         YangInstanceIdentifier current = parent;
30         for (int i = 1;; ++i) {
31             final Collection<PathArgument> args = current.tryReversePathArguments();
32             if (args != null) {
33                 return i + args.size();
34             }
35
36             Verify.verify(current instanceof StackedYangInstanceIdentifier);
37             current = current.getParent();
38         }
39     }
40
41     @Override
42     public int size() {
43         int ret = size;
44         if (!haveSize) {
45             ret = calculateSize(identifier.getParent());
46             size = ret;
47             haveSize = true;
48         }
49
50         return ret;
51     }
52
53
54     @Override
55     public boolean contains(final Object o) {
56         final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o);
57         return Iterators.contains(iterator(), srch);
58     }
59
60     @Override
61     public PathArgument get(final int index) {
62         return Iterators.get(iterator(), index);
63     }
64
65     @Override
66     public int indexOf(final Object o) {
67         final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o);
68         return super.indexOf(srch);
69     }
70
71     @Override
72     public int lastIndexOf(final Object o) {
73         final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o);
74
75         int ret = -1;
76         final Iterator<PathArgument> it = iterator();
77         for (int i = 0; it.hasNext(); ++i) {
78             if (srch.equals(it.next())) {
79                 ret = i;
80             }
81         }
82
83         return ret;
84     }
85
86     @Nonnull
87     @Override
88     public UnmodifiableIterator<PathArgument> iterator() {
89         return new IteratorImpl(identifier);
90     }
91
92     private static final class IteratorImpl extends UnmodifiableIterator<PathArgument> {
93         private StackedYangInstanceIdentifier identifier;
94         private Iterator<PathArgument> tail;
95
96         IteratorImpl(final StackedYangInstanceIdentifier identifier) {
97             this.identifier = Preconditions.checkNotNull(identifier);
98         }
99
100         @Override
101         public boolean hasNext() {
102             return tail == null || tail.hasNext();
103         }
104
105         @Override
106         public PathArgument next() {
107             if (tail != null) {
108                 return tail.next();
109             }
110
111             final PathArgument ret = identifier.getLastPathArgument();
112             final YangInstanceIdentifier next = identifier.getParent();
113             final Iterable<PathArgument> args = next.tryReversePathArguments();
114             if (args != null) {
115                 tail = args.iterator();
116                 identifier = null;
117             } else {
118                 Verify.verify(next instanceof StackedYangInstanceIdentifier);
119                 identifier = (StackedYangInstanceIdentifier) next;
120             }
121
122             return ret;
123         }
124     }
125 }