Merge "Bug 3016 : This manual serialization of ImmutableList was done because in...
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / YangInstanceIdentifier.java
index 62c876b530495e8cdf151e4585f45a7216a4a577..4488ac32c27d937fc6bc92f19d687ab782289b4e 100644 (file)
@@ -22,6 +22,7 @@ import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -71,19 +72,23 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
  * @see <a href="http://tools.ietf.org/html/rfc6020#section-9.13">RFC6020</a>
  */
 public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier>, Immutable, Serializable {
+    /**
+     * An empty {@link YangInstanceIdentifier}. It corresponds to the path of the conceptual
+     * root of the YANG namespace.
+     */
+    public static final YangInstanceIdentifier EMPTY = trustedCreate(Collections.<PathArgument>emptyList());
     @SuppressWarnings("rawtypes")
     private static final AtomicReferenceFieldUpdater<YangInstanceIdentifier, ImmutableList> LEGACYPATH_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, ImmutableList.class, "legacyPath");
     private static final AtomicReferenceFieldUpdater<YangInstanceIdentifier, String> TOSTRINGCACHE_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, String.class, "toStringCache");
-    private static final YangInstanceIdentifier EMPTY = trustedCreate(Collections.<PathArgument>emptyList());
     private static final Field PATHARGUMENTS_FIELD;
 
     private static final long serialVersionUID = 3L;
-    private transient final Iterable<PathArgument> pathArguments;
+    private final transient Iterable<PathArgument> pathArguments;
     private final int hash;
 
-    private volatile ImmutableList<PathArgument> legacyPath = null;
+    private transient volatile ImmutableList<PathArgument> legacyPath = null;
     private transient volatile String toStringCache = null;
 
     static {
@@ -98,7 +103,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         PATHARGUMENTS_FIELD = f;
     }
 
-    private final ImmutableList<PathArgument> getLegacyPath() {
+    private ImmutableList<PathArgument> getLegacyPath() {
         // Temporary variable saves a volatile read
         ImmutableList<PathArgument> ret = legacyPath;
         if (ret == null) {
@@ -156,7 +161,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         this.hash = hash;
     }
 
-    private static final YangInstanceIdentifier trustedCreate(final Iterable<PathArgument> path) {
+    private static YangInstanceIdentifier trustedCreate(final Iterable<PathArgument> path) {
         final HashCodeBuilder<PathArgument> hash = new HashCodeBuilder<>();
         for (PathArgument a : path) {
             hash.addArgument(a);
@@ -165,7 +170,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         return new YangInstanceIdentifier(path, hash.build());
     }
 
-    public static final YangInstanceIdentifier create(final Iterable<? extends PathArgument> path) {
+    public static YangInstanceIdentifier create(final Iterable<? extends PathArgument> path) {
         if (Iterables.isEmpty(path)) {
             return EMPTY;
         }
@@ -173,7 +178,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         return trustedCreate(ImmutableList.copyOf(path));
     }
 
-    public static final YangInstanceIdentifier create(final PathArgument... path) {
+    public static YangInstanceIdentifier create(final PathArgument... path) {
         // We are forcing a copy, since we cannot trust the user
         return create(Arrays.asList(path));
     }
@@ -302,7 +307,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
      *
      * @return new builder for InstanceIdentifier with empty path arguments.
      */
-    static public InstanceIdentifierBuilder builder() {
+    public static InstanceIdentifierBuilder builder() {
         return new BuilderImpl();
     }
 
@@ -313,7 +318,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
      * @param origin Instace Identifier from which path arguments are copied.
      * @return new builder for InstanceIdentifier with path arguments copied from original instance identifier.
      */
-    static public InstanceIdentifierBuilder builder(final YangInstanceIdentifier origin) {
+    public static InstanceIdentifierBuilder builder(final YangInstanceIdentifier origin) {
         return new BuilderImpl(origin.getPathArguments(), origin.hashCode());
     }
 
@@ -646,7 +651,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
 
         @Override
         public String toString() {
-            final StringBuffer sb = new StringBuffer("AugmentationIdentifier{");
+            final StringBuilder sb = new StringBuilder("AugmentationIdentifier{");
             sb.append("childNames=").append(childNames).append('}');
             return sb.toString();
         }
@@ -801,6 +806,7 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
 
     private void readObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
         inputStream.defaultReadObject();
+        legacyPath = ImmutableList.copyOf((Collection<PathArgument>)inputStream.readObject());
 
         try {
             PATHARGUMENTS_FIELD.set(this, legacyPath);
@@ -821,7 +827,8 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
          * it out. The read path does the opposite -- it reads the legacyPath and then
          * uses invocation API to set the field.
          */
-        getLegacyPath();
+        ImmutableList<PathArgument> pathArguments = getLegacyPath();
         outputStream.defaultWriteObject();
+        outputStream.writeObject(pathArguments);
     }
 }