Merge "Bug 1512 - generated builder java file for a leaf containing a union"
authorTony Tkacik <ttkacik@cisco.com>
Mon, 15 Sep 2014 10:45:46 +0000 (10:45 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 15 Sep 2014 10:45:46 +0000 (10:45 +0000)
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/gen/impl/DataNodeContainerSerializerSource.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/BindingCodecContext.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/ValueTypeCodec.java
code-generator/binding-data-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/EmptyLeafTest.java [new file with mode: 0644]
code-generator/binding-test-model/src/main/yang/opendaylight-yangtools-augment-test.yang
common/parent/pom.xml
model/ietf/pom.xml
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java
yang/yang-data-api/src/test/java/org/opendaylight/yangtools/yang/data/api/InstanceIdentifierTest.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableNormalizedValueNode.java

index 07d6602c2dd7d0025f0586c2a278718236bdd755..9b8faba4cb67a2a3bf36215dbc9796937ed9b48d 100644 (file)
@@ -7,10 +7,8 @@
  */package org.opendaylight.yangtools.binding.data.codec.gen.impl;
 
 import com.google.common.base.Preconditions;
-
 import java.util.HashMap;
 import java.util.Map;
-
 import org.opendaylight.yangtools.binding.data.codec.util.ChoiceDispatchSerializer;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature;
@@ -31,6 +29,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
 
 abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSource {
 
@@ -106,7 +105,7 @@ abstract class DataNodeContainerSerializerSource extends DataObjectSerializerSou
             while (rootType.getBaseType() != null) {
                 rootType = rootType.getBaseType();
             }
-            if(rootType instanceof BooleanTypeDefinition) {
+            if(rootType instanceof BooleanTypeDefinition || rootType instanceof EmptyTypeDefinition) {
                 prefix = "is";
             }
         }
index dfef41afc0aedd37bac71784384be0b3e816db95..881a62bc2e0c0abe4da9baf94c9a5536a9bf0076 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.binding.data.codec.impl;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -25,10 +24,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.Callable;
-
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-
 import org.opendaylight.yangtools.binding.data.codec.impl.NodeCodecContext.CodecContextFactory;
 import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.concepts.Immutable;
@@ -53,6 +50,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
@@ -207,7 +205,7 @@ class BindingCodecContext implements CodecContextFactory, Immutable {
         while (typeDef.getBaseType() != null) {
             typeDef = typeDef.getBaseType();
         }
-        if (typeDef instanceof BooleanTypeDefinition) {
+        if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
             return "is" + suffix;
         }
         return GETTER_PREFIX + suffix;
@@ -246,6 +244,14 @@ class BindingCodecContext implements CodecContextFactory, Immutable {
 
 
     private Codec<Object, Object> getCodec(final Class<?> valueType, final DataSchemaNode schema) {
+        final TypeDefinition<?> instantiatedType;
+        if (schema instanceof LeafSchemaNode) {
+            instantiatedType = ((LeafSchemaNode) schema).getType();
+        } else if (schema instanceof LeafListSchemaNode) {
+            instantiatedType = ((LeafListSchemaNode) schema).getType();
+        } else {
+            throw new IllegalArgumentException("Unsupported leaf node type " + schema.getClass());
+        }
         if (Class.class.equals(valueType)) {
             @SuppressWarnings({ "unchecked", "rawtypes" })
             final Codec<Object, Object> casted = (Codec) identityCodec;
@@ -254,18 +260,12 @@ class BindingCodecContext implements CodecContextFactory, Immutable {
             @SuppressWarnings({ "unchecked", "rawtypes" })
             final Codec<Object, Object> casted = (Codec) instanceIdentifierCodec;
             return casted;
-        } else if (BindingReflections.isBindingClass(valueType)) {
-            final TypeDefinition<?> instantiatedType;
-            if (schema instanceof LeafSchemaNode) {
-                instantiatedType = ((LeafSchemaNode) schema).getType();
-            } else if (schema instanceof LeafListSchemaNode) {
-                instantiatedType = ((LeafListSchemaNode) schema).getType();
-            } else {
-                instantiatedType = null;
-            }
-            if (instantiatedType != null) {
-                return getCodec(valueType, instantiatedType);
+        } else if (Boolean.class.equals(valueType)) {
+            if(instantiatedType instanceof EmptyTypeDefinition) {
+                return ValueTypeCodec.EMPTY_CODEC;
             }
+        } else if (BindingReflections.isBindingClass(valueType)) {
+                            return getCodec(valueType, instantiatedType);
         }
         return ValueTypeCodec.NOOP_CODEC;
     }
index e432c55b005d4d81f6b80740ddb1bf2743574140..d8536ee667e9aae07184f25f0e74bf943e72dd31 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.yangtools.concepts.Codec;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
 
 /**
@@ -59,11 +60,46 @@ abstract class ValueTypeCodec implements Codec<Object, Object> {
         }
     };
 
+    public static final SchemaUnawareCodec EMPTY_CODEC = new SchemaUnawareCodec() {
+
+        @Override
+        public Object serialize(Object arg0) {
+            // Empty type has null value in NormalizedNode and Composite Node
+            // representation
+            return null;
+        }
+
+        @Override
+        public Object deserialize(Object arg0) {
+            /* Empty type has boolean.TRUE representation in Binding-aware world
+            *  otherwise it is null / false.
+            *  So when codec is triggered, empty leaf is present, that means we
+            *  are safe to return true.
+            */
+            return Boolean.TRUE;
+        }
+    };
+
+    private static final Callable<? extends SchemaUnawareCodec> EMPTY_LOADER = new Callable<SchemaUnawareCodec>() {
+
+        @Override
+        public SchemaUnawareCodec call() throws Exception {
+            return EMPTY_CODEC;
+        }
+    };
+
 
     public static SchemaUnawareCodec getCodecFor(final Class<?> typeClz, final TypeDefinition<?> def) {
         if (BindingReflections.isBindingClass(typeClz)) {
             return getCachedSchemaUnawareCodec(typeClz, getCodecLoader(typeClz, def));
         }
+        TypeDefinition<?> rootType = def;
+        while (rootType.getBaseType() != null) {
+            rootType = rootType.getBaseType();
+        }
+        if(rootType instanceof EmptyTypeDefinition) {
+            return EMPTY_CODEC;
+        }
         return NOOP_CODEC;
     }
 
@@ -85,6 +121,8 @@ abstract class ValueTypeCodec implements Codec<Object, Object> {
             return EnumerationCodec.loader(typeClz, (EnumTypeDefinition) rootType);
         } else if (rootType instanceof BitsTypeDefinition) {
             return BitsCodec.loader(typeClz, (BitsTypeDefinition) rootType);
+        } else if (rootType instanceof EmptyTypeDefinition) {
+            return EMPTY_LOADER;
         }
         return EncapsulatedValueCodec.loader(typeClz);
     }
diff --git a/code-generator/binding-data-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/EmptyLeafTest.java b/code-generator/binding-data-codec/src/test/java/org/opendaylight/yangtools/binding/data/codec/test/EmptyLeafTest.java
new file mode 100644 (file)
index 0000000..53258f8
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.binding.data.codec.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Map.Entry;
+import javassist.ClassPool;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.RpcComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.RpcComplexUsesAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.TreeComplexUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.TreeLeafOnlyAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.complex.from.grouping.ContainerWithUsesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.complex.from.grouping.ListViaUses;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.top.top.level.list.choice.in.list.EmptyLeaf;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.top.top.level.list.choice.in.list.EmptyLeafBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.two.level.list.TopLevelListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.two.level.list.top.level.list.ChoiceInList;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+
+public class EmptyLeafTest extends AbstractBindingRuntimeTest {
+
+    private static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo");
+    private static final InstanceIdentifier<TopLevelList> BA_TOP_LEVEL_LIST = InstanceIdentifier.builder(Top.class)
+            .child(TopLevelList.class, TOP_FOO_KEY).toInstance();
+    private static final InstanceIdentifier<TreeLeafOnlyAugment> BA_TREE_LEAF_ONLY = BA_TOP_LEVEL_LIST
+            .augmentation(TreeLeafOnlyAugment.class);
+    private static final InstanceIdentifier<TreeComplexUsesAugment> BA_TREE_COMPLEX_USES = BA_TOP_LEVEL_LIST
+            .augmentation(TreeComplexUsesAugment.class);
+    private static final QName SIMPLE_VALUE_QNAME = QName.create(TreeComplexUsesAugment.QNAME, "simple-value");
+
+    private BindingNormalizedNodeCodecRegistry registry;
+
+    @Override
+    public void setup() {
+        super.setup();
+        JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault());
+        registry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(utils));
+        registry.onBindingRuntimeContextUpdated(getRuntimeContext());
+    }
+
+    @Test
+    public void testCaseWithEmptyLeafType() {
+        TopLevelList withEmptyCase = new TopLevelListBuilder()
+            .setKey(TOP_FOO_KEY)
+            .setChoiceInList(new EmptyLeafBuilder().setEmptyType(true).build())
+            .build();
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> dom = registry.toNormalizedNode(BA_TOP_LEVEL_LIST, withEmptyCase);
+        Entry<InstanceIdentifier<?>, DataObject> readed = registry.fromNormalizedNode(dom.getKey(),dom.getValue());
+        ChoiceInList list = ((TopLevelList) readed.getValue()).getChoiceInList();
+        assertTrue(list instanceof EmptyLeaf);
+        assertTrue(((EmptyLeaf) list).isEmptyType());
+    }
+
+    private RpcComplexUsesAugment createComplexData() {
+        return new RpcComplexUsesAugmentBuilder()
+        .setContainerWithUses(new ContainerWithUsesBuilder()
+            .setLeafFromGrouping("foo")
+        .build())
+        .setListViaUses(Collections.<ListViaUses>emptyList())
+        .build();
+    }
+
+}
index 6d155becc7628237edfc133df77c594f5fcf58ef..7363f38c46ff87e5223cc2f91011d686949c667f 100644 (file)
@@ -97,6 +97,11 @@ module opendaylight-yangtools-augment-test {
         case complex-via-uses {
             uses complex-from-grouping;
         }
+        case empty-leaf {
+            leaf empty-type {
+                type empty;
+            }
+        }
     }
 
     augment "/test:put-top/test:input/test:top-level-list/test:choice-in-list" {
index 914d1973bfd16a04b0517e71ee51ababdb0753f5..263fd7924315d22a42068133cdd8aea263f0dd68 100644 (file)
@@ -32,6 +32,7 @@
         <ctrie.version>0.2.0</ctrie.version>
         <exam.version>3.0.0</exam.version>
         <groovy.version>2.1.6</groovy.version>
+        <yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
         <ietf.topology.version>2013.10.21.2-SNAPSHOT</ietf.topology.version>
         <ietf.inet.types.version>2010.09.24.4-SNAPSHOT</ietf.inet.types.version>
         <ietf.yang.types.version>2010.09.24.4-SNAPSHOT</ietf.yang.types.version>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-data-util</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>maven-sal-api-gen-plugin</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.thirdparty</groupId>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>concepts</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>object-cache-api</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>object-cache-guava</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>object-cache-noop</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>binding-model-api</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>binding-generator-api</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>binding-generator-spi</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>binding-generator-util</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>binding-generator-impl</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>binding-java-api-generator</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-common</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-data-api</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-data-impl</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-data-codec-gson</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-model-api</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-model-util</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-binding</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-parser-api</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-parser-impl</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin-spi</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-inet-types</artifactId>
-                <version>2010.09.24.4-SNAPSHOT</version>
+                <version>${ietf.inet.types.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-yang-types</artifactId>
-                <version>2010.09.24.4-SNAPSHOT</version>
+                <version>${ietf.yang.types.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-yang-types-20130715</artifactId>
-                <version>2013.07.15.1-SNAPSHOT</version>
+                <version>${ietf.yang.types.20130715.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-ted</artifactId>
-                <version>2013.10.21.2-SNAPSHOT</version>
+                <version>${ietf.topology.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-topology</artifactId>
-                <version>2013.10.21.2-SNAPSHOT</version>
+                <version>${ietf.topology.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-topology-isis</artifactId>
-                <version>2013.10.21.2-SNAPSHOT</version>
+                <version>${ietf.topology.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-topology-l3-unicast-igp</artifactId>
-                <version>2013.10.21.2-SNAPSHOT</version>
+                <version>${ietf.topology.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-topology-ospf</artifactId>
-                <version>2013.10.21.2-SNAPSHOT</version>
+                <version>${ietf.topology.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-topology-l3-unicast</artifactId>
-                <version>2013.10.21.2-SNAPSHOT</version>
+                <version>${ietf.topology.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-data-composite-node</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.maven</groupId>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>restconf-client-api</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>restconf-common</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>restconf-util</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>restconf-test-service</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>restconf-client-impl</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>restconf-jaxrs-api</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>bug527-test-model</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
                 <scope>test</scope>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>bug1196-test-model</artifactId>
-                <version>0.6.2-SNAPSHOT</version>
+                <version>${yangtools.version}</version>
                 <scope>test</scope>
             </dependency>
 
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>websocket-client</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>object-cache-api</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>object-cache-guava</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>object-cache-noop</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>util</artifactId>
-                <version>${project.version}</version>
+                <version>${yangtools.version}</version>
             </dependency>
             <dependency>
               <groupId>org.opendaylight.yangtools.model</groupId>
             <dependency>
               <groupId>org.opendaylight.yangtools</groupId>
               <artifactId>binding-type-provider</artifactId>
-              <version>${project.version}</version>
+              <version>${yangtools.version}</version>
             </dependency>
             <dependency>
               <groupId>org.opendaylight.yangtools</groupId>
               <artifactId>yang-data-operations</artifactId>
-              <version>${project.version}</version>
+              <version>${yangtools.version}</version>
             </dependency>
             <dependency>
               <groupId>org.opendaylight.yangtools</groupId>
               <artifactId>binding-data-codec</artifactId>
-              <version>${project.version}</version>
+              <version>${yangtools.version}</version>
             </dependency>
             <dependency>
               <groupId>org.opendaylight.yangtools</groupId>
               <artifactId>features-test</artifactId>
-              <version>${project.version}</version>
+              <version>${yangtools.version}</version>
               <scope>test</scope>
             </dependency>
         </dependencies>
index 1f0606307d83ce3a95a6a61baa18fbc1a539d017..886a16dfefa5e2c3d5b6943284f44854bdaa5730 100644 (file)
     <name>${project.artifactId}</name>
     <description>${project.artifactId}</description>
 
-    <properties>
-        <ietf.topology.version>2013.10.21.2-SNAPSHOT</ietf.topology.version>
-        <ietf.inet.types.version>2010.09.24.4-SNAPSHOT</ietf.inet.types.version>
-        <ietf.yang.types.version>2010.09.24.4-SNAPSHOT</ietf.yang.types.version>
-        <ietf.restconf.version>2013.10.19.1-SNAPSHOT</ietf.restconf.version>
-    </properties>
-
     <modules>
         <module>ietf-inet-types</module>
         <module>ietf-yang-types</module>
index 9a597152c3ce4f3aa1a4e04e8ff94c230378e0c4..9840338bb9442bd82db429ef1a2379db6a45d2ee 100644 (file)
@@ -13,13 +13,13 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
-
 import java.io.IOException;
 import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.concepts.Path;
@@ -55,17 +55,29 @@ import org.opendaylight.yangtools.util.HashCodeBuilder;
  *
  */
 public class InstanceIdentifier<T extends DataObject> implements Path<InstanceIdentifier<? extends DataObject>>, Immutable, Serializable {
-    private static final long serialVersionUID = 1L;
+    private static final Field PATHARGUMENTS_FIELD;
+    private static final long serialVersionUID = 2L;
     /*
      * Protected to differentiate internal and external access. Internal
      * access is required never to modify the contents. References passed
      * to outside entities have to be wrapped in an unmodifiable view.
      */
-    protected final Iterable<PathArgument> pathArguments;
+    protected transient final Iterable<PathArgument> pathArguments;
     private final Class<T> targetType;
     private final boolean wildcarded;
     private final int hash;
 
+    static {
+        final Field f;
+        try {
+            f = InstanceIdentifier.class.getDeclaredField("pathArguments");
+        } catch (NoSuchFieldException | SecurityException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+        f.setAccessible(true);
+        PATHARGUMENTS_FIELD = f;
+    }
+
     InstanceIdentifier(final Class<T> type, final Iterable<PathArgument> pathArguments, final boolean wildcarded, final int hash) {
         this.pathArguments = Preconditions.checkNotNull(pathArguments);
         this.targetType = Preconditions.checkNotNull(type);
@@ -653,16 +665,26 @@ public class InstanceIdentifier<T extends DataObject> implements Path<InstanceId
     }
 
     private void writeObject(final java.io.ObjectOutputStream out) throws IOException {
-        out.writeObject(targetType);
-        out.writeBoolean(wildcarded);
-        out.writeInt(hash);
-        out.write(Iterables.size(pathArguments));
+        out.defaultWriteObject();
+        out.writeInt(Iterables.size(pathArguments));
         for (Object o : pathArguments) {
             out.writeObject(o);
         }
     }
 
     private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
-        // TODO Auto-generated method stub
+        in.defaultReadObject();
+
+        final int size = in.readInt();
+        final List<PathArgument> args = new ArrayList<>(size);
+        for (int i = 0; i < size; ++i) {
+            args.add((PathArgument) in.readObject());
+        }
+
+        try {
+            PATHARGUMENTS_FIELD.set(this, ImmutableList.copyOf(args));
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new IOException(e);
+        }
     }
 }
index 2916b88e8bfde2898622e3076b151f5e0b8421c5..dfd623fa84021d0452266c6941034eeabe629b70 100644 (file)
@@ -13,8 +13,12 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.lang.reflect.Array;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -72,14 +76,27 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
     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 = 2L;
-    private final Iterable<PathArgument> pathArguments;
+    private static final long serialVersionUID = 3L;
+    private transient final Iterable<PathArgument> pathArguments;
     private final int hash;
 
-    private transient volatile ImmutableList<PathArgument> legacyPath = null;
+    private volatile ImmutableList<PathArgument> legacyPath = null;
     private transient volatile String toStringCache = null;
 
+    static {
+        final Field f;
+        try {
+            f = YangInstanceIdentifier.class.getDeclaredField("pathArguments");
+        } catch (NoSuchFieldException | SecurityException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+        f.setAccessible(true);
+
+        PATHARGUMENTS_FIELD = f;
+    }
+
     private final ImmutableList<PathArgument> getLegacyPath() {
         // Temporary variable saves a volatile read
         ImmutableList<PathArgument> ret = legacyPath;
@@ -802,4 +819,26 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         }
         return ret;
     }
+
+    private void readObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
+        inputStream.defaultReadObject();
+
+        try {
+            PATHARGUMENTS_FIELD.set(this, legacyPath);
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new IOException(e);
+        }
+    }
+
+    private void writeObject(final ObjectOutputStream outputStream) throws IOException {
+        /*
+         * This may look strange, but what we are doing here is side-stepping the fact
+         * that pathArguments is not generally serializable. We are forcing instantiation
+         * of the legacy path, which is an ImmutableList (thus Serializable) and write
+         * it out. The read path does the opposite -- it reads the legacyPath and then
+         * uses invocation API to set the field.
+         */
+        getLegacyPath();
+        outputStream.defaultWriteObject();
+    }
 }
index 3cc626389c705b1186d8ffab111133d4fe849b32..d451d6e86166f359e8f79008f07318eb1d1957d3 100644 (file)
@@ -10,17 +10,19 @@ package org.opendaylight.yangtools.yang.data.api;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map.Entry;
-
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
@@ -301,4 +303,24 @@ public class InstanceIdentifierTest {
 
         assertNotNull( node1.toString() ); // for code coverage
     }
+
+    @Test
+    public void serializationTest() throws IOException, ClassNotFoundException {
+        final YangInstanceIdentifier expected = YangInstanceIdentifier.create(new NodeIdentifier(nodeName1), new NodeIdentifier(nodeName2));
+
+        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        final ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(expected);
+        oos.close();
+
+        final byte[] bytes = bos.toByteArray();
+        final ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+        final ObjectInputStream ois = new ObjectInputStream(bis);
+
+        final YangInstanceIdentifier read = (YangInstanceIdentifier) ois.readObject();
+        assertEquals(0, ois.available());
+        ois.close();
+
+        assertEquals(expected, read);
+    }
 }
index beb797975cf696cf8189f69532c1d4a36909376b..bd8252159ae58b9c2e898f6d0de573d34fbd40e6 100644 (file)
@@ -20,7 +20,11 @@ public abstract class AbstractImmutableNormalizedValueNode<K extends YangInstanc
     protected AbstractImmutableNormalizedValueNode(final K nodeIdentifier, final V value) {
         super(nodeIdentifier);
         if (value == null) {
-            LOGGER.warn("The value of node " + nodeIdentifier.getNodeType() + " is null");
+            /*
+             * Null value is allowed for empty type definition so it should be debug,
+             * but still we are logging it in case we need to debug missing values.
+             */
+            LOGGER.debug("The value of node {} is null",nodeIdentifier.getNodeType());
         }
         this.value = value;
     }