From 5ad97de7baf1ea8575349e4c5625525101d7749a Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 19 May 2015 00:29:06 +0200 Subject: [PATCH] BUG-3263: return a Collection for path arguments With the rework in place, we can now return a Collection from both getPathArguments() and getReversePathArguments() even in the stacked case. Change-Id: I51179320022f060d9fb2597f473d0919d391092c Signed-off-by: Robert Varga --- .../data/api/FixedYangInstanceIdentifier.java | 5 ++ .../yang/data/api/IterablePathArguments.java | 21 +++++++++ .../yang/data/api/PathArgumentCollection.java | 47 +++++++++++++++++++ .../yang/data/api/StackedPathArguments.java | 31 ++++++++---- .../data/api/StackedReversePathArguments.java | 47 +++++++++++++++++-- .../api/StackedYangInstanceIdentifier.java | 24 ++++++---- .../yang/data/api/YangInstanceIdentifier.java | 12 +++-- 7 files changed, 160 insertions(+), 27 deletions(-) create mode 100644 yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/IterablePathArguments.java create mode 100644 yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/PathArgumentCollection.java diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/FixedYangInstanceIdentifier.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/FixedYangInstanceIdentifier.java index cfe41829ea..20045cf43c 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/FixedYangInstanceIdentifier.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/FixedYangInstanceIdentifier.java @@ -67,6 +67,11 @@ final class FixedYangInstanceIdentifier extends YangInstanceIdentifier { return path; } + @Override + List tryReversePathArguments() { + return path.reverse(); + } + @Override public PathArgument getLastPathArgument() { return path.isEmpty()? null : path.get(path.size() - 1); diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/IterablePathArguments.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/IterablePathArguments.java new file mode 100644 index 0000000000..51b744ada5 --- /dev/null +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/IterablePathArguments.java @@ -0,0 +1,21 @@ +/* + * 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 org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; + +/* + * This base class provides binary backwards compatibility for Helium, which + * used an Iterable instead of collection. + * + * @deprecated remove this class in Beryllium + */ +@Deprecated +abstract class IterablePathArguments { + public abstract Iterable getPathArguments(); + public abstract Iterable getReversePathArguments(); +} diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/PathArgumentCollection.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/PathArgumentCollection.java new file mode 100644 index 0000000000..5ed5e256a0 --- /dev/null +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/PathArgumentCollection.java @@ -0,0 +1,47 @@ +/* + * 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.collect.UnmodifiableIterator; +import java.util.AbstractCollection; +import java.util.Collection; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; + +abstract class PathArgumentCollection extends AbstractCollection { + @Override + public abstract UnmodifiableIterator iterator(); + + @Override + public final boolean isEmpty() { + return false; + } + + @Override + public final boolean remove(final Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public final boolean addAll(final Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public final boolean removeAll(final Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public final boolean retainAll(final Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public final void clear() { + throw new UnsupportedOperationException(); + } +} diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedPathArguments.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedPathArguments.java index 6efb2b444a..ed9d65b8ba 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedPathArguments.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedPathArguments.java @@ -13,26 +13,37 @@ import java.util.Iterator; import java.util.List; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; -final class StackedPathArguments implements Iterable { - private final List stack; - private final YangInstanceIdentifier base; +final class StackedPathArguments extends PathArgumentCollection { + private final Collection base; + private final List stack; - public StackedPathArguments(final YangInstanceIdentifier base, final List stack) { - this.base = Preconditions.checkNotNull(base); + public StackedPathArguments(final YangInstanceIdentifier base, final List stack) { + this.base = base.getPathArguments(); this.stack = Preconditions.checkNotNull(stack); } @Override - public Iterator iterator() { + public int size() { + return stack.size() + base.size(); + } + + @Override + public boolean contains(final Object o) { + final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o); + return stack.contains(srch) || base.contains(srch); + } + + @Override + public UnmodifiableIterator iterator() { return new IteratorImpl(base, stack); } private static final class IteratorImpl extends UnmodifiableIterator { - private final Iterator stack; + private final Iterator stack; private final Iterator base; - IteratorImpl(final YangInstanceIdentifier base, final Collection stack) { - this.base = base.getPathArguments().iterator(); + IteratorImpl(final Iterable base, final Iterable stack) { + this.base = base.iterator(); this.stack = stack.iterator(); } @@ -46,7 +57,7 @@ final class StackedPathArguments implements Iterable { if (base.hasNext()) { return base.next(); } - return stack.next().getLastPathArgument(); + return stack.next(); } } } diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedReversePathArguments.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedReversePathArguments.java index 54f6498bc2..5e71817b2f 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedReversePathArguments.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedReversePathArguments.java @@ -7,19 +7,56 @@ package org.opendaylight.yangtools.yang.data.api; import com.google.common.base.Preconditions; +import com.google.common.base.Verify; +import com.google.common.collect.Iterators; import com.google.common.collect.UnmodifiableIterator; +import java.util.Collection; import java.util.Iterator; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; -final class StackedReversePathArguments implements Iterable { +final class StackedReversePathArguments extends PathArgumentCollection { private final StackedYangInstanceIdentifier identifier; + private int size; + private volatile boolean haveSize; StackedReversePathArguments(final StackedYangInstanceIdentifier identifier) { this.identifier = Preconditions.checkNotNull(identifier); } + private static int calculateSize(final YangInstanceIdentifier parent) { + YangInstanceIdentifier current = parent; + for (int i = 1;; ++i) { + final Collection args = current.tryReversePathArguments(); + if (args != null) { + return i + args.size(); + } + + Verify.verify(current instanceof StackedYangInstanceIdentifier); + current = ((StackedYangInstanceIdentifier)current).getParent(); + } + } + + @Override + public int size() { + int ret = size; + if (!haveSize) { + ret = calculateSize(identifier.getParent()); + size = ret; + haveSize = true; + } + + return ret; + } + + + @Override + public boolean contains(final Object o) { + final PathArgument srch = (PathArgument) Preconditions.checkNotNull(o); + return Iterators.contains(iterator(), srch); + } + @Override - public Iterator iterator() { + public UnmodifiableIterator iterator() { return new IteratorImpl(identifier); } @@ -44,10 +81,12 @@ final class StackedReversePathArguments implements Iterable { final PathArgument ret = identifier.getLastPathArgument(); final YangInstanceIdentifier next = identifier.getParent(); - if (!(next instanceof StackedYangInstanceIdentifier)) { - tail = next.getReversePathArguments().iterator(); + final Iterable args = next.tryReversePathArguments(); + if (args != null) { + tail = args.iterator(); identifier = null; } else { + Verify.verify(next instanceof StackedYangInstanceIdentifier); identifier = (StackedYangInstanceIdentifier) next; } diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedYangInstanceIdentifier.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedYangInstanceIdentifier.java index dc803ece58..d204bf09cb 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedYangInstanceIdentifier.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedYangInstanceIdentifier.java @@ -16,6 +16,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; @@ -43,8 +44,8 @@ final class StackedYangInstanceIdentifier extends YangInstanceIdentifier { private final PathArgument pathArgument; private transient volatile ImmutableList legacyPath; - private transient volatile Iterable pathArguments; - private transient volatile Iterable reversePathArguments; + private transient volatile StackedPathArguments pathArguments; + private transient volatile StackedReversePathArguments reversePathArguments; StackedYangInstanceIdentifier(final YangInstanceIdentifier parent, final PathArgument pathArgument, final int hash) { super(hash); @@ -77,16 +78,16 @@ final class StackedYangInstanceIdentifier extends YangInstanceIdentifier { } @Override - public Iterable getPathArguments() { - Iterable ret = tryPathArguments(); + public Collection getPathArguments() { + StackedPathArguments ret = tryPathArguments(); if (ret == null) { - List stack = new ArrayList<>(); + List stack = new ArrayList<>(); YangInstanceIdentifier current = this; while (current.tryPathArguments() == null) { Verify.verify(current instanceof StackedYangInstanceIdentifier); final StackedYangInstanceIdentifier stacked = (StackedYangInstanceIdentifier) current; - stack.add(stacked); + stack.add(stacked.getLastPathArgument()); current = stacked.getParent(); } @@ -98,8 +99,8 @@ final class StackedYangInstanceIdentifier extends YangInstanceIdentifier { } @Override - public Iterable getReversePathArguments() { - Iterable ret = reversePathArguments; + public Collection getReversePathArguments() { + StackedReversePathArguments ret = tryReversePathArguments(); if (ret == null) { ret = new StackedReversePathArguments(this); reversePathArguments = ret; @@ -113,10 +114,15 @@ final class StackedYangInstanceIdentifier extends YangInstanceIdentifier { } @Override - Iterable tryPathArguments() { + StackedPathArguments tryPathArguments() { return pathArguments; } + @Override + StackedReversePathArguments tryReversePathArguments() { + return reversePathArguments; + } + @Override YangInstanceIdentifier createRelativeIdentifier(final int skipFromRoot) { // TODO: can we optimize this one? diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java index 55599305c0..a582e5c32a 100644 --- a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java +++ b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java @@ -14,6 +14,7 @@ import com.google.common.collect.Iterables; import java.io.Serializable; import java.lang.reflect.Array; import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -63,7 +64,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; * * @see RFC6020 */ -public abstract class YangInstanceIdentifier implements Path, Immutable, Serializable { +public abstract class YangInstanceIdentifier extends IterablePathArguments implements Path, Immutable, Serializable { /** * An empty {@link YangInstanceIdentifier}. It corresponds to the path of the conceptual * root of the YANG namespace. @@ -83,7 +84,8 @@ public abstract class YangInstanceIdentifier implements Path tryPathArguments(); + @Nonnull abstract Collection tryPathArguments(); + @Nonnull abstract Collection tryReversePathArguments(); /** * Check if this instance identifier has empty path arguments, e.g. it is @@ -115,7 +117,8 @@ public abstract class YangInstanceIdentifier implements Path getPathArguments(); + @Override + public abstract Collection getPathArguments(); /** * Returns an iterable of path arguments in reverse order. This is useful @@ -123,7 +126,8 @@ public abstract class YangInstanceIdentifier implements Path getReversePathArguments(); + @Override + public abstract Collection getReversePathArguments(); /** * Returns the last PathArgument. This is equivalent of iterating -- 2.36.6