BUG-3263: return a Collection for path arguments 85/20685/10
authorRobert Varga <rovarga@cisco.com>
Mon, 18 May 2015 22:29:06 +0000 (00:29 +0200)
committerRobert Varga <rovarga@cisco.com>
Tue, 19 May 2015 08:49:08 +0000 (10:49 +0200)
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 <rovarga@cisco.com>
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/FixedYangInstanceIdentifier.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/IterablePathArguments.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/PathArgumentCollection.java [new file with mode: 0644]
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedPathArguments.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedReversePathArguments.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/StackedYangInstanceIdentifier.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java

index cfe41829ea688400362bc75ba4943d404b2032dd..20045cf43ca3a61d0e287a930fb2fe9ae7065195 100644 (file)
@@ -67,6 +67,11 @@ final class FixedYangInstanceIdentifier extends YangInstanceIdentifier {
         return path;
     }
 
+    @Override
+    List<PathArgument> 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 (file)
index 0000000..51b744a
--- /dev/null
@@ -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<PathArgument> getPathArguments();
+    public abstract Iterable<PathArgument> 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 (file)
index 0000000..5ed5e25
--- /dev/null
@@ -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<PathArgument> {
+    @Override
+    public abstract UnmodifiableIterator<PathArgument> 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<? extends PathArgument> 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();
+    }
+}
index 6efb2b444a837f9dfc1d6d66b00d008dc594a06b..ed9d65b8ba2f80a1c2e7c5be68f9bee50d39a761 100644 (file)
@@ -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<PathArgument> {
-    private final List<StackedYangInstanceIdentifier> stack;
-    private final YangInstanceIdentifier base;
+final class StackedPathArguments extends PathArgumentCollection {
+    private final Collection<PathArgument> base;
+    private final List<PathArgument> stack;
 
-    public StackedPathArguments(final YangInstanceIdentifier base, final List<StackedYangInstanceIdentifier> stack) {
-        this.base = Preconditions.checkNotNull(base);
+    public StackedPathArguments(final YangInstanceIdentifier base, final List<PathArgument> stack) {
+        this.base = base.getPathArguments();
         this.stack = Preconditions.checkNotNull(stack);
     }
 
     @Override
-    public Iterator<PathArgument> 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<PathArgument> iterator() {
         return new IteratorImpl(base, stack);
     }
 
     private static final class IteratorImpl extends UnmodifiableIterator<PathArgument> {
-        private final Iterator<StackedYangInstanceIdentifier> stack;
+        private final Iterator<PathArgument> stack;
         private final Iterator<PathArgument> base;
 
-        IteratorImpl(final YangInstanceIdentifier base, final Collection<StackedYangInstanceIdentifier> stack) {
-            this.base = base.getPathArguments().iterator();
+        IteratorImpl(final Iterable<PathArgument> base, final Iterable<PathArgument> stack) {
+            this.base = base.iterator();
             this.stack = stack.iterator();
         }
 
@@ -46,7 +57,7 @@ final class StackedPathArguments implements Iterable<PathArgument> {
             if (base.hasNext()) {
                 return base.next();
             }
-            return stack.next().getLastPathArgument();
+            return stack.next();
         }
     }
 }
index 54f6498bc247d4f165ca77c9241f749fa42ca327..5e71817b2fa51a29e9202ffcc7e00a8f4f81d609 100644 (file)
@@ -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<PathArgument> {
+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<PathArgument> 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<PathArgument> iterator() {
+    public UnmodifiableIterator<PathArgument> iterator() {
         return new IteratorImpl(identifier);
     }
 
@@ -44,10 +81,12 @@ final class StackedReversePathArguments implements Iterable<PathArgument> {
 
             final PathArgument ret = identifier.getLastPathArgument();
             final YangInstanceIdentifier next = identifier.getParent();
-            if (!(next instanceof StackedYangInstanceIdentifier)) {
-                tail = next.getReversePathArguments().iterator();
+            final Iterable<PathArgument> args = next.tryReversePathArguments();
+            if (args != null) {
+                tail = args.iterator();
                 identifier = null;
             } else {
+                Verify.verify(next instanceof StackedYangInstanceIdentifier);
                 identifier = (StackedYangInstanceIdentifier) next;
             }
 
index dc803ece58e5a94b43e13daf0a89929c88f591b4..d204bf09cbed3c9079c932b35a8decc739499953 100644 (file)
@@ -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<PathArgument> legacyPath;
-    private transient volatile Iterable<PathArgument> pathArguments;
-    private transient volatile Iterable<PathArgument> 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<PathArgument> getPathArguments() {
-        Iterable<PathArgument> ret = tryPathArguments();
+    public Collection<PathArgument> getPathArguments() {
+        StackedPathArguments ret = tryPathArguments();
         if (ret == null) {
-            List<StackedYangInstanceIdentifier> stack = new ArrayList<>();
+            List<PathArgument> 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<PathArgument> getReversePathArguments() {
-        Iterable<PathArgument> ret = reversePathArguments;
+    public Collection<PathArgument> getReversePathArguments() {
+        StackedReversePathArguments ret = tryReversePathArguments();
         if (ret == null) {
             ret = new StackedReversePathArguments(this);
             reversePathArguments = ret;
@@ -113,10 +114,15 @@ final class StackedYangInstanceIdentifier extends YangInstanceIdentifier {
     }
 
     @Override
-    Iterable<PathArgument> tryPathArguments() {
+    StackedPathArguments tryPathArguments() {
         return pathArguments;
     }
 
+    @Override
+    StackedReversePathArguments tryReversePathArguments() {
+        return reversePathArguments;
+    }
+
     @Override
     YangInstanceIdentifier createRelativeIdentifier(final int skipFromRoot) {
         // TODO: can we optimize this one?
index 55599305c09aadcf27003a9b541c0c3bf6b156e3..a582e5c32a3e1f0855bfbaad0a9685172ff42464 100644 (file)
@@ -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 <a href="http://tools.ietf.org/html/rfc6020#section-9.13">RFC6020</a>
  */
-public abstract class YangInstanceIdentifier implements Path<YangInstanceIdentifier>, Immutable, Serializable {
+public abstract class YangInstanceIdentifier extends IterablePathArguments implements Path<YangInstanceIdentifier>, 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<YangInstanceIdentif
     }
 
     @Nonnull abstract YangInstanceIdentifier createRelativeIdentifier(int skipFromRoot);
-    @Nonnull abstract Iterable<PathArgument> tryPathArguments();
+    @Nonnull abstract Collection<PathArgument> tryPathArguments();
+    @Nonnull abstract Collection<PathArgument> tryReversePathArguments();
 
     /**
      * Check if this instance identifier has empty path arguments, e.g. it is
@@ -115,7 +117,8 @@ public abstract class YangInstanceIdentifier implements Path<YangInstanceIdentif
      *
      * @return Immutable iteration of path arguments.
      */
-    public abstract Iterable<PathArgument> getPathArguments();
+    @Override
+    public abstract Collection<PathArgument> getPathArguments();
 
     /**
      * Returns an iterable of path arguments in reverse order. This is useful
@@ -123,7 +126,8 @@ public abstract class YangInstanceIdentifier implements Path<YangInstanceIdentif
      *
      * @return Immutable iterable of path arguments in reverse order.
      */
-    public abstract Iterable<PathArgument> getReversePathArguments();
+    @Override
+    public abstract Collection<PathArgument> getReversePathArguments();
 
     /**
      * Returns the last PathArgument. This is equivalent of iterating