Merge "Bug 735 - Part 1: Update ietf-restconf and ietf-yangtypes to newer versions"
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / InstanceIdentifier.java
index f3a6c3800fe6d5fdd2c765ca204ce73602a245ce..951e27f743dfb7d16883b6255da1f7116e6b7c59 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
@@ -42,7 +44,7 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
         this.path = ImmutableList.copyOf(path);
     }
 
-    private InstanceIdentifier(NodeIdentifier nodeIdentifier) {
+    private InstanceIdentifier(final NodeIdentifier nodeIdentifier) {
         this.path = ImmutableList.<PathArgument> of(nodeIdentifier);
     }
 
@@ -69,7 +71,7 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
     }
 
     @Override
-    public boolean equals(Object obj) {
+    public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
@@ -93,9 +95,34 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
         return true;
     }
 
+    public InstanceIdentifier node(final QName name) {
+        return node(new NodeIdentifier(name));
+    }
+
+    public InstanceIdentifier node(final PathArgument arg) {
+        return new InstanceIdentifier(ImmutableList.<PathArgument>builder().addAll(path).add(arg).build());
+    }
+
+    /**
+     * Get the relative path from an ancestor. This method attempts to perform the reverse
+     * of concatenating a base (ancestor) and a path.
+     *
+     * @param ancestor Ancestor against which the relative path should be calculated
+     * @return This object's relative path from parent, or Optional.absent() if the
+     *         specified parent is not in fact an ancestor of this object.
+     */
+    public Optional<InstanceIdentifier> relativeTo(final InstanceIdentifier ancestor) {
+        if (ancestor.contains(this)) {
+            final int common = ancestor.path.size();
+            return Optional.of(new InstanceIdentifier(path.subList(common, path.size())));
+        } else {
+            return Optional.absent();
+        }
+    }
+
     // Static factories & helpers
 
-    public static InstanceIdentifier of(QName name) {
+    public static InstanceIdentifier of(final QName name) {
         return new InstanceIdentifier(new NodeIdentifier(name));
     }
 
@@ -103,10 +130,14 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
         return new BuilderImpl();
     }
 
-    static public InstanceIdentifierBuilder builder(InstanceIdentifier origin) {
+    static public InstanceIdentifierBuilder builder(final InstanceIdentifier origin) {
         return new BuilderImpl(origin.getPath());
     }
 
+    public static InstanceIdentifierBuilder builder(final QName node) {
+        return builder().node(node);
+    }
+
     public interface PathArgument extends Immutable, Serializable {
 
         /**
@@ -137,20 +168,14 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
 
     /**
      * Simple path argument identifying a {@link ContainerNode} or {@link LeafNode} leaf
-     * overal data tree.
-     *
+     * overall data tree.
      */
-    public static final class NodeIdentifier implements PathArgument {
-
-        /**
-         *
-         */
+    public static final class NodeIdentifier implements PathArgument, Comparable<NodeIdentifier> {
         private static final long serialVersionUID = -2255888212390871347L;
-
         private final QName nodeType;
 
-        public NodeIdentifier(QName node) {
-            this.nodeType = node;
+        public NodeIdentifier(final QName node) {
+            this.nodeType = Preconditions.checkNotNull(node);
         }
 
         @Override
@@ -160,57 +185,48 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
 
         @Override
         public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((nodeType == null) ? 0 : nodeType.hashCode());
-            return result;
+            return 31 + nodeType.hashCode();
         }
 
         @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
+        public boolean equals(final Object obj) {
+            if (this == obj) {
                 return true;
-            if (obj == null)
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            NodeIdentifier other = (NodeIdentifier) obj;
-            if (nodeType == null) {
-                if (other.nodeType != null)
-                    return false;
-            } else if (!nodeType.equals(other.nodeType))
+            }
+            if (!(obj instanceof NodeIdentifier)) {
                 return false;
-            return true;
+            }
+            final NodeIdentifier other = (NodeIdentifier) obj;
+            return nodeType.equals(other.nodeType);
         }
 
         @Override
         public String toString() {
             return nodeType.toString();
         }
+
+        @Override
+        public int compareTo(final NodeIdentifier o) {
+            return nodeType.compareTo(o.nodeType);
+        }
     }
 
     /**
-     *
      * Composite path argument identifying a {@link MapEntryNode} leaf
-     * overal data tree.
-     *
+     * overall data tree.
      */
     public static final class NodeIdentifierWithPredicates implements PathArgument {
-
-        /**
-         *
-         */
         private static final long serialVersionUID = -4787195606494761540L;
 
         private final QName nodeType;
         private final Map<QName, Object> keyValues;
 
-        public NodeIdentifierWithPredicates(QName node, Map<QName, Object> keyValues) {
-            this.nodeType = node;
+        public NodeIdentifierWithPredicates(final QName node, final Map<QName, Object> keyValues) {
+            this.nodeType = Preconditions.checkNotNull(node);
             this.keyValues = ImmutableMap.copyOf(keyValues);
         }
 
-        public NodeIdentifierWithPredicates(QName node, QName key, Object value) {
+        public NodeIdentifierWithPredicates(final QName node, final QName key, final Object value) {
             this.nodeType = node;
             this.keyValues = ImmutableMap.of(key, value);
         }
@@ -234,24 +250,31 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
         }
 
         @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
+        public boolean equals(final Object obj) {
+            if (this == obj) {
                 return true;
-            if (obj == null)
+            }
+            if (obj == null) {
                 return false;
-            if (getClass() != obj.getClass())
+            }
+            if (getClass() != obj.getClass()) {
                 return false;
+            }
             NodeIdentifierWithPredicates other = (NodeIdentifierWithPredicates) obj;
             if (keyValues == null) {
-                if (other.keyValues != null)
+                if (other.keyValues != null) {
                     return false;
-            } else if (!keyValues.equals(other.keyValues))
+                }
+            } else if (!keyValues.equals(other.keyValues)) {
                 return false;
+            }
             if (nodeType == null) {
-                if (other.nodeType != null)
+                if (other.nodeType != null) {
                     return false;
-            } else if (!nodeType.equals(other.nodeType))
+                }
+            } else if (!nodeType.equals(other.nodeType)) {
                 return false;
+            }
             return true;
         }
 
@@ -263,24 +286,16 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
 
     /**
      * Simple path argument identifying a {@link LeafSetEntryNode} leaf
-     * overal data tree.
-     *
+     * overall data tree.
      */
     public static final class NodeWithValue implements PathArgument {
-
-       /**
-        *
-        * Composite path argument identifying a {@link AugmentationNode} leaf
-        * overal data tree.
-        *
-        */
         private static final long serialVersionUID = -3637456085341738431L;
 
         private final QName nodeType;
         private final Object value;
 
-        public NodeWithValue(QName node, Object value) {
-            this.nodeType = node;
+        public NodeWithValue(final QName node, final Object value) {
+            this.nodeType = Preconditions.checkNotNull(node);
             this.value = value;
         }
 
@@ -303,24 +318,31 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
         }
 
         @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
+        public boolean equals(final Object obj) {
+            if (this == obj) {
                 return true;
-            if (obj == null)
+            }
+            if (obj == null) {
                 return false;
-            if (getClass() != obj.getClass())
+            }
+            if (getClass() != obj.getClass()) {
                 return false;
+            }
             NodeWithValue other = (NodeWithValue) obj;
             if (value == null) {
-                if (other.value != null)
+                if (other.value != null) {
                     return false;
-            } else if (!value.equals(other.value))
+                }
+            } else if (!value.equals(other.value)) {
                 return false;
+            }
             if (nodeType == null) {
-                if (other.nodeType != null)
+                if (other.nodeType != null) {
                     return false;
-            } else if (!nodeType.equals(other.nodeType))
+                }
+            } else if (!nodeType.equals(other.nodeType)) {
                 return false;
+            }
             return true;
         }
 
@@ -331,29 +353,66 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
 
     }
 
-
+    /**
+     * Composite path argument identifying a {@link AugmentationNode} leaf
+     * overall data tree.
+     */
     public static final class AugmentationIdentifier implements PathArgument {
-
-
         private static final long serialVersionUID = -8122335594681936939L;
-        private final QName nodeType;
         private final ImmutableSet<QName> childNames;
 
         @Override
         public QName getNodeType() {
-            return nodeType;
+            // This should rather throw exception than return always null
+            throw new UnsupportedOperationException("Augmentation node has no QName");
         }
 
-        public AugmentationIdentifier(QName nodeType, Set<QName> childNames) {
-            super();
-            this.nodeType = nodeType;
+        public AugmentationIdentifier(final Set<QName> childNames) {
             this.childNames = ImmutableSet.copyOf(childNames);
         }
 
+        /**
+         * Augmentation node has no QName
+         */
+        @Deprecated
+        public AugmentationIdentifier(final QName nodeType, final Set<QName> childNames) {
+            this(childNames);
+        }
+
         public Set<QName> getPossibleChildNames() {
             return childNames;
         }
 
+        @Override
+        public String toString() {
+            final StringBuffer sb = new StringBuffer("AugmentationIdentifier{");
+            sb.append("childNames=").append(childNames);
+            sb.append('}');
+            return sb.toString();
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof AugmentationIdentifier)) {
+                return false;
+            }
+
+            AugmentationIdentifier that = (AugmentationIdentifier) o;
+
+            if (!childNames.equals(that.childNames)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return childNames.hashCode();
+        }
     }
 
     private static class BuilderImpl implements InstanceIdentifierBuilder {
@@ -364,25 +423,25 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
             path = ImmutableList.<PathArgument> builder();
         }
 
-        public BuilderImpl(List<? extends PathArgument> prefix) {
+        public BuilderImpl(final List<? extends PathArgument> prefix) {
             path = ImmutableList.<PathArgument> builder();
             path.addAll(prefix);
         }
 
         @Override
-        public InstanceIdentifierBuilder node(QName nodeType) {
+        public InstanceIdentifierBuilder node(final QName nodeType) {
             path.add(new NodeIdentifier(nodeType));
             return this;
         }
 
         @Override
-        public InstanceIdentifierBuilder nodeWithKey(QName nodeType, QName key, Object value) {
+        public InstanceIdentifierBuilder nodeWithKey(final QName nodeType, final QName key, final Object value) {
             path.add(new NodeIdentifierWithPredicates(nodeType, key, value));
             return this;
         }
 
         @Override
-        public InstanceIdentifierBuilder nodeWithKey(QName nodeType, Map<QName, Object> keyValues) {
+        public InstanceIdentifierBuilder nodeWithKey(final QName nodeType, final Map<QName, Object> keyValues) {
             path.add(new NodeIdentifierWithPredicates(nodeType, keyValues));
             return this;
         }
@@ -439,16 +498,19 @@ public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable,
         if (toStringCache != null) {
             return toStringCache;
         }
-        StringBuilder builder = new StringBuilder();
+
+        final StringBuilder builder = new StringBuilder('/');
+        boolean first = true;
         for (PathArgument argument : path) {
-            builder.append("/");
+            if (first) {
+                first = false;
+            } else {
+                builder.append('/');
+            }
             builder.append(argument.toString());
         }
+
         toStringCache = builder.toString();
         return toStringCache;
     }
-
-    public static InstanceIdentifierBuilder builder(QName node) {
-        return builder().node(node);
-    }
 }