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
7 package org.opendaylight.yangtools.yang.data.api;
9 import com.google.common.base.Preconditions;
10 import com.google.common.base.Verify;
11 import com.google.common.collect.Iterables;
12 import com.google.common.collect.Lists;
13 import java.io.IOException;
14 import java.io.ObjectInputStream;
15 import java.io.ObjectOutputStream;
16 import java.lang.reflect.Field;
17 import java.util.ArrayList;
18 import java.util.List;
20 final class StackedYangInstanceIdentifier extends YangInstanceIdentifier {
21 private static final long serialVersionUID = 1L;
22 private static final Field PARENT_FIELD;
27 f = StackedYangInstanceIdentifier.class.getDeclaredField("parent");
28 } catch (NoSuchFieldException | SecurityException e) {
29 throw new ExceptionInInitializerError(e);
31 f.setAccessible(true);
36 private final YangInstanceIdentifier parent;
37 private final PathArgument pathArgument;
39 private transient volatile StackedPathArguments pathArguments;
40 private transient volatile StackedReversePathArguments reversePathArguments;
42 StackedYangInstanceIdentifier(final YangInstanceIdentifier parent, final PathArgument pathArgument, final int hash) {
44 this.parent = Preconditions.checkNotNull(parent);
45 this.pathArgument = Preconditions.checkNotNull(pathArgument);
49 public YangInstanceIdentifier getParent() {
54 public boolean isEmpty() {
59 public List<PathArgument> getPathArguments() {
60 StackedPathArguments ret = tryPathArguments();
62 final List<PathArgument> stack = new ArrayList<>();
63 YangInstanceIdentifier current = this;
65 Verify.verify(current instanceof StackedYangInstanceIdentifier);
66 final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) current;
67 stack.add(stacked.getLastPathArgument());
68 current = stacked.getParent();
69 } while (current.tryPathArguments() == null);
71 ret = new StackedPathArguments(current, Lists.reverse(stack));
79 public List<PathArgument> getReversePathArguments() {
80 StackedReversePathArguments ret = tryReversePathArguments();
82 ret = new StackedReversePathArguments(this);
83 reversePathArguments = ret;
89 public PathArgument getLastPathArgument() {
94 StackedPathArguments tryPathArguments() {
99 StackedReversePathArguments tryReversePathArguments() {
100 return reversePathArguments;
104 YangInstanceIdentifier createRelativeIdentifier(final int skipFromRoot) {
105 // TODO: can we optimize this one?
106 return YangInstanceIdentifier.create(Iterables.skip(getPathArguments(), skipFromRoot));
110 boolean pathArgumentsEqual(final YangInstanceIdentifier other) {
111 if (other instanceof StackedYangInstanceIdentifier) {
112 final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) other;
113 return pathArgument.equals(stacked.pathArgument) && parent.equals(stacked.parent);
115 return super.pathArgumentsEqual(other);
119 private void readObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
120 inputStream.defaultReadObject();
122 final FixedYangInstanceIdentifier p = (FixedYangInstanceIdentifier) inputStream.readObject();
124 PARENT_FIELD.set(this, p);
125 } catch (IllegalArgumentException | IllegalAccessException e) {
126 throw new IOException("Failed to set parent", e);
130 private void writeObject(final ObjectOutputStream outputStream) throws IOException {
131 outputStream.defaultWriteObject();
133 final FixedYangInstanceIdentifier p;
134 if (parent instanceof FixedYangInstanceIdentifier) {
135 p = (FixedYangInstanceIdentifier) parent;
137 p = FixedYangInstanceIdentifier.create(parent.getPathArguments(), parent.hashCode());
139 outputStream.writeObject(p);
143 public YangInstanceIdentifier toOptimized() {
144 return FixedYangInstanceIdentifier.create(getPathArguments());