Bug 5019: Add QName param to NormalizedNodeWriter#leafSetEntryNode
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / FixedYangInstanceIdentifier.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.collect.ImmutableList;
12 import java.io.ObjectStreamException;
13 import java.util.List;
14 import org.opendaylight.yangtools.util.HashCodeBuilder;
15
16 final class FixedYangInstanceIdentifier extends YangInstanceIdentifier implements Cloneable {
17     static final FixedYangInstanceIdentifier EMPTY_INSTANCE = new FixedYangInstanceIdentifier(ImmutableList.<PathArgument>of(), new HashCodeBuilder<>().build());
18     private static final long serialVersionUID = 1L;
19     private final ImmutableList<PathArgument> path;
20     private transient volatile YangInstanceIdentifier parent;
21
22     private FixedYangInstanceIdentifier(final ImmutableList<PathArgument> path, final int hash) {
23         super(hash);
24         this.path = Preconditions.checkNotNull(path, "path must not be null.");
25     }
26
27     static FixedYangInstanceIdentifier create(final Iterable<? extends PathArgument> path, final int hash) {
28         return new FixedYangInstanceIdentifier(ImmutableList.copyOf(path), hash);
29     }
30
31     @Override
32     public boolean isEmpty() {
33         return path.isEmpty();
34     }
35
36     @Override
37     public FixedYangInstanceIdentifier clone() {
38         try {
39             return (FixedYangInstanceIdentifier) super.clone();
40         } catch (CloneNotSupportedException e) {
41             throw new IllegalStateException("clone() should be supported", e);
42         }
43     }
44
45     @Override
46     public YangInstanceIdentifier getParent() {
47         if (path.isEmpty()) {
48             return null;
49         }
50
51         YangInstanceIdentifier ret = parent;
52         if (ret == null) {
53             ret = YangInstanceIdentifier.create(path.subList(0, path.size() - 1));
54             parent = ret;
55         }
56
57         return ret;
58     }
59
60     @Override
61     public YangInstanceIdentifier getAncestor(final int depth) {
62         Preconditions.checkArgument(depth >= 0, "Negative depth is not allowed");
63         Preconditions.checkArgument(depth <= path.size(), "Depth %s exceeds maximum depth %s", depth, path.size());
64
65         if (depth == path.size()) {
66             return this;
67         }
68         if (depth == path.size() - 1) {
69             // Use the parent cache
70             return getParent();
71         }
72         return YangInstanceIdentifier.create(path.subList(0, depth));
73     }
74
75     @Override
76     public List<PathArgument> getPathArguments() {
77         return path;
78     }
79
80     @Override
81     public List<PathArgument> getReversePathArguments() {
82         return path.reverse();
83     }
84
85     @Override
86     List<PathArgument> tryPathArguments() {
87         return path;
88     }
89
90     @Override
91     List<PathArgument> tryReversePathArguments() {
92         return path.reverse();
93     }
94
95     @Override
96     public PathArgument getLastPathArgument() {
97         return path.isEmpty()? null : path.get(path.size() - 1);
98     }
99
100     @Override
101     YangInstanceIdentifier createRelativeIdentifier(final int skipFromRoot) {
102         if (skipFromRoot == path.size()) {
103             return EMPTY_INSTANCE;
104         }
105
106         final ImmutableList<PathArgument> newPath = path.subList(skipFromRoot, path.size());
107         final HashCodeBuilder<PathArgument> hash = new HashCodeBuilder<>();
108         for (PathArgument a : newPath) {
109             hash.addArgument(a);
110         }
111
112         return new FixedYangInstanceIdentifier(newPath, hash.build());
113     }
114
115     private Object readResolve() throws ObjectStreamException {
116         return path.isEmpty() ? EMPTY_INSTANCE : this;
117     }
118
119     @Override
120     boolean pathArgumentsEqual(final YangInstanceIdentifier other) {
121         if (other instanceof FixedYangInstanceIdentifier) {
122             return path.equals(((FixedYangInstanceIdentifier) other).path);
123         } else {
124             return super.pathArgumentsEqual(other);
125         }
126     }
127
128     @Override
129     public FixedYangInstanceIdentifier toOptimized() {
130         return this;
131     }
132 }