002de6b6926fd8288d5ddab0d253a6f0ec764b14
[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 PathArgumentList {
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 PathArgument get(final int index) {
60         return Iterators.get(iterator(), index);
61     }
62
63     @Override
64     public int indexOf(final Object o) {
65         final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o);
66         return super.indexOf(srch);
67     }
68
69     @Override
70     public int lastIndexOf(final Object o) {
71         final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o);
72
73         int ret = -1;
74         final Iterator<PathArgument> it = iterator();
75         for (int i = 0; it.hasNext(); ++i) {
76             if (srch.equals(it.next())) {
77                 ret = i;
78             }
79         }
80
81         return ret;
82     }
83
84     @Override
85     public UnmodifiableIterator<PathArgument> iterator() {
86         return new IteratorImpl(identifier);
87     }
88
89     private static final class IteratorImpl extends UnmodifiableIterator<PathArgument> {
90         private StackedYangInstanceIdentifier identifier;
91         private Iterator<PathArgument> tail;
92
93         IteratorImpl(final StackedYangInstanceIdentifier identifier) {
94             this.identifier = Preconditions.checkNotNull(identifier);
95         }
96
97         @Override
98         public boolean hasNext() {
99             return tail == null || tail.hasNext();
100         }
101
102         @Override
103         public PathArgument next() {
104             if (tail != null) {
105                 return tail.next();
106             }
107
108             final PathArgument ret = identifier.getLastPathArgument();
109             final YangInstanceIdentifier next = identifier.getParent();
110             final Iterable<PathArgument> args = next.tryReversePathArguments();
111             if (args != null) {
112                 tail = args.iterator();
113                 identifier = null;
114             } else {
115                 Verify.verify(next instanceof StackedYangInstanceIdentifier);
116                 identifier = (StackedYangInstanceIdentifier) next;
117             }
118
119             return ret;
120         }
121     }
122 }