[ONOS-7302] UT for value namespace in identifier. JSON/XML serializer change for value ns.
Change-Id: Ia5e77c2af822455d36cd307a38c91ba6a28597cd
diff --git a/model/src/main/java/org/onosproject/yang/model/LeafNode.java b/model/src/main/java/org/onosproject/yang/model/LeafNode.java
index beeb165..2224750 100644
--- a/model/src/main/java/org/onosproject/yang/model/LeafNode.java
+++ b/model/src/main/java/org/onosproject/yang/model/LeafNode.java
@@ -82,7 +82,7 @@
"key=" + key() + ", " +
"value=" + asString() +
"valueNamespace=" + valueNamespace() +
- "leafType=" + leafType.toString() +
+ "leafType=" + String.valueOf(type) +
"}";
}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/TestUtils.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/TestUtils.java
index f059e1f..ddd4f55 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/TestUtils.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/TestUtils.java
@@ -243,6 +243,19 @@
}
/**
+ * Validates the leaf data node with value namespace.
+ *
+ * @param leaf leaf data node
+ * @param value leaf value
+ * @param valueNs leaf value namespace
+ */
+ public static void validateLeafDataNodeNs(LeafNode leaf, Object value,
+ String valueNs) {
+ assertEquals(leaf.value(), value);
+ assertEquals(leaf.valueNamespace(), valueNs);
+ }
+
+ /**
* Walks in the given built data tree and validates it.
*/
public static void walkINTree(DataNode node,
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
index 9e63b1a..e1d83f2 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YtbResourceIdTest.java
@@ -20,6 +20,23 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.DefaultTest;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Giga;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Optical;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Typed;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.Con;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.DefaultCon;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.con.DefaultInterfaces;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.con.Interfaces;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.con.interfaces.DefaultIntList;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.con.interfaces.IntList;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.con.interfaces.intlist.Available;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.test.con.interfaces.intlist.DefaultAvailable;
+import org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.typed.TypedUnion;
+import org.onosproject.yang.gen.v1.identitytypes.rev20130715.identitytypes.Loopback;
+import org.onosproject.yang.gen.v1.identitytypes.rev20130715.identitytypes.Physical;
+import org.onosproject.yang.gen.v1.identitytypessecond.rev20130715.identitytypessecond.Ethernet;
+import org.onosproject.yang.gen.v1.identitytypessecond.rev20130715.identitytypessecond.Virtual;
import org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.Bitdef;
import org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.DefaultType;
import org.onosproject.yang.gen.v1.modulelistandkey.rev20160826.modulelistandkey.DefaultVal;
@@ -75,6 +92,7 @@
import org.onosproject.yang.model.KeyLeaf;
import org.onosproject.yang.model.LeafIdentifier;
import org.onosproject.yang.model.LeafListKey;
+import org.onosproject.yang.model.LeafNode;
import org.onosproject.yang.model.ListKey;
import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectId;
@@ -112,6 +130,7 @@
import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.processSchemaRegistry;
import static org.onosproject.yang.runtime.impl.MockYangSchemaNodeProvider.registry;
import static org.onosproject.yang.runtime.impl.TestUtils.validateDataNode;
+import static org.onosproject.yang.runtime.impl.TestUtils.validateLeafDataNodeNs;
/**
* Unit test cases for resource id conversion from model object id.
@@ -120,6 +139,7 @@
@Rule
public ExpectedException thrown = ExpectedException.none();
+ DefaultYangModelRegistry reg;
private ResourceData rscData;
private DefaultDataTreeBuilder treeBuilder;
private ResourceId id;
@@ -127,7 +147,6 @@
private SchemaId sid;
private ModelObjectId mid;
private Builder data;
- DefaultYangModelRegistry reg;
/**
* Prior setup for each UT.
@@ -523,4 +542,136 @@
validateDataNode(it.next(), "wait", ns,
SINGLE_INSTANCE_LEAF_VALUE_NODE, true, "wait");
}
+
+ /**
+ * Processes identity with value namespace.
+ */
+ @Test
+ public void processIdentity() {
+ org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Available
+ avail1 = new org.onosproject.yang.gen.v1.identitytest
+ .rev20130715.identitytest.Available(Loopback.class);
+ org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Available
+ avail2 = new org.onosproject.yang.gen.v1.identitytest
+ .rev20130715.identitytest.Available(Giga.class);
+ org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Available
+ avail3 = new org.onosproject.yang.gen.v1.identitytest
+ .rev20130715.identitytest.Available(Ethernet.class);
+
+ Available available = new DefaultAvailable();
+ available.addToLl(avail1);
+ available.addToLl(avail2);
+ available.addToLl(avail3);
+
+ TypedUnion typedUnion = new TypedUnion(Virtual.class);
+ Typed typed = new Typed(typedUnion);
+ IntList list = new DefaultIntList();
+ list.iden(typed);
+ list.available(available);
+
+ org.onosproject.yang.gen.v1.identitytest.rev20130715.identitytest.Available
+ avail4 = new org.onosproject.yang.gen.v1.identitytest
+ .rev20130715.identitytest.Available(Giga.class);
+
+ Available available2 = new DefaultAvailable();
+ available2.addToLl(avail4);
+
+ TypedUnion typedUnion2 = new TypedUnion(Optical.class);
+ Typed typed2 = new Typed(typedUnion2);
+ IntList list2 = new DefaultIntList();
+ list2.iden(typed2);
+ list2.available(available2);
+
+ Interfaces ifs = new DefaultInterfaces();
+ ifs.addToIntList(list);
+ ifs.addToIntList(list2);
+
+ Con con = new DefaultCon();
+ con.yangAutoPrefixInterface(Physical.class);
+ con.interfaces(ifs);
+
+ mid = builder().addChild(DefaultTest.class).build();
+ data = new Builder();
+ data.identifier(mid);
+ data.addModelObject((ModelObject) con);
+ rscData = treeBuilder.getResourceData(data.build());
+
+ List<DataNode> contDn = rscData.dataNodes();
+ String ns = "identity:ns:test:json:ser";
+ String ns2 = "identity:list:ns:test:json:ser";
+ String ns3 = "identity:list:second:ns:test:json:ser";
+ Iterator<DataNode> it = contDn.iterator();
+
+ DataNode contNode = it.next();
+ validateDataNode(contNode, "con", ns, SINGLE_INSTANCE_NODE,
+ true, null);
+
+ Map<NodeKey, DataNode> child = ((InnerNode) contNode).childNodes();
+ List<DataNode> ints = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ ints.add(c.getValue());
+ }
+
+ it = ints.iterator();
+ DataNode ifl = it.next();
+ validateLeafDataNodeNs((LeafNode) ifl, "physical", ns2);
+
+ DataNode inters = it.next();
+ validateDataNode(inters, "interfaces", ns, SINGLE_INSTANCE_NODE,
+ true, null);
+
+ child = ((InnerNode) inters).childNodes();
+ ints = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ ints.add(c.getValue());
+ }
+ Iterator<DataNode> listIt = ints.iterator();
+ DataNode intLi1 = listIt.next();
+ validateDataNode(intLi1, "int-list", ns,
+ MULTI_INSTANCE_NODE, true, null);
+ child = ((InnerNode) intLi1).childNodes();
+ ints = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ ints.add(c.getValue());
+ }
+ it = ints.iterator();
+ DataNode id1 = it.next();
+ validateLeafDataNodeNs((LeafNode) id1, "virtual", ns3);
+ DataNode avail = it.next();
+ validateDataNode(avail, "available", ns,
+ SINGLE_INSTANCE_NODE, true, null);
+
+ child = ((InnerNode) avail).childNodes();
+ ints = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ ints.add(c.getValue());
+ }
+ it = ints.iterator();
+ validateLeafDataNodeNs((LeafNode) it.next(), "Loopback", ns2);
+ validateLeafDataNodeNs((LeafNode) it.next(), "Giga", ns);
+ validateLeafDataNodeNs((LeafNode) it.next(), "Ethernet", ns3);
+ DataNode intLi2 = listIt.next();
+
+ validateDataNode(intLi2, "int-list", ns,
+ MULTI_INSTANCE_NODE, true, null);
+ child = ((InnerNode) intLi2).childNodes();
+ ints = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ ints.add(c.getValue());
+ }
+ it = ints.iterator();
+ DataNode id2 = it.next();
+ validateLeafDataNodeNs((LeafNode) id2, "optical", ns);
+ DataNode availab2 = it.next();
+ validateDataNode(availab2, "available", ns,
+ SINGLE_INSTANCE_NODE, true, null);
+
+ child = ((InnerNode) availab2).childNodes();
+ ints = new LinkedList<>();
+ for (Map.Entry<NodeKey, DataNode> c : child.entrySet()) {
+ ints.add(c.getValue());
+ }
+ it = ints.iterator();
+ validateLeafDataNodeNs((LeafNode) it.next(), "Giga", ns);
+ }
}
diff --git a/runtime/src/test/resources/ytbTestYangFiles/identity-test.yang b/runtime/src/test/resources/ytbTestYangFiles/identity-test.yang
new file mode 100644
index 0000000..960e1ef
--- /dev/null
+++ b/runtime/src/test/resources/ytbTestYangFiles/identity-test.yang
@@ -0,0 +1,61 @@
+module identity-test {
+ yang-version 1;
+ namespace "identity:ns:test:json:ser";
+ prefix "id";
+
+ import identity-types {
+ prefix "type";
+ }
+
+ revision "2013-07-15";
+
+ identity optical {
+ base type:int-type;
+ }
+
+ identity Giga {
+ base type:physical;
+ }
+
+ typedef available {
+ type identityref {
+ base "type:physical";
+ }
+ }
+
+ typedef typed{
+ type union {
+ type int32;
+ type int8;
+ type identityref {
+ base type:int-type;
+ }
+ }
+ }
+
+ container test {
+ leaf l {
+ type string;
+ }
+ container con {
+ leaf interface {
+ type identityref {
+ base "type:int-type";
+ }
+ }
+ container interfaces {
+ list int-list {
+ key "iden";
+ leaf iden {
+ type "id:typed";
+ }
+ container available {
+ leaf-list ll {
+ type available;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/runtime/src/test/resources/ytbTestYangFiles/identity-types-second.yang b/runtime/src/test/resources/ytbTestYangFiles/identity-types-second.yang
new file mode 100644
index 0000000..f5742b2
--- /dev/null
+++ b/runtime/src/test/resources/ytbTestYangFiles/identity-types-second.yang
@@ -0,0 +1,19 @@
+module identity-types-second{
+ yang-version 1;
+ namespace "identity:list:second:ns:test:json:ser";
+ prefix "sec";
+
+ import identity-types {
+ prefix "type";
+ }
+
+ revision "2013-07-15";
+
+ identity virtual {
+ base type:int-type;
+ }
+
+ identity Ethernet {
+ base type:physical;
+ }
+}
diff --git a/runtime/src/test/resources/ytbTestYangFiles/identity-types.yang b/runtime/src/test/resources/ytbTestYangFiles/identity-types.yang
new file mode 100644
index 0000000..25c8fa5
--- /dev/null
+++ b/runtime/src/test/resources/ytbTestYangFiles/identity-types.yang
@@ -0,0 +1,17 @@
+module identity-types {
+ yang-version 1;
+ namespace "identity:list:ns:test:json:ser";
+ prefix "type";
+ revision "2013-07-15";
+
+ identity int-type {
+ }
+
+ identity physical {
+ base int-type;
+ }
+
+ identity Loopback {
+ base physical;
+ }
+}
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java
index 8a02804..cff16cd 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonBuilder.java
@@ -82,11 +82,12 @@
}
appendField(nodeName);
treeString.append(QUOTE);
- treeString.append(value);
if (valNamespace != null) {
- treeString.append(COLON);
treeString.append(valNamespace);
+ treeString.append(COLON);
}
+ treeString.append(value);
+
treeString.append(QUOTE);
treeString.append(COMMA);
}
diff --git a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
index 185c90c..081ade2 100644
--- a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
+++ b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
@@ -20,7 +20,9 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.io.IOUtils;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.DefaultResourceData;
import org.onosproject.yang.model.NodeKey;
@@ -60,6 +62,16 @@
private static YangSerializerContext context;
private static YangSerializer jsonSerializer;
+ private static String outputIdTestJson = "{\"identity-test:con\":{\"inte" +
+ "rface\":\"identity-types:physical\",\"interfaces\":{\"int-list" +
+ "\":[{\"iden\":\"identity-types-second:virtual\",\"available\":" +
+ "{\"ll\":[\"Loopback:identity-types\",\"Giga:identity-test\",\"" +
+ "Ethernet:identity-types-second\"]}},{\"iden\":\"optical\",\"av" +
+ "ailable\":{\"ll\":[\"Giga\"]}}]}}}";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
@Test
public void demo1Test() throws IOException {
String path = "src/test/resources/test.json";
@@ -97,6 +109,52 @@
}
@Test
+ public void identityValueNsTest() throws IOException {
+ String path = "src/test/resources/id-test1.json";
+ // decode
+ DefaultCompositeStream external =
+ new DefaultCompositeStream("identity-test:test", parseInput(path));
+ CompositeData compositeData = jsonSerializer.decode(external, context);
+ ResourceData resourceData = compositeData.resourceData();
+ ResourceId rid = resourceData.resourceId();
+ DataNode rootNode = resourceData.dataNodes().get(0);
+
+ // encode
+ RuntimeContext.Builder runtimeContextBuilder = DefaultRuntimeContext.builder();
+ runtimeContextBuilder.setDataFormat("JSON");
+ DefaultResourceData.Builder resourceDataBuilder = DefaultResourceData.builder();
+ resourceDataBuilder.addDataNode(rootNode);
+ resourceDataBuilder.resourceId(rid);
+
+ ResourceData resourceDataOutput = resourceDataBuilder.build();
+ DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData.builder();
+ compositeDataBuilder.resourceData(resourceDataOutput);
+ CompositeData compositeData1 = compositeDataBuilder.build();
+ // CompositeData --- YangRuntimeService ---> CompositeStream.
+ CompositeStream compositeStreamOutPut = jsonSerializer.encode(compositeData1,
+ context);
+ InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
+ ObjectNode rootNodeOutput;
+ ObjectMapper mapper = new ObjectMapper();
+ try {
+ rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
+ assertEquals(rootNodeOutput.toString(), outputIdTestJson);
+ } catch (IOException e) {
+ throw e;
+ }
+ }
+
+ @Test
+ public void identityValueNsErrorTest() throws IOException {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Invalid input for value namespace");
+ String path = "src/test/resources/id-test2.json";
+ DefaultCompositeStream external =
+ new DefaultCompositeStream("identity-test:test", parseInput(path));
+ jsonSerializer.decode(external, context);
+ }
+
+ @Test
public void testContainerInResourceIdToUri() {
ResourceId rid = ResourceId.builder().addBranchPointSchema("/", null)
.addBranchPointSchema("device", "namespace1")
diff --git a/serializers/json/src/test/resources/id-test1.json b/serializers/json/src/test/resources/id-test1.json
new file mode 100644
index 0000000..95aabb9
--- /dev/null
+++ b/serializers/json/src/test/resources/id-test1.json
@@ -0,0 +1,28 @@
+{
+ "identity-test:con": {
+ "identity-test:interface": "identity-types:physical",
+ "identity-test:interfaces": {
+ "int-list": [
+ {
+ "iden": "identity-types-second:virtual",
+ "available": {
+ "ll": [
+ "identity-types:Loopback",
+ "identity-test:Giga",
+ "identity-types-second:Ethernet"
+ ]
+ }
+ },
+ {
+ "iden": "optical",
+ "available": {
+ "ll": [
+ "Giga"
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
+
diff --git a/serializers/json/src/test/resources/id-test2.json b/serializers/json/src/test/resources/id-test2.json
new file mode 100644
index 0000000..296c4e9
--- /dev/null
+++ b/serializers/json/src/test/resources/id-test2.json
@@ -0,0 +1,5 @@
+{
+ "identity-test:con": {
+ "identity-test:interface": "physical"
+ }
+}
\ No newline at end of file
diff --git a/serializers/json/src/test/resources/identity-test.yang b/serializers/json/src/test/resources/identity-test.yang
new file mode 100644
index 0000000..960e1ef
--- /dev/null
+++ b/serializers/json/src/test/resources/identity-test.yang
@@ -0,0 +1,61 @@
+module identity-test {
+ yang-version 1;
+ namespace "identity:ns:test:json:ser";
+ prefix "id";
+
+ import identity-types {
+ prefix "type";
+ }
+
+ revision "2013-07-15";
+
+ identity optical {
+ base type:int-type;
+ }
+
+ identity Giga {
+ base type:physical;
+ }
+
+ typedef available {
+ type identityref {
+ base "type:physical";
+ }
+ }
+
+ typedef typed{
+ type union {
+ type int32;
+ type int8;
+ type identityref {
+ base type:int-type;
+ }
+ }
+ }
+
+ container test {
+ leaf l {
+ type string;
+ }
+ container con {
+ leaf interface {
+ type identityref {
+ base "type:int-type";
+ }
+ }
+ container interfaces {
+ list int-list {
+ key "iden";
+ leaf iden {
+ type "id:typed";
+ }
+ container available {
+ leaf-list ll {
+ type available;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/serializers/json/src/test/resources/identity-types-second.yang b/serializers/json/src/test/resources/identity-types-second.yang
new file mode 100644
index 0000000..f5742b2
--- /dev/null
+++ b/serializers/json/src/test/resources/identity-types-second.yang
@@ -0,0 +1,19 @@
+module identity-types-second{
+ yang-version 1;
+ namespace "identity:list:second:ns:test:json:ser";
+ prefix "sec";
+
+ import identity-types {
+ prefix "type";
+ }
+
+ revision "2013-07-15";
+
+ identity virtual {
+ base type:int-type;
+ }
+
+ identity Ethernet {
+ base type:physical;
+ }
+}
diff --git a/serializers/json/src/test/resources/identity-types.yang b/serializers/json/src/test/resources/identity-types.yang
new file mode 100644
index 0000000..25c8fa5
--- /dev/null
+++ b/serializers/json/src/test/resources/identity-types.yang
@@ -0,0 +1,17 @@
+module identity-types {
+ yang-version 1;
+ namespace "identity:list:ns:test:json:ser";
+ prefix "type";
+ revision "2013-07-15";
+
+ identity int-type {
+ }
+
+ identity physical {
+ base int-type;
+ }
+
+ identity Loopback {
+ base physical;
+ }
+}
diff --git a/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerHandler.java b/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerHandler.java
index b7c1c3f..214eda1 100644
--- a/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerHandler.java
+++ b/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerHandler.java
@@ -20,9 +20,12 @@
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.LeafNode;
import java.util.Stack;
+import static org.onosproject.yang.serializers.xml.XmlSerializerLeafHandler.XML_PREFIX;
+
/**
* Represents an serializer handler to process the XML content and add
* element to the stack.
@@ -56,6 +59,10 @@
nameSpace = node.key().schemaId().namespace();
name = node.key().schemaId().name();
}
+ String valueNs = null;
+ if (node instanceof LeafNode) {
+ valueNs = ((LeafNode) node).valueNamespace();
+ }
if (elementStack.isEmpty()) {
Element rootElement = DocumentHelper.createDocument()
@@ -77,6 +84,9 @@
} else {
newElement = xmlElement.addElement(name);
}
+ if (valueNs != null) {
+ newElement.addNamespace(XML_PREFIX, valueNs);
+ }
return newElement;
}
}
diff --git a/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerLeafHandler.java b/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerLeafHandler.java
index 423cf52..7206361 100644
--- a/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerLeafHandler.java
+++ b/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerLeafHandler.java
@@ -22,16 +22,26 @@
import java.util.Stack;
+import static org.onosproject.yang.serializers.xml.XmlSerializerListener.COLON;
+
/**
* Represents a leaf node handler in XML serializer.
*/
public class XmlSerializerLeafHandler extends XmlSerializerHandler {
+ protected static final String XML_PREFIX = "yangid";
+
@Override
public void setXmlValue(DataNode node, Stack<Element> elementStack) {
Object value = ((LeafNode) node).value();
if (value != null) {
- elementStack.peek().setText(value.toString());
+ Element ele = elementStack.peek();
+ if (ele.getNamespaceForPrefix(XML_PREFIX) != null) {
+ elementStack.peek().setText(XML_PREFIX + COLON +
+ value.toString());
+ } else {
+ elementStack.peek().setText(value.toString());
+ }
}
}
}
diff --git a/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerListener.java b/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerListener.java
index eebc95c..67832d3 100644
--- a/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerListener.java
+++ b/serializers/xml/src/main/java/org/onosproject/yang/serializers/xml/XmlSerializerListener.java
@@ -17,12 +17,15 @@
package org.onosproject.yang.serializers.xml;
import org.dom4j.Element;
+import org.dom4j.Namespace;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.ResourceId;
import org.onosproject.yang.runtime.AnnotatedNodeInfo;
import org.onosproject.yang.runtime.CompositeData;
import org.onosproject.yang.runtime.HelperContext;
+import java.util.List;
+
import static org.onosproject.yang.runtime.SerializerHelper.addDataNode;
import static org.onosproject.yang.runtime.SerializerHelper.exitDataNode;
import static org.onosproject.yang.runtime.SerializerHelper.getResourceId;
@@ -37,7 +40,7 @@
*/
class XmlSerializerListener implements XmlListener {
- private static final String COLON = ":";
+ protected static final String COLON = ":";
/**
* Data node builder.
@@ -95,32 +98,44 @@
return;
}
- if (nodeType == OBJECT_NODE) {
- if (dnBuilder != null) {
- dnBuilder = addDataNode(dnBuilder, element.getName(),
- element.getNamespace().getURI(),
- null, null);
- }
- } else if (nodeType == TEXT_NODE) {
- if (dnBuilder != null) {
- String valNamespace = null;
- String actVal;
- String valPrefix;
- String value = element.getText();
- if (value != null) {
- actVal = getLatterSegment(value, COLON);
- valPrefix = getPreSegment(value, COLON);
- if (valPrefix != null) {
- valNamespace = element.getNamespaceForPrefix(valPrefix).getURI();
- }
- } else {
- actVal = value;
+ if (dnBuilder != null) {
+ if (nodeType == OBJECT_NODE) {
+ List cont = element.content();
+ if (cont != null && cont.size() == 2 &&
+ isValueNsForLeaf(cont, element)) {
+ return;
}
dnBuilder = addDataNode(dnBuilder, element.getName(),
element.getNamespace().getURI(),
- actVal, valNamespace, null);
+ null, null);
+ } else if (nodeType == TEXT_NODE) {
+ dnBuilder = addDataNode(dnBuilder, element.getName(),
+ element.getNamespace().getURI(),
+ element.getText(), null, null);
}
}
+
+ }
+
+ private boolean isValueNsForLeaf(List cont, Element element) {
+ for (Object c : cont) {
+ if (c instanceof Namespace) {
+ String value = element.getText();
+ String valueNs = ((Namespace) c).getURI();
+ if (value != null) {
+ String actVal = getLatterSegment(value, COLON);
+ String valPrefix = getPreSegment(value, COLON);
+ if (valPrefix != null && actVal != null &&
+ valPrefix.equals(((Namespace) c).getPrefix())) {
+ dnBuilder = addDataNode(dnBuilder, element.getName(),
+ element.getNamespace().getURI(),
+ actVal, valueNs, null);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
@Override
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
index 541046b..4d92437 100644
--- a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
@@ -18,7 +18,9 @@
import org.apache.commons.io.IOUtils;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.InnerNode;
import org.onosproject.yang.model.KeyLeaf;
@@ -56,11 +58,23 @@
*/
public class XmlSerializerTest {
- private static YangSerializerContext context;
- private static YangSerializer xmlSerializer;
-
public static final String LNS = "yrt:list.anydata";
private static final String LIST_NS = "yrt:list";
+ private static YangSerializerContext context;
+ private static YangSerializer xmlSerializer;
+ private static String idXml = "<test xmlns=\"identity:ns:test:json:ser" +
+ "\"><con><interface xmlns:yangid=\"identity:list:ns:test:jso" +
+ "n:ser\">yangid:physical</interface><interfaces><int-list><ide" +
+ "n xmlns:yangid=\"identity:list:second:ns:test:json:ser\">ya" +
+ "ngid:virtual</iden><available><ll xmlns:yangid=\"identity:li" +
+ "st:ns:test:json:ser\">yangid:Loopback</ll><ll xmlns:yangid=" +
+ "\"identity:ns:test:json:ser\">yangid:Giga</ll><ll xmlns:yan" +
+ "gid=\"identity:list:second:ns:test:json:ser\">yangid:Ether" +
+ "net</ll></available></int-list><int-list><iden>optical</iden><av" +
+ "ailable><ll>Giga</ll></available></int-list></interfaces></con><" +
+ "/test>";
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
@BeforeClass
public static void prepare() {
@@ -444,6 +458,35 @@
}
/**
+ * Validates XML encode and decode with value namespace for leaf with
+ * identity-ref types.
+ */
+ @Test
+ public void identityValueNsTest() {
+ String path = "src/test/resources/id-test.xml";
+ DefaultCompositeStream external =
+ new DefaultCompositeStream(null, parseInput(path));
+ CompositeData compositeData = xmlSerializer.decode(external, context);
+ CompositeStream compositeStream = xmlSerializer.encode(compositeData,
+ context);
+ InputStream inputStream = compositeStream.resourceData();
+ assertThat(convertInputStreamToString(inputStream), is(idXml));
+ }
+
+ /**
+ * Validates the error message for identity-ref without proper namespace.
+ */
+ @Test
+ public void identityValueNsErrorTest() {
+ thrown.expect(XmlSerializerException.class);
+ thrown.expectMessage("Invalid input for value namespace");
+ String path = "src/test/resources/id-test2.xml";
+ DefaultCompositeStream external =
+ new DefaultCompositeStream(null, parseInput(path));
+ xmlSerializer.decode(external, context);
+ }
+
+ /**
* Validates whether XML attributes is converted to annotations.
*/
@Test
diff --git a/serializers/xml/src/test/resources/id-test.xml b/serializers/xml/src/test/resources/id-test.xml
new file mode 100644
index 0000000..ab3308b
--- /dev/null
+++ b/serializers/xml/src/test/resources/id-test.xml
@@ -0,0 +1,21 @@
+<test xmlns="identity:ns:test:json:ser" operation="create">
+ <con>
+ <interface xmlns:types="identity:list:ns:test:json:ser">types:physical</interface>
+ <interfaces>
+ <int-list>
+ <iden xmlns:second="identity:list:second:ns:test:json:ser">second:virtual</iden>
+ <available>
+ <ll xmlns:types="identity:list:ns:test:json:ser">types:Loopback</ll>
+ <ll xmlns:test="identity:ns:test:json:ser">test:Giga</ll>
+ <ll xmlns:second="identity:list:second:ns:test:json:ser">second:Ethernet</ll>
+ </available>
+ </int-list>
+ <int-list>
+ <iden>optical</iden>
+ <available>
+ <ll>Giga</ll>
+ </available>
+ </int-list>
+ </interfaces>
+ </con>
+</test>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/id-test2.xml b/serializers/xml/src/test/resources/id-test2.xml
new file mode 100644
index 0000000..be15bc9
--- /dev/null
+++ b/serializers/xml/src/test/resources/id-test2.xml
@@ -0,0 +1,13 @@
+<!--
+ ~ Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ ~ Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
+ ~ Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
+ ~ Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
+ ~ Vestibulum commodo. Ut rhoncus gravida arcu.
+ -->
+
+<test xmlns="identity:ns:test:json:ser" operation="create">
+ <con>
+ <interface>physical</interface>
+ </con>
+</test>
\ No newline at end of file
diff --git a/serializers/xml/src/test/resources/identity-test.yang b/serializers/xml/src/test/resources/identity-test.yang
new file mode 100644
index 0000000..960e1ef
--- /dev/null
+++ b/serializers/xml/src/test/resources/identity-test.yang
@@ -0,0 +1,61 @@
+module identity-test {
+ yang-version 1;
+ namespace "identity:ns:test:json:ser";
+ prefix "id";
+
+ import identity-types {
+ prefix "type";
+ }
+
+ revision "2013-07-15";
+
+ identity optical {
+ base type:int-type;
+ }
+
+ identity Giga {
+ base type:physical;
+ }
+
+ typedef available {
+ type identityref {
+ base "type:physical";
+ }
+ }
+
+ typedef typed{
+ type union {
+ type int32;
+ type int8;
+ type identityref {
+ base type:int-type;
+ }
+ }
+ }
+
+ container test {
+ leaf l {
+ type string;
+ }
+ container con {
+ leaf interface {
+ type identityref {
+ base "type:int-type";
+ }
+ }
+ container interfaces {
+ list int-list {
+ key "iden";
+ leaf iden {
+ type "id:typed";
+ }
+ container available {
+ leaf-list ll {
+ type available;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/serializers/xml/src/test/resources/identity-types-second.yang b/serializers/xml/src/test/resources/identity-types-second.yang
new file mode 100644
index 0000000..f5742b2
--- /dev/null
+++ b/serializers/xml/src/test/resources/identity-types-second.yang
@@ -0,0 +1,19 @@
+module identity-types-second{
+ yang-version 1;
+ namespace "identity:list:second:ns:test:json:ser";
+ prefix "sec";
+
+ import identity-types {
+ prefix "type";
+ }
+
+ revision "2013-07-15";
+
+ identity virtual {
+ base type:int-type;
+ }
+
+ identity Ethernet {
+ base type:physical;
+ }
+}
diff --git a/serializers/xml/src/test/resources/identity-types.yang b/serializers/xml/src/test/resources/identity-types.yang
new file mode 100644
index 0000000..25c8fa5
--- /dev/null
+++ b/serializers/xml/src/test/resources/identity-types.yang
@@ -0,0 +1,17 @@
+module identity-types {
+ yang-version 1;
+ namespace "identity:list:ns:test:json:ser";
+ prefix "type";
+ revision "2013-07-15";
+
+ identity int-type {
+ }
+
+ identity physical {
+ base int-type;
+ }
+
+ identity Loopback {
+ base physical;
+ }
+}