/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.yangtools.yang.data.api;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verify;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Nonnull;
-final class StackedYangInstanceIdentifier extends YangInstanceIdentifier {
+final class StackedYangInstanceIdentifier extends YangInstanceIdentifier implements Cloneable {
private static final long serialVersionUID = 1L;
private static final Field PARENT_FIELD;
private transient volatile StackedPathArguments pathArguments;
private transient volatile StackedReversePathArguments reversePathArguments;
- StackedYangInstanceIdentifier(final YangInstanceIdentifier parent, final PathArgument pathArgument, final int hash) {
+ StackedYangInstanceIdentifier(final YangInstanceIdentifier parent, final PathArgument pathArgument,
+ final int hash) {
super(hash);
- this.parent = Preconditions.checkNotNull(parent);
- this.pathArgument = Preconditions.checkNotNull(pathArgument);
+ this.parent = requireNonNull(parent);
+ this.pathArgument = requireNonNull(pathArgument);
+ }
+
+ @Override
+ public StackedYangInstanceIdentifier clone() {
+ try {
+ return (StackedYangInstanceIdentifier) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException("clone() should be supported", e);
+ }
}
@Override
return parent;
}
+ @Nonnull
+ @Override
+ public YangInstanceIdentifier getAncestor(final int depth) {
+ checkArgument(depth >= 0, "Steps cannot be negative");
+
+ // Calculate how far up our FixedYangInstanceIdentifier ancestor is
+ int stackedDepth = 1;
+ YangInstanceIdentifier wlk = getParent();
+ while (wlk instanceof StackedYangInstanceIdentifier) {
+ wlk = wlk.getParent();
+ stackedDepth++;
+ }
+
+ // Guaranteed to come from FixedYangInstanceIdentifier
+ final int fixedDepth = wlk.getPathArguments().size();
+ if (fixedDepth >= depth) {
+ return wlk.getAncestor(depth);
+ }
+
+ // Calculate our depth and check argument
+ final int ourDepth = stackedDepth + fixedDepth;
+ checkArgument(depth <= ourDepth, "Depth %s exceeds maximum depth %s", depth, ourDepth);
+
+ // Requested depth is covered by the stack, traverse up for specified number of steps
+ final int toWalk = ourDepth - depth;
+ YangInstanceIdentifier result = this;
+ for (int i = 0; i < toWalk; ++i) {
+ result = result.getParent();
+ }
+
+ return result;
+ }
+
@Override
public boolean isEmpty() {
return false;
final List<PathArgument> stack = new ArrayList<>();
YangInstanceIdentifier current = this;
do {
- Verify.verify(current instanceof StackedYangInstanceIdentifier);
+ verify(current instanceof StackedYangInstanceIdentifier);
final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) current;
stack.add(stacked.getLastPathArgument());
current = stacked.getParent();
return pathArgument;
}
+ @Nonnull
@Override
StackedPathArguments tryPathArguments() {
return pathArguments;
}
+ @Nonnull
@Override
StackedReversePathArguments tryReversePathArguments() {
return reversePathArguments;
}
+ @Nonnull
@Override
YangInstanceIdentifier createRelativeIdentifier(final int skipFromRoot) {
// TODO: can we optimize this one?
if (other instanceof StackedYangInstanceIdentifier) {
final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) other;
return pathArgument.equals(stacked.pathArgument) && parent.equals(stacked.parent);
- } else {
- return super.pathArgumentsEqual(other);
}
+ return super.pathArgumentsEqual(other);
}
private void readObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {