BUG-994: introduce SchemaPath.create() and friends 19/7319/5
authorRobert Varga <rovarga@cisco.com>
Wed, 21 May 2014 18:38:44 +0000 (20:38 +0200)
committerRobert Varga <rovarga@cisco.com>
Fri, 23 May 2014 09:10:18 +0000 (11:10 +0200)
This introduces a proper static constructor method, which does not
necesssarily have to allocate a new object. It also does not require an
explicit list as initializer, giving more flexibility to both users and
implementation itself.

Also introduces a couple of utility methods which make manipulating
SchemaPath easier.

This patch obsoletes the public contructor and getPath() method.

Change-Id: I4ec49d4336f4c30a9732c0bd95650e19c5d5e3f2
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java

index 51eb64159301e5a4998df1438de97909f6ad9fea..1669e0816f82b79b102df64348bbefc31a791b92 100644 (file)
@@ -7,11 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.model.api;
 
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import org.opendaylight.yangtools.yang.common.QName;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 
 /**
  *
@@ -19,10 +23,20 @@ import com.google.common.collect.ImmutableList;
  *
  */
 public class SchemaPath {
+    /**
+     * Shared instance of the conceptual root schema node.
+     */
+    public static final SchemaPath ROOT = SchemaPath.create(Collections.<QName>emptyList(), true);
+
+    /**
+     * Shared instance of the "same" relative schema node.
+     */
+    public static final SchemaPath SAME = SchemaPath.create(Collections.<QName>emptyList(), false);
+
     /**
      * List of QName instances which represents complete path to the node.
      */
-    private final List<QName> path;
+    private final ImmutableList<QName> path;
 
     /**
      * Boolean value which represents type of schema path (relative or
@@ -39,10 +53,12 @@ public class SchemaPath {
      * @param absolute
      *            boolean value which specifies if the path is absolute or
      *            relative
+     *
+     * @deprecated Use {@link #create(Iterable, boolean)} instead.
      */
+    @Deprecated
     public SchemaPath(final List<QName> path, final boolean absolute) {
-        this.path = ImmutableList.copyOf(path);
-        this.absolute = absolute;
+        this(ImmutableList.copyOf(path), absolute, null);
     }
 
     /**
@@ -50,11 +66,113 @@ public class SchemaPath {
      *
      * @return list of <code>QName</code> instances which represents complete
      *         path to schema node
+     *
+     * @deprecated Use {@link #getPathFromRoot()} instead.
      */
+    @Deprecated
     public List<QName> getPath() {
         return path;
     }
 
+    private SchemaPath(final ImmutableList<QName> path, final boolean absolute, final Void dummy) {
+        this.path = Preconditions.checkNotNull(path);
+        this.absolute = absolute;
+    }
+
+    /**
+     * Constructs new instance of this class with the concrete path.
+     *
+     * @param path
+     *            list of QName instances which specifies exact path to the
+     *            module node
+     * @param absolute
+     *            boolean value which specifies if the path is absolute or
+     *            relative
+     *
+     * @return A SchemaPath instance.
+     */
+    public static SchemaPath create(final Iterable<QName> path, final boolean absolute) {
+        if (Iterables.isEmpty(path)) {
+            return absolute ? ROOT : SAME;
+        } else {
+            return new SchemaPath(ImmutableList.copyOf(path), absolute, null);
+        }
+    }
+
+    /**
+     * Constructs new instance of this class with the concrete path.
+     *
+     * @param absolute
+     *            boolean value which specifies if the path is absolute or
+     *            relative
+     * @param path
+     *            one or more QName instances which specifies exact path to the
+     *            module node
+     *
+     * @return A SchemaPath instance.
+     */
+    public static SchemaPath create(final boolean absolute, final QName... path) {
+       return create(Arrays.asList(path), absolute);
+    }
+
+    /**
+     * Create a child path based on concatenation of this path and a relative path.
+     *
+     * @param relative Relative path
+     * @return A new child path
+     */
+    public SchemaPath createChild(final Iterable<QName> relative) {
+        if (Iterables.isEmpty(relative)) {
+            return this;
+        }
+        return create(Iterables.concat(path, relative), absolute);
+    }
+
+    /**
+     * Create a child path based on concatenation of this path and a relative path.
+     *
+     * @param relative Relative SchemaPath
+     * @return A new child path
+     */
+    public SchemaPath createChild(final SchemaPath relative) {
+        Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path");
+        return createChild(relative.path);
+    }
+
+    /**
+     * Create a child path based on concatenation of this path and additional
+     * path elements.
+     *
+     * @param elements Relative SchemaPath elements
+     * @return A new child path
+     */
+    public SchemaPath createChild(final QName... elements) {
+        return createChild(Arrays.asList(elements));
+    }
+
+    /**
+     * Returns the list of nodes which need to be traversed to get from the
+     * starting point (root for absolute SchemaPaths) to the node represented
+     * by this object.
+     *
+     * @return list of <code>qname</code> instances which represents
+     *         path from the root to the schema node.
+     */
+    public Iterable<QName> getPathFromRoot() {
+        return path;
+    }
+
+    /**
+     * Returns the list of nodes which need to be traversed to get from this
+     * node to the starting point (root for absolute SchemaPaths).
+     *
+     * @return list of <code>qname</code> instances which represents
+     *         path from the schema node towards the root.
+     */
+    public Iterable<QName> getPathTowardsRoot() {
+        return path.reverse();
+    }
+
     /**
      * Describes whether schema path is|isn't absolute.
      *
@@ -70,7 +188,9 @@ public class SchemaPath {
         final int prime = 31;
         int result = 1;
         result = prime * result + absolute.hashCode();
-        result = prime * result + ((path == null) ? 0 : path.hashCode());
+        for (Object o : path) {
+            result = prime * result + o.hashCode();
+        }
         return result;
     }
 
@@ -89,14 +209,8 @@ public class SchemaPath {
         if (absolute != other.absolute) {
             return false;
         }
-        if (path == null) {
-            if (other.path != null) {
-                return false;
-            }
-        } else if (!path.equals(other.path)) {
-            return false;
-        }
-        return true;
+
+        return Iterables.elementsEqual(path, other.path);
     }
 
     @Override