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 List<PathArgument> stack = new ArrayList<>();
63 YangInstanceIdentifier current = this;
64 while (current.tryPathArguments() == null) {
65 Verify.verify(current instanceof StackedYangInstanceIdentifier);
67 final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) current;
68 stack.add(stacked.getLastPathArgument());
69 current = stacked.getParent();
72 ret = new StackedPathArguments(current, Lists.reverse(stack));
80 public List<PathArgument> getReversePathArguments() {
81 StackedReversePathArguments ret = tryReversePathArguments();
83 ret = new StackedReversePathArguments(this);
84 reversePathArguments = ret;
90 public PathArgument getLastPathArgument() {
95 StackedPathArguments tryPathArguments() {
100 StackedReversePathArguments tryReversePathArguments() {
101 return reversePathArguments;
105 YangInstanceIdentifier createRelativeIdentifier(final int skipFromRoot) {
106 // TODO: can we optimize this one?
107 return YangInstanceIdentifier.create(Iterables.skip(getPathArguments(), skipFromRoot));
111 boolean pathArgumentsEqual(final YangInstanceIdentifier other) {
112 if (other instanceof StackedYangInstanceIdentifier) {
113 final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) other;
114 return pathArgument.equals(stacked.pathArgument) && parent.equals(stacked.parent);
116 return super.pathArgumentsEqual(other);
120 private void readObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
121 inputStream.defaultReadObject();
123 final FixedYangInstanceIdentifier p = (FixedYangInstanceIdentifier) inputStream.readObject();
125 PARENT_FIELD.set(this, p);
126 } catch (IllegalArgumentException | IllegalAccessException e) {
127 throw new IOException("Failed to set parent", e);
131 private void writeObject(final ObjectOutputStream outputStream) throws IOException {
132 outputStream.defaultWriteObject();
134 final FixedYangInstanceIdentifier p;
135 if (parent instanceof FixedYangInstanceIdentifier) {
136 p = (FixedYangInstanceIdentifier) parent;
138 p = FixedYangInstanceIdentifier.create(parent.getPathArguments(), parent.hashCode());
140 outputStream.writeObject(p);