Fixed bug with Key generation with fields added from grouping
[yangtools.git] / yang / yang-binding / src / main / java / org / opendaylight / yangtools / yang / binding / InstanceIdentifier.java
index dc9a8008bfbdc713f98c515fb03858dcbfbfada8..221bdc48f26e4f5d9b8a4d35e8035723ba7b8144 100644 (file)
@@ -11,18 +11,21 @@ import java.util.ArrayList;
 import java.util.Collections;\r
 import java.util.List;\r
 \r
+import org.opendaylight.yangtools.concepts.Builder;\r
+import org.opendaylight.yangtools.concepts.Immutable;\r
+import org.opendaylight.yangtools.concepts.Mutable;\r
+\r
 /**\r
  * Uniquely identifies instance of data tree.\r
  * \r
- * \r
  */\r
-public class InstanceIdentifier {\r
+public final class InstanceIdentifier implements Immutable {\r
 \r
     private final List<PathArgument> path;\r
     private final Class<? extends DataObject> targetType;\r
 \r
     public InstanceIdentifier(Class<? extends DataObject> type) {\r
-        path = Collections.emptyList();\r
+        path = Collections.<PathArgument> singletonList(new Item<>(type));\r
         this.targetType = type;\r
     }\r
 \r
@@ -33,7 +36,7 @@ public class InstanceIdentifier {
 \r
     /**\r
      * \r
-     * @return\r
+     * @return path\r
      */\r
     public List<PathArgument> getPath() {\r
         return this.path;\r
@@ -42,10 +45,7 @@ public class InstanceIdentifier {
     public Class<?> getTargetType() {\r
         return this.targetType;\r
     }\r
-    \r
-    \r
-    \r
-    \r
+\r
     @Override\r
     public String toString() {\r
         return "InstanceIdentifier [path=" + path + "]";\r
@@ -62,14 +62,58 @@ public class InstanceIdentifier {
      */\r
     public interface PathArgument {\r
 \r
+        Class<? extends DataObject> getType();\r
+\r
+    }\r
+\r
+    public static final class Item<T extends DataObject> implements PathArgument {\r
+        private final Class<T> type;\r
+\r
+        public Item(Class<T> type) {\r
+            this.type = type;\r
+        }\r
+\r
+        public Class<T> getType() {\r
+            return type;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((type == null) ? 0 : type.hashCode());\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (obj == null)\r
+                return false;\r
+            if (getClass() != obj.getClass())\r
+                return false;\r
+            Item<?> other = (Item<?>) obj;\r
+            if (type == null) {\r
+                if (other.type != null)\r
+                    return false;\r
+            } else if (!type.equals(other.type))\r
+                return false;\r
+            return true;\r
+        }\r
     }\r
 \r
-    public static class IdentifiableItem<I extends Identifiable<T>, T extends Identifier<I>> implements PathArgument {\r
+    public static final class IdentifiableItem<I extends Identifiable<T> & DataObject, T extends Identifier<I>> implements\r
+            PathArgument {\r
 \r
         private final T key;\r
-        private final Class<? extends I> type;\r
+        private final Class<I> type;\r
 \r
         public IdentifiableItem(Class<I> type, T key) {\r
+            if (type == null)\r
+                throw new IllegalArgumentException("Type must not be null.");\r
+            if (key == null)\r
+                throw new IllegalArgumentException("Key must not be null.");\r
             this.type = type;\r
             this.key = key;\r
         }\r
@@ -78,25 +122,26 @@ public class InstanceIdentifier {
             return this.key;\r
         }\r
 \r
-        Class<? extends I> getType() {\r
+        @Override\r
+        public Class<I> getType() {\r
             return this.type;\r
         }\r
-        \r
+\r
         @Override\r
         public boolean equals(Object obj) {\r
-            if(obj == null) {\r
+            if (obj == null) {\r
                 return false;\r
             }\r
-            if(obj.hashCode() != hashCode()) {\r
+            if (obj.hashCode() != hashCode()) {\r
                 return false;\r
             }\r
-            if(!(obj instanceof IdentifiableItem<?, ?>)) {\r
+            if (!(obj instanceof IdentifiableItem<?, ?>)) {\r
                 return false;\r
             }\r
             IdentifiableItem<?, ?> foreign = (IdentifiableItem<?, ?>) obj;\r
             return key.equals(foreign.getKey());\r
         }\r
-        \r
+\r
         @Override\r
         public int hashCode() {\r
             return key.hashCode();\r
@@ -104,7 +149,77 @@ public class InstanceIdentifier {
 \r
         @Override\r
         public String toString() {\r
-            return "IdentifiableItem [key=" + key + "]";\r
+            return type.getName() + "[key=" + key + "]";\r
+        }\r
+    }\r
+\r
+    public interface InstanceIdentifierBuilder extends Builder<InstanceIdentifier> {\r
+\r
+        <T extends DataObject> InstanceIdentifierBuilder node(Class<T> container);\r
+\r
+        <I extends Identifiable<T> & DataObject, T extends Identifier<I>> InstanceIdentifierBuilder node(\r
+                Class<I> listItem, T listKey);\r
+\r
+    }\r
+\r
+    public static InstanceIdentifierBuilder builder() {\r
+        return new BuilderImpl();\r
+    }\r
+\r
+    private static class BuilderImpl implements InstanceIdentifierBuilder {\r
+\r
+        private List<PathArgument> path;\r
+        private Class<? extends DataObject> target = null;\r
+\r
+        @Override\r
+        public InstanceIdentifier toInstance() {\r
+            List<PathArgument> immutablePath = Collections.unmodifiableList(new ArrayList<PathArgument>(path));\r
+            return new InstanceIdentifier(immutablePath, target);\r
+        }\r
+\r
+        @Override\r
+        public <T extends DataObject> InstanceIdentifierBuilder node(Class<T> container) {\r
+            target = container;\r
+            path.add(new Item<T>(container));\r
+            return this;\r
+        }\r
+\r
+        @Override\r
+        public <I extends Identifiable<T> & DataObject, T extends Identifier<I>> InstanceIdentifierBuilder node(\r
+                Class<I> listItem, T listKey) {\r
+            target = listItem;\r
+            path.add(new IdentifiableItem<I, T>(listItem, listKey));\r
+            return this;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((path == null) ? 0 : path.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        if (getClass() != obj.getClass()) {\r
+            return false;\r
+        }\r
+        InstanceIdentifier other = (InstanceIdentifier) obj;\r
+        if (path == null) {\r
+            if (other.path != null) {\r
+                return false;\r
+            }\r
+        } else if (!path.equals(other.path)) {\r
+            return false;\r
         }\r
+        return true;\r
     }\r
 }\r