Updated Concepts descriptions 97/1597/1
authorTony Tkacik <ttkacik@cisco.com>
Wed, 2 Oct 2013 10:06:57 +0000 (12:06 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Wed, 2 Oct 2013 10:06:57 +0000 (12:06 +0200)
Added fluent builder to the instance identifier.

Change-Id: Icd28833f53a8365ec1d6e00b075db003dd421098
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
concepts/src/main/java/org/opendaylight/yangtools/concepts/Builder.java
concepts/src/main/java/org/opendaylight/yangtools/concepts/Immutable.java
yang/yang-binding/pom.xml
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java

index 7cf29157a3bdb48abd9c3151218bc4f2dcad6137..cfec0f236b5fcf6b6edad6d1754dd9a6f89ff84f 100644 (file)
@@ -14,6 +14,6 @@ package org.opendaylight.yangtools.concepts;
  *
  * @param <P> Product of Build process
  */
-public interface Builder<P> {
+public interface Builder<P> extends Mutable {
     P toInstance();
 }
index c2630317c4ab18e1e6e2e667027e891579ed1e7d..323683885d91fe5b15affb127c9705fcfe060fd3 100644 (file)
@@ -10,12 +10,30 @@ package org.opendaylight.yangtools.concepts;
 /**\r
  * Immutable Object - object does not change its state during lifecycle.\r
  * \r
+ * <p>\r
+ * Marker interface for objects which are immutable. This interface should be\r
+ * used directly on objects, preferably final, which are eligible for the\r
+ * JSR-305 @Immutable annotation and objects implementing this interface are\r
+ * required to abide to interface contract specified by @Immutable. \r
+ * \r
+ * <p>The reason for the existence of this interface is twofold: \r
+ * unlike @Immutable, it is\r
+ * visible at runtime and objects can be quickly checked for compliance using a\r
+ * quick 'instanceof' check. This is useful for code which needs to capture a\r
+ * point-in-time snapshot of otherwise unknown objects -- a typical example\r
+ * being logging/tracing systems. Such systems would normally have to rely on\r
+ * serializing the object to get a stable checkpoint. Objects marked with this\r
+ * interface are guaranteed to remain stable, thus already being a checkpoint\r
+ * for all intents and purposes, so aside from retaining a reference no further\r
+ * action on them is necessary.\r
+ * \r
  * Implementations of this interface must not change any public state during\r
  * their whole lifecycle.\r
  * \r
  * This interface is mutually exclusive with {@link Mutable} and other\r
  * {@link MutationBehaviour}s.\r
  * \r
+ * @author Robert Varga <rovarga@cisco.com>\r
  * @author Tony Tkacik <ttkacik@cisco.com>\r
  * \r
  */\r
index 1d6374c807e37f5217e6ab3255d656ac6a103892..2d51f451da3b69c3c23757fc3106ffee1ead660a 100644 (file)
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
 \r
     <parent>\r
         <groupId>org.opendaylight.yangtools</groupId>\r
     <artifactId>yang-binding</artifactId>\r
     <name>${project.artifactId}</name>\r
     <description>Java binding for YANG</description>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.opendaylight.yangtools</groupId>\r
+            <artifactId>concepts</artifactId>\r
+            <version>0.1.1-SNAPSHOT</version>\r
+        </dependency>\r
+    </dependencies>\r
 </project>\r
index cf4974dafbe0534f074aaf9b3f867bf21f318ceb..26c254a2a4b7f330f0388f59a536cef0dfcfd8e9 100644 (file)
@@ -11,12 +11,15 @@ 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 class InstanceIdentifier implements Immutable {\r
 \r
     private final List<PathArgument> path;\r
     private final Class<? extends DataObject> targetType;\r
@@ -59,12 +62,52 @@ public class InstanceIdentifier {
      */\r
     public interface PathArgument {\r
 \r
+        Class<? extends DataObject> getType();\r
+\r
+    }\r
+\r
+    public static 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 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
             this.type = type;\r
@@ -75,7 +118,8 @@ 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
@@ -101,7 +145,48 @@ 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
 }\r