[ONOS-5962]YANG Runtime: ModelConverter's createModel implementation
Change-Id: I8377ad86d0b0b60f96c4d8d40517cede66c5fc27
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
index 1328185..4509e59 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangModule.java
@@ -88,7 +88,8 @@
extends YangNode
implements YangLeavesHolder, YangDesc, YangReference, Parsable,
CollisionDetector, YangReferenceResolver, RpcNotificationContainer,
- YangFeatureHolder, YangIsFilterContentNodes, YangNamespace, YangDeviationHolder {
+ YangFeatureHolder, YangIsFilterContentNodes, YangNamespace,
+ YangDeviationHolder {
private static final long serialVersionUID = 806201610L;
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java
index e2d7e00..0dd728a 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNode.java
@@ -1017,7 +1017,7 @@
// setting the schema Id
schemaId = new SchemaId(getName(), getNameSpace()
.getModuleNamespace());
- } else if (this instanceof YangCase) {
+ } else if (this instanceof YangCase || this instanceof YangAugment) {
((YangLeavesHolder) this).setLeafParentContext();
}
}
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNotification.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNotification.java
index 0255a2a..fba7fd9 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNotification.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangNotification.java
@@ -19,12 +19,17 @@
import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
import org.onosproject.yang.compiler.datamodel.utils.Parsable;
import org.onosproject.yang.compiler.datamodel.utils.YangConstructType;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.model.SchemaId;
+import org.onosproject.yang.model.SingleInstanceNodeContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Collections.unmodifiableList;
import static org.onosproject.yang.compiler.datamodel.YangNodeType.NOTIFICATION_NODE;
import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_SINGLE_INSTANCE_NODE;
@@ -32,7 +37,11 @@
import static org.onosproject.yang.compiler.datamodel.exceptions.ErrorMessages.COLLISION_DETECTION;
import static org.onosproject.yang.compiler.datamodel.exceptions.ErrorMessages.NOTIFICATION;
import static org.onosproject.yang.compiler.datamodel.exceptions.ErrorMessages.getErrorMsgCollision;
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.E_ID;
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.FMT_NOT_EXIST;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.errorMsg;
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.getNodeIdFromSchemaId;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.getParentSchemaContext;
import static org.onosproject.yang.compiler.datamodel.utils.YangConstructType.NOTIFICATION_DATA;
@@ -88,7 +97,8 @@
public abstract class YangNotification
extends YangNode
implements YangLeavesHolder, YangCommonInfo, Parsable, CollisionDetector,
- YangAugmentableNode, YangIfFeatureHolder, InvalidOpTypeHolder {
+ YangAugmentableNode, YangIfFeatureHolder, InvalidOpTypeHolder,
+ SingleInstanceNodeContext {
private static final long serialVersionUID = 806201611L;
@@ -128,7 +138,8 @@
* Create a notification node.
*/
public YangNotification() {
- super(NOTIFICATION_NODE, new HashMap<>());
+ super(NOTIFICATION_NODE, new HashMap<>(),
+ DataNode.Type.SINGLE_INSTANCE_NODE);
listOfLeaf = new LinkedList<>();
listOfLeafList = new LinkedList<>();
ifFeatureList = new LinkedList<>();
@@ -329,4 +340,24 @@
public void cloneAugmentInfo() {
yangAugmentedInfo = new ArrayList<>();
}
+
+ @Override
+ public SchemaContext getChildContext(SchemaId schemaId) {
+
+ checkNotNull(schemaId, E_ID);
+ YangSchemaNodeIdentifier id = getNodeIdFromSchemaId(
+ schemaId, getNameSpace().getModuleNamespace());
+ try {
+ YangSchemaNode node = getChildSchema(id).getSchemaNode();
+ if (node instanceof SchemaDataNode) {
+ return node;
+ } else {
+ throw new IllegalArgumentException(errorMsg(FMT_NOT_EXIST,
+ schemaId.name(),
+ getName()));
+ }
+ } catch (DataModelException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
}
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
index e1bac7f..1569ef8 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangSubModule.java
@@ -97,7 +97,8 @@
extends YangNode
implements YangLeavesHolder, YangDesc, YangReference, Parsable,
CollisionDetector, YangReferenceResolver, RpcNotificationContainer,
- YangFeatureHolder, YangIsFilterContentNodes, YangNamespace, YangDeviationHolder {
+ YangFeatureHolder, YangIsFilterContentNodes, YangNamespace,
+ YangDeviationHolder {
private static final long serialVersionUID = 806201614L;
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/builtindatatype/ObjectProvider.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/builtindatatype/ObjectProvider.java
index 85dc23d..0b1c3b5 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/builtindatatype/ObjectProvider.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/utils/builtindatatype/ObjectProvider.java
@@ -80,7 +80,9 @@
case BOOLEAN:
return Boolean.parseBoolean(leafValue);
case BINARY:
- return Base64.getDecoder().decode(leafValue);
+ byte[] data = Base64.getDecoder().decode(leafValue);
+ String str = new String(data);
+ return str;
case BITS:
case IDENTITYREF:
case ENUMERATION:
@@ -93,8 +95,12 @@
.getDataTypeExtendedInfo()).getEffectiveDataType();
return getObject(refType, leafValue, refType.getDataType());
case DERIVED:
- return getObject(null, leafValue, ((YangDerivedInfo) typeInfo
- .getDataTypeExtendedInfo()).getEffectiveBuiltInType());
+ // referred typedef's list of type will always has only one type
+ YangType rt = ((YangDerivedInfo) typeInfo
+ .getDataTypeExtendedInfo()).getReferredTypeDef()
+ .getTypeList().get(0);
+ return getObject(rt, leafValue, ((YangDerivedInfo)
+ typeInfo.getDataTypeExtendedInfo()).getEffectiveBuiltInType());
case UNION:
return parseUnionTypeInfo(typeInfo, leafValue);
default:
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/JavaFileGenerator.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/JavaFileGenerator.java
index b764ead..6a5ed29 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/JavaFileGenerator.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/JavaFileGenerator.java
@@ -59,6 +59,8 @@
import static org.onosproject.yang.compiler.translator.tojava.GeneratedJavaFileType.GENERATE_TYPEDEF_CLASS;
import static org.onosproject.yang.compiler.translator.tojava.GeneratedJavaFileType.GENERATE_UNION_CLASS;
import static org.onosproject.yang.compiler.translator.tojava.GeneratedJavaFileType.INTERFACE_MASK;
+import static org.onosproject.yang.compiler.translator.tojava.GeneratedTempFileType.ADD_TO_LIST_IMPL_MASK;
+import static org.onosproject.yang.compiler.translator.tojava.GeneratedTempFileType.ADD_TO_LIST_INTERFACE_MASK;
import static org.onosproject.yang.compiler.translator.tojava.GeneratedTempFileType.ATTRIBUTES_MASK;
import static org.onosproject.yang.compiler.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_FOR_TYPE_MASK;
import static org.onosproject.yang.compiler.translator.tojava.GeneratedTempFileType.ENUM_IMPL_MASK;
@@ -254,6 +256,8 @@
insertDataIntoJavaFile(file, getDataFromTempFileHandle(
SETTER_FOR_INTERFACE_MASK, getBeanFiles(curNode), path));
+ insertDataIntoJavaFile(file, getDataFromTempFileHandle(
+ ADD_TO_LIST_INTERFACE_MASK, getBeanFiles(curNode), path));
} catch (IOException e) {
throw new IOException(getErrorMsg(className, INTERFACE));
}
@@ -500,6 +504,10 @@
methods.add(getDataFromTempFileHandle(
SETTER_FOR_CLASS_MASK, getBeanFiles(curNode), path));
+ //Add to list impl method.
+ methods.add(getDataFromTempFileHandle(
+ ADD_TO_LIST_IMPL_MASK, getBeanFiles(curNode), path));
+
// Hash code method.
methods.add(getHashCodeMethodClose(
getHashCodeMethodOpen() + getDataFromTempFileHandle(
diff --git a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java
index 3d88b35..c853fef 100644
--- a/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java
+++ b/compiler/base/translator/src/main/java/org/onosproject/yang/compiler/translator/tojava/utils/MethodsGenerator.java
@@ -1451,17 +1451,17 @@
param.put(attr.getAttributeName() + KEYS, retType + KEYS);
param.put(attr.getAttributeName() + VALUE_CAPS, retType);
return multiAttrMethodSignature(methodName, null, null,
- className, param,
+ VOID, param,
INTERFACE_TYPE,
FOUR_SPACE_INDENTATION);
default:
return methodSignature(methodName, null, null, ADD_STRING + TO_CAPS,
- className, retType,
+ VOID, retType,
INTERFACE_TYPE);
}
}
return methodSignature(methodName, null, null, ADD_STRING + TO_CAPS,
- className, getReturnType(attr),
+ VOID, getReturnType(attr),
INTERFACE_TYPE);
}
@@ -1505,7 +1505,7 @@
param.put(attr.getAttributeName() + VALUE_CAPS, retType);
builder.append(multiAttrMethodSignature(methodName,
null, PUBLIC,
- name, param,
+ VOID, param,
CLASS_TYPE,
FOUR_SPACE_INDENTATION))
.append(getIfConditionForAddToListMethod(attr));
@@ -1518,7 +1518,7 @@
builder.append(methodSignature(methodName,
null, PUBLIC,
ADD_STRING + TO_CAPS,
- name, retType,
+ VOID, retType,
CLASS_TYPE))
.append(getIfConditionForAddToListMethod(attr));
retString = EIGHT_SPACE_INDENTATION + attrName + PERIOD + ADD_STRING +
@@ -1528,7 +1528,7 @@
builder.append(methodSignature(ADD_STRING + TO_CAPS +
getCapitalCase(attrName),
null, PUBLIC, ADD_STRING + TO_CAPS,
- name, retType,
+ VOID, retType,
CLASS_TYPE))
.append(getIfConditionForAddToListMethod(attr));
retString = EIGHT_SPACE_INDENTATION + attrName + PERIOD + ADD_STRING +
@@ -1536,8 +1536,6 @@
}
builder.append(retString)
.append(signatureClose())
- .append(getReturnString(THIS, EIGHT_SPACE_INDENTATION))
- .append(signatureClose())
.append(methodClose(FOUR_SPACE));
return builder.toString();
diff --git a/compiler/base/utils/src/main/java/org/onosproject/yang/compiler/utils/io/impl/JavaDocGen.java b/compiler/base/utils/src/main/java/org/onosproject/yang/compiler/utils/io/impl/JavaDocGen.java
index 2b2c0ec..050fd52 100644
--- a/compiler/base/utils/src/main/java/org/onosproject/yang/compiler/utils/io/impl/JavaDocGen.java
+++ b/compiler/base/utils/src/main/java/org/onosproject/yang/compiler/utils/io/impl/JavaDocGen.java
@@ -597,9 +597,7 @@
break;
}
}
- javadoc.append(getJavaDocParamLine(
- attribute, ADD_STRING + TO_CAPS))
- .append(getJavaDocReturnLine(attribute))
+ javadoc.append(getJavaDocParamLine(attribute, ADD_STRING + TO_CAPS))
.append(getJavaDocEndLine());
return javadoc.toString();
}
diff --git a/model/src/main/java/org/onosproject/yang/model/LeafModelObject.java b/model/src/main/java/org/onosproject/yang/model/LeafModelObject.java
index 162fc54..028d7e4 100644
--- a/model/src/main/java/org/onosproject/yang/model/LeafModelObject.java
+++ b/model/src/main/java/org/onosproject/yang/model/LeafModelObject.java
@@ -72,4 +72,13 @@
public void values(List<Object> v) {
values = v;
}
+
+ /**
+ * Adds value to list.
+ *
+ * @param v value
+ */
+ public void addValue(Object v) {
+ values.add(v);
+ }
}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java
index 8a97560..3bb668b 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java
@@ -105,10 +105,19 @@
ResourceId.Builder builder, String name, String namespace,
String value) {
try {
+ SchemaContext parentCont = (SchemaContext) builder.appInfo();
SchemaContext child = getChildSchemaContext(
- (SchemaContext) builder.appInfo(), name, namespace);
+ parentCont, name, namespace);
+ if (child == null) {
+ throw new IllegalArgumentException(
+ errorMsg(FMT_NOT_EXIST, name));
+ }
DataNode.Type type = child.getType();
updateResourceId(builder, name, value, child, type);
+ if (type == SINGLE_INSTANCE_LEAF_VALUE_NODE &&
+ ((YangLeaf) child).isKeyLeaf()) {
+ builder.appInfo(parentCont);
+ }
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage());
}
@@ -287,8 +296,8 @@
nodeInfo = info;
}
- SchemaContext childSchema = getChildSchemaContext(
- node, name, namespace);
+ SchemaContext childSchema = getChildSchemaContext(node, name,
+ namespace);
DataNode.Type nodeType = childSchema.getType();
if (type != null && !nodeType.equals(type)) {
@@ -423,7 +432,7 @@
* @param namespace namespace of the child node
* @return schema context
*/
- private static SchemaContext getChildSchemaContext(
+ public static SchemaContext getChildSchemaContext(
SchemaContext context, String name, String namespace)
throws IllegalArgumentException {
SchemaContext child;
@@ -436,10 +445,6 @@
SchemaId id = new SchemaId(name, namespace);
child = ((SingleInstanceNodeContext) context).getChildContext(id);
- if (child == null) {
- throw new IllegalArgumentException(
- errorMsg(FMT_NOT_EXIST, name));
- }
return child;
}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java
index 241304c..77d1b7f 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java
@@ -38,7 +38,8 @@
@Override
public ModelObjectData createModel(ResourceData data) {
- return null;
+ DefaultYobBuilder builder = new DefaultYobBuilder(reg);
+ return builder.getYangObject(data);
}
@Override
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
index 9756603..e679d60 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
@@ -16,8 +16,6 @@
package org.onosproject.yang.runtime.impl;
-import org.onosproject.yang.model.YangModel;
-import org.onosproject.yang.model.YangModuleId;
import org.onosproject.yang.compiler.datamodel.SchemaDataNode;
import org.onosproject.yang.compiler.datamodel.YangChoice;
import org.onosproject.yang.compiler.datamodel.YangNode;
@@ -28,6 +26,8 @@
import org.onosproject.yang.model.SchemaContext;
import org.onosproject.yang.model.SchemaId;
import org.onosproject.yang.model.SingleInstanceNodeContext;
+import org.onosproject.yang.model.YangModel;
+import org.onosproject.yang.model.YangModuleId;
import org.onosproject.yang.runtime.AppModuleInfo;
import org.onosproject.yang.runtime.ModelRegistrationParam;
import org.onosproject.yang.runtime.YangModelRegistry;
@@ -580,8 +580,7 @@
//If namespace if module name.
node = getForSchemaName(schemaId.namespace());
}
- YangSchemaNodeIdentifier id = getNodeIdFromSchemaId(
- schemaId, namespace);
+ YangSchemaNodeIdentifier id = getNodeIdFromSchemaId(schemaId, namespace);
try {
if (node != null) {
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYobBuilder.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYobBuilder.java
new file mode 100644
index 0000000..fa0e804
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYobBuilder.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.YangLeaf;
+import org.onosproject.yang.compiler.datamodel.YangLeafList;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.DefaultModelObjectData;
+import org.onosproject.yang.model.LeafListKey;
+import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ModelObjectId;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.model.SchemaId;
+
+import java.util.Iterator;
+import java.util.List;
+
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.nonEmpty;
+import static org.onosproject.yang.runtime.helperutils.DefaultDataNodeWalker.walk;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.getChildSchemaContext;
+import static org.onosproject.yang.runtime.impl.YobUtils.FORWARD_SLASH;
+import static org.onosproject.yang.runtime.impl.YobUtils.handleLeafListKey;
+import static org.onosproject.yang.runtime.impl.YobUtils.handleListKey;
+import static org.onosproject.yang.runtime.impl.YobUtils.handleNodeKey;
+
+/**
+ * Represents implementation to build and obtain YANG objects from data node.
+ */
+public class DefaultYobBuilder {
+ private final DefaultYangModelRegistry registry;
+ private YangSchemaNode lastIndexNode;
+
+ /**
+ * Creates an instance of YOB builder.
+ *
+ * @param reg YANG model registry
+ */
+ public DefaultYobBuilder(DefaultYangModelRegistry reg) {
+ registry = reg;
+ }
+
+ /**
+ * Returns the YANG object.
+ *
+ * @param data resource data
+ * @return model object identifier and YANG object
+ */
+ public ModelObjectData getYangObject(ResourceData data) {
+ DefaultModelObjectData.Builder builder = DefaultModelObjectData.builder();
+ ModelObjectId id = null;
+ if (data.resourceId() != null) {
+ id = convertRscIdToMoId(data.resourceId());
+ }
+
+ List<DataNode> dataNodes = data.dataNodes();
+ if (nonEmpty(dataNodes)) {
+ for (DataNode dataNode : dataNodes) {
+ YobListener listener = new YobListener(lastIndexNode, registry);
+ walk(listener, dataNode);
+ List<ModelObject> objList = listener.modelObjectList();
+ if (objList != null) {
+ for (ModelObject obj : objList) {
+ builder.addModelObject(obj);
+ }
+ }
+ }
+ }
+ return builder.identifer(id).build();
+ }
+
+ /**
+ * Converts resource identifier to model object identifier.
+ *
+ * @param id resource identifier
+ * @return model object identifier
+ */
+ private ModelObjectId convertRscIdToMoId(ResourceId id) {
+ ModelObjectId.Builder midb = ModelObjectId.builder();
+
+ if (id != null) {
+ List<NodeKey> nodeKeys = id.nodeKeys();
+ NodeKey key;
+ SchemaId sId;
+ if (nonEmpty(nodeKeys)) {
+ Iterator<NodeKey> it = nodeKeys.iterator();
+ while (it.hasNext()) {
+ key = it.next();
+ sId = key.schemaId();
+ if (sId.name().equals(FORWARD_SLASH)) {
+ continue;
+ }
+
+ YangSchemaNode schemaNode;
+ if (lastIndexNode == null) {
+ schemaNode = ((YangSchemaNode) registry.getChildContext(sId));
+ } else {
+ schemaNode = ((YangSchemaNode)
+ getChildSchemaContext(lastIndexNode, sId.name(),
+ sId.namespace()));
+ }
+
+ if (key instanceof ListKey) {
+ midb = handleListKey(midb, registry, schemaNode, key);
+ } else if (key instanceof LeafListKey) {
+ LeafListKey llKey = (LeafListKey) key;
+ midb = handleLeafListKey(midb, registry, schemaNode,
+ llKey);
+ } else {
+ midb = handleNodeKey(midb, registry, schemaNode, key);
+ }
+ if (!(schemaNode instanceof YangLeaf) || !(schemaNode
+ instanceof YangLeafList)) {
+ lastIndexNode = schemaNode;
+ }
+ }
+ }
+ }
+ return midb.build();
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobConstants.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobConstants.java
new file mode 100644
index 0000000..642d84c
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobConstants.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+/**
+ * Represents common constant utility for YANG object builder.
+ */
+final class YobConstants {
+
+ private YobConstants() {
+ }
+
+ static final String FROM_STRING = "fromString";
+ static final String OP_PARAM = "OpParam";
+ static final String DEFAULT = "Default";
+ static final String ADD_TO = "addTo";
+ static final String OF = "of";
+ static final String PERIOD = ".";
+ static final String ADD_AUGMENT_METHOD = "addAugmentation";
+ static final String YANG = "yang";
+ static final String JAVA_LANG = "java.lang";
+
+ //Error strings
+ static final String E_HAS_NO_CHILD = " does not have child ";
+ static final String E_FAIL_TO_GET_FIELD = "Failed to get field for" +
+ " class: ";
+ static final String L_FAIL_TO_GET_FIELD =
+ "Failed to get field for class: {}";
+ static final String E_FAIL_TO_GET_METHOD =
+ "Failed to get method for class: ";
+ static final String L_FAIL_TO_GET_METHOD =
+ "Failed to get method for class: {}";
+ static final String E_FAIL_TO_LOAD_CLASS =
+ "Failed to load class for class: ";
+ static final String E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS =
+ "Failed to load leaf identifier class";
+ static final String L_FAIL_TO_LOAD_CLASS =
+ "Failed to load class for class: {}";
+ static final String E_DATA_NODE_TYPE_IS_NOT_SUPPORT =
+ "Given data node type is not supported.";
+ static final String E_FAIL_TO_CREATE_OBJ =
+ "Failed to create an object for class: ";
+ static final String L_FAIL_TO_CREATE_OBJ =
+ "Failed to create an object for class: {}";
+ static final String E_REFLECTION_FAIL_TO_CREATE_OBJ =
+ "Reflection failed to create an object for class: ";
+ static final String L_REFLECTION_FAIL_TO_CREATE_OBJ =
+ "Reflection failed to create an object for class: {}";
+ static final String E_FAIL_TO_LOAD_CONSTRUCTOR =
+ "Failed to load constructor for class: {}";
+ static final String E_FAIL_TO_INVOKE_METHOD =
+ "Failed to invoke method for class: ";
+ static final String L_FAIL_TO_INVOKE_METHOD =
+ "Failed to invoke method for class: {}";
+ static final String E_DATA_TYPE_NOT_SUPPORT =
+ "Given data type is not supported.";
+ static final String E_INVALID_IDENTITY_DATA =
+ "Value for identityref data type is invalid";
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobHandler.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobHandler.java
new file mode 100644
index 0000000..6b28345
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobHandler.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.runtime.YangModelRegistry;
+
+import static org.onosproject.yang.runtime.impl.YobUtils.getClassLoader;
+import static org.onosproject.yang.runtime.impl.YobUtils.getInstanceOfClass;
+import static org.onosproject.yang.runtime.impl.YobUtils.getQualifiedDefaultClass;
+
+/**
+ * Represents a YANG object builder handler to process the data node content and
+ * build yang object.
+ */
+abstract class YobHandler {
+
+ /**
+ * Creates a YANG builder object.
+ *
+ * @param schemaNode schema context
+ * @param reg YANG model registry
+ * @return YOB workbench for the data node
+ */
+ YobWorkBench createObject(YangSchemaNode schemaNode,
+ DefaultYangModelRegistry reg) {
+ YangSchemaNode node = schemaNode;
+ while (node.getReferredSchema() != null) {
+ node = node.getReferredSchema();
+ }
+
+ String qualName = getQualifiedDefaultClass(node);
+ ClassLoader classLoader = getClassLoader(node, reg);
+ String setterName = schemaNode.getJavaAttributeName();
+ Object builtObject = getInstanceOfClass(classLoader, qualName);
+ return new YobWorkBench(classLoader, builtObject, setterName,
+ schemaNode);
+ }
+
+
+ /**
+ * Sets the YANG built object in corresponding parent class method.
+ *
+ * @param dataNode data node
+ * @param childWb YOB work bench for data node
+ * @param parentWb YOB work bench for parent node
+ * @param reg YANG model registry
+ */
+ void setInParent(DataNode dataNode,
+ YobWorkBench childWb,
+ YobWorkBench parentWb,
+ DefaultYangModelRegistry reg) {
+ parentWb.setObject(childWb, dataNode, reg);
+ }
+
+ /**
+ * Builds the object.
+ *
+ * @param curWorkbench YOB work bench
+ * @param reg YANG model registry
+ */
+ void buildObject(YobWorkBench curWorkbench,
+ YangModelRegistry reg) {
+ curWorkbench.buildObject(reg);
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobHandlerFactory.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobHandlerFactory.java
new file mode 100644
index 0000000..d4e73f3
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobHandlerFactory.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.model.DataNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_DATA_NODE_TYPE_IS_NOT_SUPPORT;
+
+/**
+ * Represents an YANG object builder factory to create different types
+ * of YANG data tree node.
+ */
+final class YobHandlerFactory {
+
+ private static final Logger log =
+ LoggerFactory.getLogger(YobHandlerFactory.class);
+
+ /**
+ * Map of YANG object builder handler.
+ */
+ private static final Map<DataNode.Type, YobHandler> HANDLER_MAP = new
+ HashMap<>();
+
+ /**
+ * Creates instance of YobHandlerFactory.
+ */
+ private YobHandlerFactory() {
+ HANDLER_MAP.put(SINGLE_INSTANCE_NODE, new YobInnerNodeHandler());
+ HANDLER_MAP.put(MULTI_INSTANCE_NODE, new YobInnerNodeHandler());
+ HANDLER_MAP.put(SINGLE_INSTANCE_LEAF_VALUE_NODE,
+ new YobLeafNodeHandler());
+ HANDLER_MAP.put(MULTI_INSTANCE_LEAF_VALUE_NODE,
+ new YobLeafListNodeHandler());
+ }
+
+ /**
+ * Returns the corresponding YOB handler for current context.
+ *
+ * @param type data node type
+ * @return handler to create the object
+ * @throws ModelConvertorException if the data node type is not supported in YOB
+ */
+ YobHandler getYobHandlerForContext(DataNode.Type type) {
+ YobHandler yobHandler = HANDLER_MAP.get(type);
+ if (yobHandler == null) {
+ log.error(E_DATA_NODE_TYPE_IS_NOT_SUPPORT);
+ throw new ModelConvertorException(E_DATA_NODE_TYPE_IS_NOT_SUPPORT);
+ }
+ return yobHandler;
+ }
+
+ /**
+ * Returns the YANG object builder factory instance.
+ *
+ * @return YANG object builder factory instance
+ */
+ static YobHandlerFactory instance() {
+ return LazyHolder.INSTANCE;
+ }
+
+ /*
+ * Bill Pugh Singleton pattern. INSTANCE won't be instantiated until the
+ * LazyHolder class is loaded via a call to the instance() method below.
+ */
+ static class LazyHolder {
+ private static final YobHandlerFactory INSTANCE =
+ new YobHandlerFactory();
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobInnerNodeHandler.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobInnerNodeHandler.java
new file mode 100644
index 0000000..22c4172
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobInnerNodeHandler.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+/**
+ * Represents a inner node handler in YANG object builder.
+ */
+class YobInnerNodeHandler extends YobHandler {
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobLeafListNodeHandler.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobLeafListNodeHandler.java
new file mode 100644
index 0000000..81ccd1d
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobLeafListNodeHandler.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.YangLeafList;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.compiler.datamodel.YangType;
+import org.onosproject.yang.compiler.datamodel.javadatamodel.JavaQualifiedTypeInfoContainer;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.LeafNode;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+
+import static org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes.IDENTITYREF;
+import static org.onosproject.yang.runtime.impl.YobConstants.ADD_TO;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yang.runtime.impl.YobUtils.getCapitalCase;
+import static org.onosproject.yang.runtime.impl.YobUtils.getChildSchemaNode;
+import static org.onosproject.yang.runtime.impl.YobUtils.setDataFromStringValue;
+
+/**
+ * Represents a multi instance leaf node handler in YANG object builder.
+ */
+class YobLeafListNodeHandler extends YobHandler {
+
+ private static final Logger log =
+ LoggerFactory.getLogger(YobLeafListNodeHandler.class);
+
+ @Override
+ YobWorkBench createObject(YangSchemaNode schemaNode,
+ DefaultYangModelRegistry registry) {
+ // For multi instance leaf no need to create an object.
+ return null;
+ }
+
+ /**
+ * Builds the object.
+ *
+ * @param registry YANG schema registry
+ */
+ void buildObject(YobWorkBench curWorkbench,
+ YangModelRegistry registry) {
+ // For multi instance leaf no need to build an object.
+ }
+
+ @Override
+ void setInParent(DataNode leafNode,
+ YobWorkBench curWb,
+ YobWorkBench parentWb,
+ DefaultYangModelRegistry reg) {
+ Class<?> parentClass = null;
+ try {
+ YangSchemaNode schemaNode = getChildSchemaNode(leafNode,
+ curWb.schemaNode());
+ YangSchemaNode referredSchema = schemaNode;
+ while (referredSchema.getReferredSchema() != null) {
+ referredSchema = referredSchema.getReferredSchema();
+ }
+
+ String setterInParent = referredSchema.getJavaAttributeName();
+ Object parentObj = curWb.getParentObject(reg, schemaNode);
+ parentClass = parentObj.getClass();
+
+ Field leafName = parentClass
+ .getDeclaredField(setterInParent);
+ ParameterizedType genericListType =
+ (ParameterizedType) leafName.getGenericType();
+ Class<?> genericListClass;
+ if (((YangLeafList) referredSchema)
+ .getDataType().getDataType() == IDENTITYREF) {
+ ParameterizedType type = (ParameterizedType)
+ genericListType.getActualTypeArguments()[0];
+ genericListClass = type.getClass().getClass();
+ } else {
+ genericListClass = (Class<?>) genericListType.getActualTypeArguments()[0];
+ }
+
+ Method setterMethod = parentClass.getDeclaredMethod(
+ ADD_TO + getCapitalCase(setterInParent), genericListClass);
+
+ JavaQualifiedTypeInfoContainer javaQualifiedType =
+ (JavaQualifiedTypeInfoContainer) referredSchema;
+ YangType<?> yangType =
+ ((YangLeafList) javaQualifiedType).getDataType();
+ setDataFromStringValue(yangType.getDataType(),
+ ((LeafNode) leafNode).value(), setterMethod,
+ parentObj, referredSchema,
+ curWb.schemaNode());
+ } catch (NoSuchMethodException | InvocationTargetException |
+ IllegalAccessException | NoSuchFieldException e) {
+ log.error(L_FAIL_TO_INVOKE_METHOD, parentClass.getName());
+ throw new ModelConvertorException(E_FAIL_TO_INVOKE_METHOD + parentClass
+ .getName());
+ }
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobLeafNodeHandler.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobLeafNodeHandler.java
new file mode 100644
index 0000000..f407d13
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobLeafNodeHandler.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.YangLeaf;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.LeafNode;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yang.runtime.impl.YobUtils.getChildSchemaNode;
+import static org.onosproject.yang.runtime.impl.YobUtils.setDataFromStringValue;
+
+/**
+ * Represents a single instance leaf node handler in YANG object builder.
+ */
+class YobLeafNodeHandler extends YobHandler {
+
+ private static final Logger log =
+ LoggerFactory.getLogger(YobLeafNodeHandler.class);
+
+ @Override
+ YobWorkBench createObject(YangSchemaNode schemaNode,
+ DefaultYangModelRegistry registry) {
+ // For single instance leaf no need to create an object.
+ return null;
+ }
+
+ /**
+ * Builds the object.
+ *
+ * @param registry YANG schema registry
+ */
+ void buildObject(YobWorkBench curWorkbench,
+ YangModelRegistry registry) {
+ // For single instance leaf no need to build an object.
+ }
+
+ @Override
+ void setInParent(DataNode leafNode,
+ YobWorkBench curWb,
+ YobWorkBench parentWb,
+ DefaultYangModelRegistry registry) {
+ Class<?> parentClass = null;
+ try {
+ YangSchemaNode schemaNode = getChildSchemaNode(leafNode, curWb
+ .schemaNode());
+ YangSchemaNode referredSchema = schemaNode;
+ while (referredSchema.getReferredSchema() != null) {
+ referredSchema = referredSchema.getReferredSchema();
+ }
+
+ String setterInParent = referredSchema.getJavaAttributeName();
+ Object parentObj = curWb.getParentObject(registry, schemaNode);
+ parentClass = parentObj.getClass();
+ YangDataTypes dataType = ((YangLeaf) referredSchema).getDataType()
+ .getDataType();
+ if (((LeafNode) leafNode).value() != null ||
+ dataType == YangDataTypes.EMPTY) {
+ Field leafName = parentClass.getDeclaredField(setterInParent);
+ Method setterMethod = parentClass.getDeclaredMethod(setterInParent,
+ leafName.getType());
+
+ setDataFromStringValue(dataType,
+ ((LeafNode) leafNode).value(),
+ setterMethod, parentObj, referredSchema,
+ curWb.schemaNode());
+ }
+ } catch (NoSuchMethodException | InvocationTargetException |
+ IllegalAccessException | NoSuchFieldException e) {
+ log.error(L_FAIL_TO_INVOKE_METHOD, parentClass.getName());
+ throw new ModelConvertorException(E_FAIL_TO_INVOKE_METHOD + parentClass
+ .getName());
+ }
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobListener.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobListener.java
new file mode 100644
index 0000000..dd07eb5
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobListener.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.model.SchemaId;
+import org.onosproject.yang.runtime.helperutils.DataNodeListener;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.getChildSchemaContext;
+import static org.onosproject.yang.runtime.impl.YobHandlerFactory.instance;
+import static org.onosproject.yang.runtime.impl.YobUtils.FORWARD_SLASH;
+import static org.onosproject.yang.runtime.impl.YobUtils.buildLeafModelObject;
+
+/**
+ * Represents implementation of YANG object builder listener.
+ */
+class YobListener implements DataNodeListener {
+
+ /**
+ * Reference to parent schema.
+ */
+ private YangSchemaNode lastIndexSchema;
+
+ /**
+ * Reference to YOB handler.
+ */
+ private final YobHandlerFactory handlerFactory;
+
+ /**
+ * Reference to YANG model registry.
+ */
+ private final DefaultYangModelRegistry registry;
+
+ /**
+ * Stack of YOB workbench.
+ */
+ private final Stack<YobWorkBench> wbStack;
+
+ /**
+ * List of model objects.
+ */
+ private List<ModelObject> modelObjectList;
+
+
+ /**
+ * Creates an instance of YANG object builder listener.
+ *
+ * @param reg YANG model registry
+ */
+ public YobListener(YangSchemaNode node, DefaultYangModelRegistry reg) {
+ this.lastIndexSchema = node;
+ this.handlerFactory = instance();
+ this.registry = reg;
+ this.wbStack = new Stack<>();
+ this.modelObjectList = new LinkedList<>();
+ }
+
+ /**
+ * Returns the list of model object.
+ *
+ * @return list of model object
+ */
+ public List<ModelObject> modelObjectList() {
+ return modelObjectList;
+ }
+
+ /**
+ * Sets the list of model object.
+ *
+ * @param moList list of model object
+ */
+ public void modelObjectList(List<ModelObject> moList) {
+ modelObjectList = moList;
+ }
+
+ /**
+ * Returns the YOB work bench stack.
+ *
+ * @return YOB work bench stack
+ */
+ public Stack<YobWorkBench> wbStack() {
+ return wbStack;
+ }
+
+
+ /**
+ * Returns the parent schema node.
+ *
+ * @return parent schema node
+ */
+ public YangSchemaNode lastIndexSchema() {
+ return lastIndexSchema;
+ }
+
+ /**
+ * Sets the parent schema node.
+ *
+ * @param schemaNode YANG schema node
+ */
+ public void lastIndexSchema(YangSchemaNode schemaNode) {
+ lastIndexSchema = schemaNode;
+ }
+
+ @Override
+ public void enterDataNode(DataNode node) {
+ SchemaId schemaId = node.key().schemaId();
+ if (schemaId.name().equals(FORWARD_SLASH)) {
+ return;
+ }
+
+ YangSchemaNode schemaNode;
+ if (wbStack.isEmpty() && lastIndexSchema == null) {
+ /*
+ * It is first level child and resource id is null. So get the
+ * schema information from registry.
+ */
+ schemaNode = ((YangSchemaNode) registry.getChildContext(schemaId));
+ } else if (wbStack.isEmpty() && lastIndexSchema != null) {
+ /*
+ * Resource id is not null, lastIndexSchema will have schema node
+ * of last node key in resource id.
+ */
+ schemaNode = ((YangSchemaNode)
+ getChildSchemaContext(lastIndexSchema, schemaId.name(),
+ schemaId.namespace()));
+ } else {
+ /*
+ * get schema context for the node from parent data node's schema
+ * context.
+ */
+ SchemaContext parentContext = wbStack.peek().schemaNode();
+ schemaNode = ((YangSchemaNode)
+ getChildSchemaContext(parentContext, schemaId.name(),
+ schemaId.namespace()));
+ }
+
+ // get YOB handler based on node type
+ YobHandler nodeHandler = handlerFactory.getYobHandlerForContext(node.type());
+
+ // Create object for the data node
+ YobWorkBench workBench = nodeHandler.createObject(schemaNode, registry);
+ if (workBench != null) {
+ wbStack.push(workBench);
+ }
+ }
+
+ @Override
+ public void exitDataNode(DataNode node) {
+ SchemaId schemaId = node.key().schemaId();
+ if (schemaId.name().equals(FORWARD_SLASH)) {
+ return;
+ }
+
+ YobWorkBench curWb;
+ YobWorkBench parentWb = null;
+ if (node instanceof InnerNode) {
+ if (wbStack.size() == 1) {
+ curWb = wbStack.pop();
+ YobHandler nodeHandler = handlerFactory.getYobHandlerForContext(node.type());
+ nodeHandler.buildObject(curWb, registry);
+ modelObjectList.add(((ModelObject) curWb.getBuiltObject()));
+ return;
+ } else {
+ curWb = wbStack.pop();
+ parentWb = wbStack.peek();
+ }
+ } else {
+ if (wbStack.isEmpty()) {
+ ModelObject obj = buildLeafModelObject(node, lastIndexSchema, registry);
+ modelObjectList.add(obj);
+ return;
+ }
+ curWb = wbStack.peek();
+ }
+
+ YobHandler nodeHandler = handlerFactory.getYobHandlerForContext(node.type());
+ nodeHandler.buildObject(curWb, registry);
+ nodeHandler.setInParent(node, curWb, parentWb, registry);
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java
new file mode 100644
index 0000000..1e43f47
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobUtils.java
@@ -0,0 +1,895 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.RpcNotificationContainer;
+import org.onosproject.yang.compiler.datamodel.YangDerivedInfo;
+import org.onosproject.yang.compiler.datamodel.YangIdentity;
+import org.onosproject.yang.compiler.datamodel.YangIdentityRef;
+import org.onosproject.yang.compiler.datamodel.YangLeaf;
+import org.onosproject.yang.compiler.datamodel.YangLeafList;
+import org.onosproject.yang.compiler.datamodel.YangLeafRef;
+import org.onosproject.yang.compiler.datamodel.YangList;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yang.compiler.datamodel.YangType;
+import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerModelObject;
+import org.onosproject.yang.model.KeyInfo;
+import org.onosproject.yang.model.KeyLeaf;
+import org.onosproject.yang.model.LeafIdentifier;
+import org.onosproject.yang.model.LeafListKey;
+import org.onosproject.yang.model.LeafModelObject;
+import org.onosproject.yang.model.LeafNode;
+import org.onosproject.yang.model.ListKey;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectId;
+import org.onosproject.yang.model.MultiInstanceObject;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.model.SchemaId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.nonEmpty;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.getCamelCase;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.getChildSchemaContext;
+import static org.onosproject.yang.runtime.impl.YobConstants.DEFAULT;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_DATA_TYPE_NOT_SUPPORT;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_LOAD_CONSTRUCTOR;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_INVALID_IDENTITY_DATA;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_REFLECTION_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yang.runtime.impl.YobConstants.FROM_STRING;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_REFLECTION_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yang.runtime.impl.YobConstants.OF;
+import static org.onosproject.yang.runtime.impl.YobConstants.OP_PARAM;
+import static org.onosproject.yang.runtime.impl.YobConstants.PERIOD;
+
+/**
+ * Utils to support object creation.
+ */
+final class YobUtils {
+
+ private static final Logger log = LoggerFactory.getLogger(YobUtils.class);
+ public static final String FORWARD_SLASH = "/";
+ private static final String ENUM_LEAF_IDENTIFIER = "$LeafIdentifier";
+
+ // no instantiation
+ private YobUtils() {
+ }
+
+ /**
+ * Sets data from string value in parent method.
+ *
+ * @param type refers to YANG data type
+ * @param value value argument is used to set the value in method
+ * @param parentSetter Invokes the underlying method represented
+ * by this parentSetter
+ * @param parentObj the parentObject is to invoke the underlying method
+ * @param schemaNode schema information
+ * @param parentSchema schema information of parent
+ * @throws InvocationTargetException if failed to invoke method
+ * @throws IllegalAccessException if member cannot be accessed
+ * @throws NoSuchMethodException if method is not found
+ */
+ static void setDataFromStringValue(YangDataTypes type,
+ Object value,
+ Method parentSetter,
+ Object parentObj,
+ YangSchemaNode schemaNode,
+ YangSchemaNode parentSchema)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ switch (type) {
+ case INT8:
+ case UINT8:
+ case INT16:
+ case UINT16:
+ case INT32:
+ case UINT32:
+ case INT64:
+ case UINT64:
+ case BOOLEAN:
+ case EMPTY:
+ case STRING:
+ parentSetter.invoke(parentObj, value);
+ break;
+ case BINARY:
+ parentSetter.invoke(parentObj, ((String) value).getBytes());
+ break;
+ case BITS:
+ parseBitSetTypeInfo(parentSetter, parentObj, value,
+ schemaNode, parentSchema);
+ break;
+ case DECIMAL64:
+ parentSetter.invoke(parentObj, new BigDecimal(value.toString()));
+ break;
+
+ case DERIVED:
+ parseDerivedTypeInfo(parentSetter, parentObj, value.toString(),
+ false, schemaNode);
+ break;
+
+ case IDENTITYREF:
+ parseIdentityRefInfo(parentSetter, parentObj, value,
+ schemaNode);
+ break;
+
+ case UNION:
+ parseDerivedTypeInfo(parentSetter, parentObj, value.toString(),
+ false, schemaNode);
+ break;
+
+ case LEAFREF:
+ parseLeafRefTypeInfo(parentSetter, parentObj, value,
+ schemaNode, parentSchema);
+ break;
+
+ case ENUMERATION:
+ parseDerivedTypeInfo(parentSetter, parentObj, value.toString(),
+ true, schemaNode);
+ break;
+
+ default:
+ log.error(E_DATA_TYPE_NOT_SUPPORT);
+ }
+ }
+
+ /**
+ * To set data into parent setter method from string value for derived type.
+ *
+ * @param parentSetter the parent setter method to be invoked
+ * @param parentObj the parent build object on which to invoke the
+ * method
+ * @param value value to be set in method
+ * @param isEnum flag to check whether type is enum or derived
+ * @param leaf schema node
+ * @throws InvocationTargetException if failed to invoke method
+ * @throws IllegalAccessException if member cannot be accessed
+ * @throws NoSuchMethodException if the required method is not found
+ */
+ static void parseDerivedTypeInfo(Method parentSetter,
+ Object parentObj,
+ String value,
+ boolean isEnum,
+ YangSchemaNode leaf)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ Class<?> childSetClass = null;
+ Constructor<?> childConstructor = null;
+ Object childValue = null;
+ Object childObject = null;
+ Method childMethod = null;
+ while (leaf.getReferredSchema() != null) {
+ leaf = leaf.getReferredSchema();
+ }
+
+ String qualifiedClassName = leaf.getJavaPackage() + PERIOD +
+ getCapitalCase(leaf.getJavaClassNameOrBuiltInType());
+ ClassLoader classLoader = parentObj.getClass().getClassLoader();
+ try {
+ childSetClass = classLoader.loadClass(qualifiedClassName);
+ } catch (ClassNotFoundException e) {
+ log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+ }
+
+ if (!isEnum) {
+ if (childSetClass != null) {
+ childConstructor = childSetClass.getDeclaredConstructor();
+ }
+
+ if (childConstructor != null) {
+ childConstructor.setAccessible(true);
+ }
+
+ try {
+ if (childConstructor != null) {
+ childObject = childConstructor.newInstance();
+ }
+ } catch (InstantiationException e) {
+ log.error(E_FAIL_TO_LOAD_CONSTRUCTOR, qualifiedClassName);
+ }
+ if (childSetClass != null) {
+ childMethod = childSetClass
+ .getDeclaredMethod(FROM_STRING, String.class);
+ }
+ } else {
+ if (childSetClass != null) {
+ childMethod = childSetClass.getDeclaredMethod(OF, String.class);
+ }
+ }
+ if (childMethod != null) {
+ childValue = childMethod.invoke(childObject, value);
+ }
+ parentSetter.invoke(parentObj, childValue);
+ }
+
+ /**
+ * To set data into parent setter method from string value for bits type.
+ *
+ * @param parentSetterMethod the parent setter method to be invoked
+ * @param parentObject the parent build object on which to invoke the
+ * method
+ * @param leafValue value to be set in method
+ * @param leaf schema information
+ * @param parentSchema schema information of parent
+ * @throws InvocationTargetException if failed to invoke method
+ * @throws IllegalAccessException if member cannot be accessed
+ * @throws NoSuchMethodException if the required method is not found
+ */
+ static void parseBitSetTypeInfo(Method parentSetterMethod,
+ Object parentObject,
+ Object leafValue,
+ YangSchemaNode leaf,
+ YangSchemaNode parentSchema)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ Class<?> childSetClass = null;
+ Object childValue = null;
+ Object childObject = null;
+ Method childMethod = null;
+
+ while (leaf.getReferredSchema() != null) {
+ leaf = leaf.getReferredSchema();
+ }
+
+ String qualifiedClassName = parentSchema.getJavaPackage() + PERIOD +
+ parentSchema.getJavaAttributeName().toLowerCase() +
+ PERIOD + getCapitalCase(leaf.getJavaAttributeName());
+
+ ClassLoader classLoader = parentObject.getClass().getClassLoader();
+
+ try {
+ childSetClass = classLoader.loadClass(qualifiedClassName);
+ } catch (ClassNotFoundException e) {
+ log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+ }
+
+ if (childSetClass != null) {
+ childMethod = childSetClass.getDeclaredMethod(FROM_STRING, String.class);
+ }
+ if (childMethod != null) {
+ childValue = childMethod.invoke(childObject, leafValue);
+ }
+
+ parentSetterMethod.invoke(parentObject, childValue);
+
+ }
+
+ /**
+ * To set data into parent setter method from string value for leafref type.
+ *
+ * @param parentSetterMethod the parent setter method to be invoked
+ * @param parentObject the parent build object on which to invoke
+ * the method
+ * @param leafValue leaf value to be set
+ * @param schemaNode schema information
+ * @param parentSchema schema information of parent
+ * @throws InvocationTargetException if method could not be invoked
+ * @throws IllegalAccessException if method could not be accessed
+ * @throws NoSuchMethodException if method does not exist
+ */
+ static void parseLeafRefTypeInfo(Method parentSetterMethod,
+ Object parentObject,
+ Object leafValue,
+ YangSchemaNode schemaNode,
+ YangSchemaNode parentSchema)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ while (schemaNode.getReferredSchema() != null) {
+ schemaNode = schemaNode.getReferredSchema();
+ }
+
+ YangLeafRef leafRef;
+ if (schemaNode instanceof YangLeaf) {
+ leafRef = (YangLeafRef) ((YangLeaf) schemaNode)
+ .getDataType().getDataTypeExtendedInfo();
+ } else {
+ leafRef = (YangLeafRef) ((YangLeafList) schemaNode)
+ .getDataType().getDataTypeExtendedInfo();
+ }
+
+ YangType type = leafRef.getEffectiveDataType();
+ if (type.getDataType() == YangDataTypes.DERIVED &&
+ schemaNode.getJavaPackage().equals(YobConstants.JAVA_LANG)) {
+ /*
+ * If leaf is inside grouping, then its return type will be of type
+ * Object and if its actual type is derived type then get the
+ * effective built-in type and set the value.
+ */
+ YangDerivedInfo derivedInfo = (YangDerivedInfo) leafRef
+ .getEffectiveDataType()
+ .getDataTypeExtendedInfo();
+ YobUtils.setDataFromStringValue(derivedInfo.getEffectiveBuiltInType(),
+ leafValue, parentSetterMethod,
+ parentObject, schemaNode, parentSchema);
+ } else {
+ YobUtils.setDataFromStringValue(type.getDataType(),
+ leafValue, parentSetterMethod,
+ parentObject,
+ schemaNode, parentSchema);
+ }
+
+ }
+
+ /**
+ * Returns class loader.
+ *
+ * @param schemaNode schema information
+ * @param reg YANG model registry
+ * @return class loader
+ */
+ static ClassLoader getClassLoader(YangSchemaNode schemaNode,
+ DefaultYangModelRegistry reg) {
+
+ YangSchemaNode curNode = schemaNode;
+ while (!(curNode instanceof RpcNotificationContainer)) {
+ curNode = ((YangNode) curNode).getParent();
+ }
+
+ Class<?> regClass = reg.getRegisteredClass(curNode);
+ return regClass.getClassLoader();
+ }
+
+ /**
+ * Returns the class loader to be used for the switched context schema node.
+ *
+ * @param curLoader current context class loader
+ * @param context switched context
+ * @param reg schema registry
+ * @return class loader to be used for the switched context schema node
+ */
+ static ClassLoader getTargetClassLoader(ClassLoader curLoader,
+ YangSchemaNodeContextInfo context,
+ DefaultYangModelRegistry
+ reg) {
+ YangSchemaNode augmentSchemaNode = context.getContextSwitchedNode();
+ if (augmentSchemaNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
+ YangSchemaNode moduleNode = ((YangNode) augmentSchemaNode).getParent();
+
+ Class<?> moduleClass = reg.getRegisteredClass(moduleNode);
+ if (moduleClass == null) {
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_CLASS + moduleNode
+ .getJavaClassNameOrBuiltInType());
+ }
+ return moduleClass.getClassLoader();
+ }
+ return curLoader;
+ }
+
+ /**
+ * Returns the qualified default / op param class.
+ *
+ * @param schemaNode schema node of the required class
+ * @return qualified default / op param class name
+ */
+ static String getQualifiedDefaultClass(YangSchemaNode schemaNode) {
+ String packageName = schemaNode.getJavaPackage();
+ String className = getCapitalCase(
+ schemaNode.getJavaClassNameOrBuiltInType());
+
+ if (schemaNode instanceof RpcNotificationContainer) {
+ return packageName + PERIOD + className + OP_PARAM;
+ }
+
+ return packageName + PERIOD + DEFAULT + className;
+ }
+
+ /**
+ * Returns the qualified interface name.
+ *
+ * @param schemaNode schema node of the required class
+ * @return qualified interface name
+ */
+ static String getQualifiedinterface(YangSchemaNode schemaNode) {
+ String packageName = schemaNode.getJavaPackage();
+ String className = getCapitalCase(
+ schemaNode.getJavaClassNameOrBuiltInType());
+
+ return packageName + PERIOD + className;
+ }
+
+ /**
+ * Returns the capital cased first letter of the given string.
+ *
+ * @param name string to be capital cased
+ * @return capital cased string
+ */
+ static String getCapitalCase(String name) {
+ return name.substring(0, 1).toUpperCase() +
+ name.substring(1);
+ }
+
+ /**
+ * To set data into parent setter method from string value for identity ref.
+ *
+ * @param parentSetterMethod the parent setter method to be invoked
+ * @param parentObject the parent build object on which to invoke
+ * the method
+ * @param leafValue leaf value to be set
+ * @param schemaNode schema information
+ * @throws InvocationTargetException if method could not be invoked
+ * @throws IllegalAccessException if method could not be accessed
+ * @throws NoSuchMethodException if method does not exist
+ */
+ static void parseIdentityRefInfo(Method parentSetterMethod,
+ Object parentObject,
+ Object leafValue,
+ YangSchemaNode schemaNode)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ Class<?> childSetClass = null;
+ Object childValue = null;
+ Method childMethod = null;
+
+ while (schemaNode.getReferredSchema() != null) {
+ schemaNode = schemaNode.getReferredSchema();
+ }
+
+ String qualifiedClassName;
+ YangType type;
+ if (schemaNode instanceof YangLeaf) {
+ type = ((YangLeaf) schemaNode).getDataType();
+ } else {
+ type = ((YangLeafList) schemaNode).getDataType();
+ }
+
+ YangIdentityRef identityRef = null;
+ YangIdentity derivedId;
+ if (type.getDataType() == YangDataTypes.LEAFREF && schemaNode
+ .getJavaPackage().equals(YobConstants.JAVA_LANG)) {
+ YangLeafRef leafref = ((YangLeafRef) type.getDataTypeExtendedInfo());
+ YangType effectiveType = leafref.getEffectiveDataType();
+ if (effectiveType.getDataType() == YangDataTypes.IDENTITYREF) {
+ identityRef = ((YangIdentityRef) effectiveType
+ .getDataTypeExtendedInfo());
+ }
+ } else {
+ identityRef = ((YangIdentityRef) type.getDataTypeExtendedInfo());
+ }
+
+ derivedId = getDerivedIdentity(leafValue.toString(), identityRef
+ .getReferredIdentity());
+ if (derivedId == null) {
+ throw new ModelConvertorException(E_INVALID_IDENTITY_DATA);
+ }
+ qualifiedClassName = derivedId.getJavaPackage() + PERIOD +
+ getCapitalCase(derivedId.getJavaClassNameOrBuiltInType());
+ ClassLoader classLoader = parentObject.getClass().getClassLoader();
+ try {
+ childSetClass = classLoader.loadClass(qualifiedClassName);
+ } catch (ClassNotFoundException e) {
+ log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+ }
+
+ if (childSetClass != null) {
+ childMethod = childSetClass
+ .getDeclaredMethod(FROM_STRING, String.class);
+ }
+
+ if (childMethod != null) {
+ childValue = childMethod.invoke(null, leafValue);
+ }
+
+ parentSetterMethod.invoke(parentObject, childValue);
+ }
+
+ /**
+ * Returns schema node for given data node.
+ *
+ * @param dataNode data node
+ * @param context schema context
+ * @return child schema node
+ */
+ static YangSchemaNode getChildSchemaNode(DataNode dataNode,
+ SchemaContext context) {
+ SchemaId schemaId = dataNode.key().schemaId();
+ SchemaContext schemaContext = getChildSchemaContext(context,
+ schemaId.name(),
+ schemaId.namespace());
+ return ((YangSchemaNode) schemaContext);
+ }
+
+ /**
+ * Builds leaf model object.
+ *
+ * @param dataNode data node
+ * @param leafHolder schema context
+ * @param reg YANG model registry
+ * @return leaf model object
+ */
+ static ModelObject buildLeafModelObject(DataNode dataNode,
+ YangSchemaNode leafHolder,
+ DefaultYangModelRegistry reg) {
+ if (leafHolder == null) {
+ YangSchemaNode schemaNode = ((YangSchemaNode) reg
+ .getChildContext(dataNode.key().schemaId()));
+ if (schemaNode instanceof YangLeaf) {
+ leafHolder = ((YangSchemaNode) ((YangLeaf) schemaNode)
+ .getContainedIn());
+ } else {
+ leafHolder = ((YangSchemaNode) ((YangLeafList) schemaNode)
+ .getContainedIn());
+ }
+ }
+ LeafModelObject leafObj = new LeafModelObject();
+ leafObj.addValue(((LeafNode) dataNode).value());
+ LeafIdentifier leafId = getLeafIdentifier(dataNode.key().schemaId(),
+ leafHolder, reg);
+ leafObj.leafIdentifier(leafId);
+ return leafObj;
+ }
+
+ /**
+ * Returns leaf identifier of the leaf.
+ *
+ * @param id schema id class loader
+ * @param leafHolder parent of leaf
+ * @param reg YANG model registry
+ * @return leaf identifier of the leaf
+ */
+ static LeafIdentifier getLeafIdentifier(SchemaId id,
+ YangSchemaNode leafHolder,
+ DefaultYangModelRegistry
+ reg) {
+ String qualName = getQualifiedDefaultClass(leafHolder);
+ ClassLoader classLoader = getClassLoader(leafHolder, reg);
+ try {
+ Class<InnerModelObject> cls = (Class<InnerModelObject>) classLoader
+ .loadClass(qualName);
+ Class<?>[] intfs = cls.getInterfaces();
+ Class<?> intf = null;
+ for (Class<?> in : intfs) {
+ if (in.getName()
+ .equals(getJavaQualifiedInterFaceName(leafHolder))) {
+ intf = in;
+ break;
+ }
+ }
+ String leafId;
+ if (intf != null) {
+ leafId = intf.getName() + ENUM_LEAF_IDENTIFIER;
+ } else {
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS);
+ }
+
+ Class<Enum> leafIdentifier =
+ (Class<Enum>) cls.getClassLoader().loadClass(leafId);
+ Enum[] enumConst = leafIdentifier.getEnumConstants();
+ for (Enum e : enumConst) {
+ if (e.name().equalsIgnoreCase(id.name())) {
+ return ((LeafIdentifier) e);
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_CLASS);
+ }
+ return null;
+ }
+
+ /**
+ * Returns class.
+ *
+ * @param loader class loader
+ * @param name class name
+ * @return java class
+ */
+ static Class<?> fetchClassForNode(ClassLoader loader, String name) {
+ try {
+ return loader.loadClass(name);
+ } catch (ClassNotFoundException e) {
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_CLASS + name);
+ }
+ }
+
+ /**
+ * Returns instance of class.
+ *
+ * @param loader class loader
+ * @param name class name
+ * @return instance of class
+ */
+ static Object getInstanceOfClass(ClassLoader loader, String name) {
+ try {
+ Class<?> defaultClass = loader.loadClass(name);
+ return defaultClass.newInstance();
+ } catch (ClassNotFoundException e) {
+ log.error(L_FAIL_TO_LOAD_CLASS, name);
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_CLASS + name);
+ } catch (NullPointerException e) {
+ log.error(L_REFLECTION_FAIL_TO_CREATE_OBJ, name);
+ throw new ModelConvertorException(E_REFLECTION_FAIL_TO_CREATE_OBJ +
+ name);
+ } catch (InstantiationException | IllegalAccessException e) {
+ log.error(L_FAIL_TO_CREATE_OBJ, name);
+ throw new ModelConvertorException(E_FAIL_TO_CREATE_OBJ + name);
+ }
+ }
+
+ /**
+ * Returns java class name.
+ *
+ * @param node YANG node
+ * @return java class name
+ */
+ static String getJavaQualifiedInterFaceName(YangSchemaNode node) {
+ if (node != null) {
+ return node.getJavaPackage() + PERIOD
+ + getCapitalCase(node.getJavaClassNameOrBuiltInType());
+ }
+ return null;
+ }
+
+ /**
+ * Returns key class name.
+ *
+ * @param node schema node
+ * @return key class name
+ */
+ static String getKeyClassName(YangSchemaNode node) {
+ if (node != null) {
+ return getJavaQualifiedInterFaceName(node) + "Keys";
+ }
+ return null;
+ }
+
+ /**
+ * Returns key leaf schema.
+ *
+ * @param keyleaf key leaf
+ * @return node YANG schema node
+ */
+ static YangLeaf getKeyLeafSchema(KeyLeaf keyleaf, YangSchemaNode
+ node) {
+ YangList list = ((YangList) node);
+ List<YangLeaf> keyLeaves = list.getListOfLeaf();
+ Iterator<YangLeaf> it = keyLeaves.iterator();
+ while (it.hasNext()) {
+ YangLeaf leaf = it.next();
+ if (leaf.getName().equals(keyleaf.leafSchema().name())) {
+ return leaf;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Adds list node key to model object id builder.
+ *
+ * @param midb model object identifier
+ * @param reg model registry
+ * @param node YANG node
+ * @param key node key
+ * @return model object id builder
+ */
+ static <T extends InnerModelObject & MultiInstanceObject<K>,
+ K extends KeyInfo<T>> ModelObjectId.Builder handleListKey(
+ ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
+ YangSchemaNode node, NodeKey key) {
+ ListKey listKey = (ListKey) key;
+ List<KeyLeaf> keyLeaves = listKey.keyLeafs();
+ String keyClassName;
+ Class<KeyInfo> keyClass;
+ Object value;
+ String javaName = null;
+ Method setter;
+ if (nonEmpty(keyLeaves)) {
+ String qualName = getQualifiedDefaultClass(node);
+ ClassLoader classLoader = getClassLoader(node, reg);
+ Class<T> listClass = ((Class<T>) fetchClassForNode(classLoader,
+ qualName));
+ K keyObj;
+ if (listClass != null) {
+ keyClassName = getKeyClassName(node);
+ try {
+ keyClass = (Class<KeyInfo>) listClass.getClassLoader()
+ .loadClass(keyClassName);
+ keyObj = (K) keyClass.newInstance();
+ for (KeyLeaf leaf : keyLeaves) {
+ YangLeaf leafSchema = getKeyLeafSchema(leaf, node);
+ YangDataTypes datatype = leafSchema.getDataType()
+ .getDataType();
+ javaName = getCamelCase(leaf.leafSchema().name(), null);
+ Field leafName = keyClass.getDeclaredField(javaName);
+ setter = keyClass.getDeclaredMethod(javaName,
+ leafName.getType());
+ value = leaf.leafValue();
+ setDataFromStringValue(datatype,
+ value, setter, keyObj,
+ leafSchema, node);
+ midb = midb.addChild(listClass, keyObj);
+ }
+ } catch (NoSuchMethodException e) {
+ throw new ModelConvertorException(
+ "Failed to load setter method for " +
+ javaName + " in key class"
+ + keyClassName);
+ } catch (InvocationTargetException e) {
+ throw new ModelConvertorException(
+ "Failed to invoke setter method for " +
+ javaName + " in key class"
+ + keyClassName);
+ } catch (ClassNotFoundException e) {
+ throw new ModelConvertorException("Failed to load key class"
+ + keyClassName);
+ } catch (IllegalAccessException | InstantiationException e) {
+ throw new ModelConvertorException("Failed Instantiation of key class"
+ + keyClassName);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return midb;
+ }
+
+ /**
+ * Adds leaf list node key to model object id builder.
+ *
+ * @param midb model object identifier
+ * @param reg model registry
+ * @param schemaNode leaf schema node
+ * @return model object id builder
+ */
+ static ModelObjectId.Builder handleLeafListKey(
+ ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
+ YangSchemaNode schemaNode, LeafListKey key) {
+ Class<?> intf = null;
+ YangSchemaNode parentSchema = ((YangSchemaNode) ((YangLeafList)
+ schemaNode).getContainedIn());
+ String qualName = getQualifiedDefaultClass(parentSchema);
+ ClassLoader classLoader = getClassLoader(parentSchema, reg);
+ Class<?> parentClass = fetchClassForNode(classLoader, qualName);
+ Class<?>[] interfaces = parentClass.getInterfaces();
+ for (Class<?> in : interfaces) {
+ if (in.getName().equals(getJavaQualifiedInterFaceName(parentSchema))) {
+ intf = in;
+ break;
+ }
+ }
+ String leafName;
+ if (intf != null) {
+ leafName = intf.getName() + ENUM_LEAF_IDENTIFIER;
+ try {
+ Class<Enum> leafId =
+ (Class<Enum>) parentClass.getClassLoader()
+ .loadClass(leafName);
+ Enum[] enumConst = leafId.getEnumConstants();
+ for (Enum e : enumConst) {
+ if (e.name().equalsIgnoreCase(key.schemaId().name())) {
+ midb = midb.addChild(((LeafIdentifier) e), key.value());
+ return midb;
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ throw new ModelConvertorException("Failed to load leaf identifier class." +
+ leafName);
+ }
+ }
+ return midb;
+ }
+
+
+ /**
+ * Adds node key for container node or single instance nodes to model
+ * object id builder.
+ *
+ * @param midb model object identifier builder
+ * @param reg model registry
+ * @param node YANG node
+ * @param key node key
+ * @return model object builder with single instance node
+ */
+ static ModelObjectId.Builder handleNodeKey(
+ ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
+ YangSchemaNode node, NodeKey key) {
+ if (node != null) {
+ if (!(node instanceof YangLeaf)) {
+ String qualName = getQualifiedDefaultClass(node);
+ ClassLoader classLoader = getClassLoader(node, reg);
+ Class<InnerModelObject> nodeClass = (Class<InnerModelObject>)
+ fetchClassForNode(classLoader, qualName);
+ if (nodeClass != null) {
+ midb = midb.addChild(nodeClass);
+ }
+ } else {
+ midb = handleLeafInfo(midb, reg, key, node);
+ }
+ }
+ return midb;
+ }
+
+ /**
+ * Adds node key for leaf node to model object id builder.
+ *
+ * @param midb model object identifier builder
+ * @param reg model registry
+ * @param schemaNode YANG schema node
+ * @return model object builder with single instance node
+ */
+ static ModelObjectId.Builder handleLeafInfo(
+ ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
+ NodeKey key, YangSchemaNode schemaNode) {
+ YangSchemaNode parentSchema = ((YangSchemaNode) ((YangLeaf) schemaNode)
+ .getContainedIn());
+ String qualName = getQualifiedDefaultClass(parentSchema);
+ ClassLoader classLoader = getClassLoader(parentSchema, reg);
+ Class<InnerModelObject> nodeClass = (Class<InnerModelObject>)
+ fetchClassForNode(classLoader, qualName);
+ Class<?>[] interfaces = nodeClass.getInterfaces();
+ for (Class<?> intf : interfaces) {
+ String leafId = intf.getName() + ENUM_LEAF_IDENTIFIER;
+ try {
+ Class<Enum> leafIdentifier =
+ (Class<Enum>) nodeClass.getClassLoader()
+ .loadClass(leafId);
+ Enum[] enumConst = leafIdentifier.getEnumConstants();
+ for (Enum e : enumConst) {
+ if (e.name().equalsIgnoreCase(key.schemaId().name())) {
+ midb = midb.addChild(((LeafIdentifier) e));
+ return midb;
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ throw new ModelConvertorException(E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS);
+ }
+ }
+ return midb;
+ }
+
+ /**
+ * Returns derived identity based on the leaf value.
+ *
+ * @param value leaf value
+ * @param referredId referred identity of leaf
+ * @return derived identity
+ */
+ static YangIdentity getDerivedIdentity(String value,
+ YangIdentity referredId) {
+ if (referredId.getJavaClassNameOrBuiltInType().equalsIgnoreCase(value)) {
+ return referredId;
+ }
+
+ List<YangIdentity> extendList = referredId.getExtendList();
+ if (extendList != null && !extendList.isEmpty()) {
+ for (YangIdentity identity : extendList) {
+ if (identity.getYangSchemaNodeIdentifier().getName()
+ .equalsIgnoreCase(value)) {
+ return identity;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobWorkBench.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobWorkBench.java
new file mode 100644
index 0000000..8d63640
--- /dev/null
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/YobWorkBench.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yang.compiler.datamodel.exceptions.DataModelException;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.InnerModelObject;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
+import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_CHOICE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
+import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
+import static org.onosproject.yang.runtime.impl.YobConstants.ADD_AUGMENT_METHOD;
+import static org.onosproject.yang.runtime.impl.YobConstants.ADD_TO;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_GET_FIELD;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_GET_METHOD;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yang.runtime.impl.YobConstants.E_HAS_NO_CHILD;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_GET_FIELD;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_GET_METHOD;
+import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yang.runtime.impl.YobUtils.getCapitalCase;
+import static org.onosproject.yang.runtime.impl.YobUtils.getInstanceOfClass;
+import static org.onosproject.yang.runtime.impl.YobUtils.getQualifiedDefaultClass;
+
+/**
+ * Represents the YANG object builder's work bench corresponding to a YANG data
+ * tree node.
+ */
+class YobWorkBench {
+
+ private static final Logger log =
+ LoggerFactory.getLogger(YobWorkBench.class);
+
+ /**
+ * Class loader to be used to load the class.
+ */
+ private ClassLoader classLoader;
+
+ /**
+ * Map of the non schema descendant objects.
+ */
+ private Map<YangSchemaNodeIdentifier, YobWorkBench> attributeMap =
+ new HashMap<>();
+
+ /**
+ * Built object.
+ */
+ private Object builtObject;
+
+ /**
+ * Setter method to be used in parent.
+ */
+ private String setterInParent;
+
+ /**
+ * YANG schema node.
+ */
+ private YangSchemaNode schemaNode;
+
+ /**
+ * Creates an instance of YANG object builder.
+ *
+ * @param classLoader class loader
+ * @param builtObject YANG object built
+ * @param setterInParent setter method in parent
+ * @param schemaNode YANG schema node
+ */
+ YobWorkBench(ClassLoader classLoader,
+ Object builtObject, String setterInParent,
+ YangSchemaNode schemaNode) {
+ this.classLoader = classLoader;
+ this.setterInParent = setterInParent;
+ this.builtObject = builtObject;
+ this.schemaNode = schemaNode;
+ }
+
+ /**
+ * Returns the class loader.
+ *
+ * @return class loader
+ */
+ ClassLoader classLoader() {
+ return classLoader;
+ }
+
+ /**
+ * Sets the class loader.
+ *
+ * @param loader class loader
+ */
+ void classLoader(ClassLoader loader) {
+ classLoader = loader;
+ }
+
+ /**
+ * Returns the setter method name.
+ *
+ * @return setter method name
+ */
+ String setterInParent() {
+ return setterInParent;
+ }
+
+ /**
+ * Sets the setter method name.
+ *
+ * @param name setter method name
+ */
+ void setterInParent(String name) {
+ setterInParent = name;
+ }
+
+ /**
+ * Returns the YANG scheme node.
+ *
+ * @return YANG schema node
+ */
+ YangSchemaNode schemaNode() {
+ return schemaNode;
+ }
+
+ /**
+ * Sets the YANG schema node.
+ *
+ * @param node YANG schema node
+ */
+ void schemaNode(YangSchemaNode node) {
+ schemaNode = node;
+ }
+
+ /**
+ * Returns the attribute map.
+ *
+ * @return attribute map
+ */
+ Map<YangSchemaNodeIdentifier, YobWorkBench> attributeMap() {
+ return attributeMap;
+ }
+
+ /**
+ * Sets the attribute map.
+ *
+ * @param attributeMap map of the non schema descendant objects
+ */
+ void attributeMap(Map<YangSchemaNodeIdentifier, YobWorkBench>
+ attributeMap) {
+ this.attributeMap = attributeMap;
+ }
+
+ /**
+ * Returns the built object.
+ *
+ * @return built object
+ */
+ Object getBuiltObject() {
+ return builtObject;
+ }
+
+ /**
+ * Sets the built object.
+ *
+ * @param obj built object
+ */
+ void setBuiltObject(Object obj) {
+ builtObject = obj;
+ }
+
+ /**
+ * Sets the model object of data node in parent object.
+ *
+ * @param curWb YOB work bench for data node
+ * @param dataNode data node
+ * @param reg YANG model registry
+ */
+ void setObject(YobWorkBench curWb, DataNode dataNode,
+ DefaultYangModelRegistry reg) {
+ Object parentObj = getParentObject(reg, curWb.schemaNode());
+ setObjectInParent(parentObj, curWb.setterInParent(),
+ curWb.getBuiltObject(), dataNode.type());
+ }
+
+ /**
+ * Sets the model object of data node in parent object.
+ *
+ * @param parentObj parent object
+ * @param setter setter method name
+ * @param curObj current object
+ * @param type data node type
+ */
+ private static void setObjectInParent(Object parentObj, String setter,
+ Object curObj, DataNode.Type type) {
+ Class<?> parentClass = parentObj.getClass();
+ String parentClassName = parentClass.getName();
+ try {
+ Class<?> classType = null;
+ Field fieldName = parentClass.getDeclaredField(setter);
+ if (fieldName != null) {
+ classType = fieldName.getType();
+ }
+
+ Method method;
+ if (type == MULTI_INSTANCE_NODE) {
+ if (fieldName != null) {
+ ParameterizedType genericTypes =
+ (ParameterizedType) fieldName.getGenericType();
+ classType = (Class<?>) genericTypes.getActualTypeArguments()[0];
+ }
+ method = parentClass
+ .getDeclaredMethod(ADD_TO + getCapitalCase(setter), classType);
+ } else {
+ method = parentClass.getDeclaredMethod(setter, classType);
+ }
+
+ method.invoke(parentObj, curObj);
+ } catch (NoSuchFieldException e) {
+ log.error(L_FAIL_TO_GET_FIELD, parentClassName);
+ throw new ModelConvertorException(E_FAIL_TO_GET_FIELD + parentClassName);
+ } catch (NoSuchMethodException e) {
+ log.error(L_FAIL_TO_GET_METHOD, parentClassName);
+ throw new ModelConvertorException(E_FAIL_TO_GET_METHOD + parentClassName);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ log.error(L_FAIL_TO_INVOKE_METHOD, parentClassName);
+ throw new ModelConvertorException(E_FAIL_TO_INVOKE_METHOD + parentClassName);
+ }
+ }
+
+ /**
+ * Returns the parent builder object in which the child object can be set.
+ *
+ * @param reg YANG model registry
+ * @param schemaNode descendant schema node for whom the builder is
+ * required
+ * @return parent builder object
+ */
+ Object getParentObject(DefaultYangModelRegistry reg,
+ YangSchemaNode schemaNode) {
+
+ YangSchemaNodeIdentifier targetNode =
+ schemaNode.getYangSchemaNodeIdentifier();
+
+ YobWorkBench curWorkBench = this;
+ YangSchemaNode nonSchemaHolder;
+ do {
+
+ //Current Schema node context
+ YangSchemaNodeContextInfo schemaContext;
+ YangSchemaNode parentSchema = null;
+ try {
+ //Find the new schema context node.
+ parentSchema = curWorkBench.schemaNode();
+ schemaContext = parentSchema.getChildSchema(targetNode);
+
+ } catch (DataModelException e) {
+ throw new ModelConvertorException(parentSchema.getName() +
+ E_HAS_NO_CHILD +
+ targetNode.getName());
+ }
+
+ nonSchemaHolder = schemaContext.getContextSwitchedNode();
+
+ //If the descendant schema node is in switched context
+ if (nonSchemaHolder != null) {
+
+ YangSchemaNodeIdentifier nonSchemaIdentifier =
+ nonSchemaHolder.getYangSchemaNodeIdentifier();
+
+ //check if the descendant builder container is already available
+ YobWorkBench childWorkBench =
+ curWorkBench.attributeMap.get(nonSchemaIdentifier);
+
+ if (childWorkBench == null) {
+ YobWorkBench newWorkBench = getNewChildWorkBench(
+ schemaContext, targetNode, curWorkBench, reg);
+
+ curWorkBench.attributeMap.put(nonSchemaIdentifier,
+ newWorkBench);
+ curWorkBench = newWorkBench;
+ } else {
+ curWorkBench = childWorkBench;
+ }
+ }
+
+ } while (nonSchemaHolder != null);
+ return curWorkBench.getBuiltObject();
+ }
+
+ /**
+ * Creates a new builder container object corresponding to a context
+ * switch schema node.
+ *
+ * @param childContext schema context of immediate child
+ * @param targetNode final node whose parent builder is
+ * required
+ * @param curWorkBench current context builder container
+ * @param registry model registry
+ * @return new builder container object corresponding to a context
+ * switch schema node
+ */
+ static YobWorkBench getNewChildWorkBench(
+ YangSchemaNodeContextInfo childContext,
+ YangSchemaNodeIdentifier targetNode, YobWorkBench curWorkBench,
+ DefaultYangModelRegistry registry) {
+
+ YangSchemaNode ctxSwitchedNode = childContext.getContextSwitchedNode();
+ String name;
+
+ /* This is the first child trying to set its object in the
+ current context. */
+ String setterInParent = ctxSwitchedNode.getJavaAttributeName();
+
+ /* If current switched context is choice, then case class needs to be
+ used. */
+ if (ctxSwitchedNode.getYangSchemaNodeType() == YANG_CHOICE_NODE) {
+ try {
+ childContext = ctxSwitchedNode.getChildSchema(targetNode);
+ ctxSwitchedNode = childContext.getContextSwitchedNode();
+ name = getQualifiedDefaultClass(
+ childContext.getContextSwitchedNode());
+
+ } catch (DataModelException e) {
+ throw new ModelConvertorException(ctxSwitchedNode.getName() +
+ E_HAS_NO_CHILD +
+ targetNode.getName());
+ }
+ } else if (ctxSwitchedNode.getYangSchemaNodeType() ==
+ YANG_AUGMENT_NODE) {
+ name = getQualifiedDefaultClass(ctxSwitchedNode);
+ setterInParent = YobUtils.getQualifiedinterface(ctxSwitchedNode);
+ } else {
+ name = getQualifiedDefaultClass(childContext.getSchemaNode());
+ }
+
+ ClassLoader newClassesLoader = YobUtils.getTargetClassLoader(
+ curWorkBench.classLoader, childContext, registry);
+
+ Object obj = getInstanceOfClass(newClassesLoader, name);
+ return new YobWorkBench(newClassesLoader, obj, setterInParent,
+ ctxSwitchedNode);
+ }
+
+ static void addInAugmentation(Object builder,
+ Object instance) {
+ Class<?> builderClass = builder.getClass();
+ Class<?> baseClass = builderClass.getSuperclass();
+ try {
+ Method method = baseClass.getDeclaredMethod(ADD_AUGMENT_METHOD,
+ InnerModelObject.class);
+ method.invoke(builder, instance);
+ } catch (NoSuchMethodException e) {
+ log.error(L_FAIL_TO_GET_METHOD, ADD_AUGMENT_METHOD);
+ throw new ModelConvertorException(E_FAIL_TO_GET_METHOD + ADD_AUGMENT_METHOD);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ log.error(L_FAIL_TO_INVOKE_METHOD, ADD_AUGMENT_METHOD);
+ throw new ModelConvertorException(E_FAIL_TO_INVOKE_METHOD + ADD_AUGMENT_METHOD);
+ }
+ }
+
+ /**
+ * Builds the non schema objects and maintain it in the contained schema
+ * node.
+ *
+ * @param reg YANG model registry
+ */
+ void buildNonSchemaAttributes(YangModelRegistry reg) {
+
+ for (Map.Entry<YangSchemaNodeIdentifier, YobWorkBench> entry :
+ attributeMap.entrySet()) {
+ YobWorkBench childWorkBench = entry.getValue();
+ YangSchemaNode childSchema = childWorkBench.schemaNode();
+ childWorkBench.buildObject(reg);
+
+ if (childSchema.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
+ addInAugmentation(builtObject,
+ childWorkBench.getBuiltObject());
+ continue;
+ }
+
+ setObjectInParent(builtObject, childWorkBench.setterInParent,
+ childWorkBench.getBuiltObject(), SINGLE_INSTANCE_NODE);
+ }
+ }
+
+ /**
+ * Set the operation type attribute and build the object from the builder
+ * object, by invoking the build method.
+ *
+ * @param reg YANG model registry
+ */
+ void buildObject(YangModelRegistry reg) {
+ buildNonSchemaAttributes(reg);
+ }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
new file mode 100644
index 0000000..3572f0c
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobAugmentTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.rev20151208.yrtietfnetwork.DefaultNetworks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.rev20151208.yrtietfnetwork.networks.DefaultNetwork;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.rev20151208.yrtietfnetwork.networks.Network;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.topology.rev20151208.yrtnetworktopology.networks.network.DefaultAugmentedNdNetwork;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.topology.rev20151208.yrtnetworktopology.networks.network.augmentedndnetwork.DefaultLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.topology.rev20151208.yrtnetworktopology.networks.network.augmentedndnetwork.Link;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.networks.network.link.DefaultAugmentedNtLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.telinkaugment.te.Config;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.telinkconfig.bundlestacklevel.Bundle;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.telinkconfig.bundlestacklevel.bundle.bundledlinks.BundledLink;
+import org.onosproject.yang.gen.v1.urn.ip.topo.rev20140101.ymsiptopology.node.DefaultAugmentedTopoNode;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.DefaultNode;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeDataNode;
+
+/**
+ * Tests the YANG object building for the YANG data nodes based on the non
+ * schema augmented nodes.
+ */
+public class YobAugmentTest {
+ private static final String TOPO_NAME_SPACE = "urn:topo";
+ private static final String IP_TOPO_NAME_SPACE = "urn:ip:topo";
+ private static final String NW_NAME_SPACE = "urn:ietf:params:xml:ns:yang:yrt-ietf-network";
+ private static final String NW_TOPO_NAME_SPACE = "urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology";
+ private static final String TE_TOPO_NAME_SPACE =
+ "urn:ietf:params:xml:ns:yang:yrt-ietf-te-topology";
+ TestYangSerializerContext context = new TestYangSerializerContext();
+ DataNode.Builder dBlr;
+ String value;
+
+ public DataNode buildDataNodeForAugmentedLeaves() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "node", TOPO_NAME_SPACE, value, null);
+
+ value = "id";
+ dBlr = addDataNode(dBlr, "node-id", TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str1";
+ dBlr = addDataNode(dBlr, "router-id", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str2";
+ dBlr = addDataNode(dBlr, "router-ip", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+ public DataNode buildDnForAugmentedList() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "networks", NW_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "network", NW_NAME_SPACE, value, null);
+ value = "network-id";
+ dBlr = addDataNode(dBlr, "network-id", NW_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "link", NW_TOPO_NAME_SPACE, value, null);
+ value = "link-id";
+ dBlr = addDataNode(dBlr, "link-id", NW_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "source", NW_TOPO_NAME_SPACE, value, null);
+ value = "source-node";
+ dBlr = addDataNode(dBlr, "source-node", NW_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr); // exit source
+ dBlr = exitDataNode(dBlr); // exit link
+ dBlr = exitDataNode(dBlr); // exit network
+ dBlr = exitDataNode(dBlr); // exit networks
+ return dBlr.build();
+ }
+
+ public DataNode buildDnForAugmentedListWithResourceId() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "node", TOPO_NAME_SPACE, value, null);
+
+ value = "id";
+ dBlr = addDataNode(dBlr, "node-id", TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str1";
+ dBlr = addDataNode(dBlr, "router-id", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str2";
+ dBlr = addDataNode(dBlr, "router-ip", IP_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+ public DataNode buildDnForChoiceCase() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "networks", NW_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "network", NW_NAME_SPACE, value, null);
+ value = "network-id";
+ dBlr = addDataNode(dBlr, "network-id", NW_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "link", NW_TOPO_NAME_SPACE, value, null);
+ value = "link-id";
+ dBlr = addDataNode(dBlr, "link-id", NW_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "te", TE_TOPO_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "config", TE_TOPO_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "bundled-links", TE_TOPO_NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "bundled-link", TE_TOPO_NAME_SPACE, value, null);
+ value = "100";
+ dBlr = addDataNode(dBlr, "sequence", TE_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr); // exit sequence
+ value = "101";
+ dBlr = addDataNode(dBlr, "src-tp-ref", TE_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr); // exit src-tp-ref
+ dBlr = exitDataNode(dBlr); // exit list bundled-link
+ dBlr = exitDataNode(dBlr); // exit bundled-links
+ value = "abc";
+ dBlr = addDataNode(dBlr, "te-link-template", TE_TOPO_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr); // te-link-template
+ dBlr = exitDataNode(dBlr); // config
+ dBlr = exitDataNode(dBlr); // te
+ dBlr = exitDataNode(dBlr); // exit link
+ dBlr = exitDataNode(dBlr); // exit network
+ dBlr = exitDataNode(dBlr); // exit networks
+ return dBlr.build();
+ }
+
+ @Test
+ public void augmentedLeaf() {
+ DataNode dataNode = buildDataNodeForAugmentedLeaves();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultNode node = ((DefaultNode) modelObject);
+ assertThat(node.nodeId(), is("id"));
+ DefaultAugmentedTopoNode obj = node
+ .augmentation(DefaultAugmentedTopoNode.class);
+ assertThat(obj.routerId(), is("str1"));
+ assertThat(obj.routerIp(), is("str2"));
+ }
+
+ @Test
+ public void augmentedList() {
+ DataNode dataNode = buildDnForAugmentedList();
+ ResourceData data = DefaultResourceData.builder()
+ .addDataNode(dataNode).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultNetworks networks = ((DefaultNetworks) modelObject);
+ Network network = networks.network().get(0);
+ assertThat(network.networkId().toString(), is("network-id"));
+ DefaultAugmentedNdNetwork augNw = ((DefaultNetwork) network)
+ .augmentation(DefaultAugmentedNdNetwork.class);
+ Link link = augNw.link().get(0);
+ assertThat(link.linkId().toString(), is("link-id"));
+ assertThat(link.source().sourceNode().toString(), is("source-node"));
+ }
+
+ @Test
+ public void augmentedChoiceCase() {
+ DataNode dataNode = buildDnForChoiceCase();
+ ResourceData data = DefaultResourceData.builder()
+ .addDataNode(dataNode).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultNetworks networks = ((DefaultNetworks) modelObject);
+ Network network = networks.network().get(0);
+ assertThat(network.networkId().toString(), is("network-id"));
+ DefaultAugmentedNdNetwork augNw = ((DefaultNetwork) network)
+ .augmentation(DefaultAugmentedNdNetwork.class);
+ Link link = augNw.link().get(0);
+ assertThat(link.linkId().toString(), is("link-id"));
+ DefaultAugmentedNtLink augLink = ((DefaultLink) link)
+ .augmentation(DefaultAugmentedNtLink.class);
+ Config config = augLink.te().config();
+ assertThat(config.teLinkTemplate().get(0), is("abc"));
+ BundledLink bundledLink = ((Bundle) config.bundleStackLevel())
+ .bundledLinks().bundledLink().get(0);
+ assertThat(bundledLink.srcTpRef(), is("101"));
+ assertThat(bundledLink.sequence(), is(100L));
+ }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobBasicYangConstructTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobBasicYangConstructTest.java
new file mode 100644
index 0000000..be21b0c
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobBasicYangConstructTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.yang.runtime.impl;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.DefaultL1;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.DefaultTop;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.l1.C1;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.top.DefaultYangAutoPrefixInterface;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.top.YangAutoPrefixInterface;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.top.yangautoprefixinterface.Address;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.LeafModelObject;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onosproject.yang.gen.v1.samplenamespace.Sample.LeafIdentifier.LEAF5;
+import static org.onosproject.yang.gen.v1.samplenamespace.Sample.LeafIdentifier.LEAF6;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addToResourceId;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeResourceId;
+
+/**
+ * Tests the YANG object building for the YANG data nodes.
+ */
+public class YobBasicYangConstructTest {
+ private static final String NAME_SPACE = "samplenamespace";
+ TestYangSerializerContext context = new TestYangSerializerContext();
+ private DataNode.Builder dBlr;
+ private String value;
+ private ResourceId.Builder rIdBlr;
+
+ private DataNode buildDataNode() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "top", NAME_SPACE, value, null);
+ value = "100";
+ dBlr = addDataNode(dBlr, "mtu", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "1123";
+ dBlr = addDataNode(dBlr, "color", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "interface", null, value, null);
+ value = "name";
+ dBlr = addDataNode(dBlr, "name", null, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "address", null, value, null);
+ value = "name";
+ dBlr = addDataNode(dBlr, "name", null, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr); // exit address
+ dBlr = exitDataNode(dBlr); // exit interface
+ dBlr = exitDataNode(dBlr); // exit top
+
+ value = null;
+ dBlr = addDataNode(dBlr, "l1", NAME_SPACE, value, null);
+ dBlr = addDataNode(dBlr, "c1", NAME_SPACE, value, null);
+ value = "leaf1_value";
+ dBlr = addDataNode(dBlr, "leaf1", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "leaf2_value";
+ dBlr = addDataNode(dBlr, "leaf2", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr); // exit container c1
+ value = "leaf3_value";
+ dBlr = addDataNode(dBlr, "leaf3", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "leaf4_value";
+ dBlr = addDataNode(dBlr, "leaf4", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr); // exit list l1
+ return dBlr.build();
+ }
+
+ private DataNode buildDnForModuleLevelLeaf() {
+ dBlr = initializeDataNode(context);
+ value = "abc";
+ dBlr = addDataNode(dBlr, "leaf5", NAME_SPACE, value, null);
+ return dBlr.build();
+ }
+
+ private DataNode buildDnForModuleLevelLeafList() {
+ dBlr = initializeDataNode(context);
+ value = "def";
+ dBlr = addDataNode(dBlr, "leaf6", NAME_SPACE, value, null);
+ return dBlr.build();
+ }
+
+ private DataNode buildDataNodeWithResourceIdForL1() {
+ ResourceId.Builder builder = buildResourceId();
+ dBlr = initializeDataNode(builder);
+ dBlr = addDataNode(dBlr, "c1", NAME_SPACE, value, null);
+ value = "leaf1_value";
+ dBlr = addDataNode(dBlr, "leaf1", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "leaf2_value";
+ dBlr = addDataNode(dBlr, "leaf2", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+ private ResourceId.Builder buildResourceIdForContainerTop() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "top", NAME_SPACE, value);
+ return rIdBlr;
+ }
+
+ private DataNode buildDataNodeWithResourceIdForLeafL3() {
+ ResourceId.Builder builder = buildResourceId();
+ dBlr = initializeDataNode(builder);
+ value = "leaf3_value";
+ dBlr = addDataNode(dBlr, "leaf3", NAME_SPACE, value, null);
+ return dBlr.build();
+ }
+
+ private ResourceId.Builder buildResourceId() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "l1", NAME_SPACE, value);
+ return rIdBlr;
+ }
+
+ @Test
+ public void testBasicYangConstruct() throws IOException {
+ DataNode dataNode = buildDataNode();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultTop top = ((DefaultTop) modelObject);
+ assertThat(top.mtu(), is("100"));
+ assertThat(top.color().get(0), is("1123"));
+
+ List<YangAutoPrefixInterface> intfList = top.yangAutoPrefixInterface();
+ YangAutoPrefixInterface intf = intfList.get(0);
+ assertThat(intf.name(), is("name"));
+
+ Address address = intf.address();
+ assertThat(address.name(), is("name"));
+
+ modelObject = modelObjectList.get(1);
+ DefaultL1 l1 = ((DefaultL1) modelObject);
+ C1 c1 = l1.c1();
+ assertThat(c1.leaf1(), is("leaf1_value"));
+ assertThat(c1.leaf2().get(0), is("leaf2_value"));
+ assertThat(l1.leaf3(), is("leaf3_value"));
+ assertThat(l1.leaf4().get(0), is("leaf4_value"));
+ }
+
+ @Test
+ public void testModuleLevelLeaf() throws IOException {
+ DataNode dataNode = buildDnForModuleLevelLeaf();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .build();
+
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ LeafModelObject obj = ((LeafModelObject) modelObject);
+ assertThat(obj.leafIdentifier(), is(LEAF5));
+ assertThat(obj.values().get(0), is("abc"));
+ }
+
+ @Test
+ public void testModuleLevelLeafList() throws IOException {
+ DataNode dataNode = buildDnForModuleLevelLeafList();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .build();
+
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ LeafModelObject obj = ((LeafModelObject) modelObject);
+ assertThat(obj.leafIdentifier(), is(LEAF6));
+ assertThat(obj.values().get(0), is("def"));
+ }
+
+ @Test
+ public void testWithResourceId() {
+ DataNode dataNode = buildDataNodeWithResourceIdForL1();
+ ResourceId.Builder rIdbuilder = buildResourceId();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .addDataNode(buildDataNodeWithResourceIdForLeafL3())
+ .resourceId(rIdbuilder.build()).build();
+
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ C1 c1 = ((C1) modelObject);
+ assertThat(c1.leaf1(), is("leaf1_value"));
+ assertThat(c1.leaf2().get(0), is("leaf2_value"));
+ }
+
+ @Test
+ public void testWithRIdForContainerTop() {
+ ResourceId.Builder builder = buildResourceIdForContainerTop();
+ dBlr = initializeDataNode(builder);
+ value = "mtu";
+ dBlr = addDataNode(dBlr, "mtu", NAME_SPACE, value, null);
+ ResourceData.Builder dataBdlr = DefaultResourceData.builder()
+ .addDataNode(dBlr.build());
+ dBlr = initializeDataNode(builder);
+ value = "color";
+ dBlr = addDataNode(dBlr, "color", NAME_SPACE, value, null);
+ dataBdlr = dataBdlr.addDataNode(dBlr.build());
+ dBlr = initializeDataNode(builder);
+ value = null;
+ dBlr = addDataNode(dBlr, "interface", NAME_SPACE, value, null);
+ value = "name";
+ dBlr = addDataNode(dBlr, "name", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dataBdlr = dataBdlr.addDataNode(dBlr.build()).resourceId(builder.build());
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = yobBuilder.getYangObject(dataBdlr.build());
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ LeafModelObject mtu = ((LeafModelObject) modelObject);
+ assertThat(mtu.values().get(0), is("mtu"));
+ LeafModelObject color = ((LeafModelObject) modelObjectList.get(1));
+ assertThat(color.values().get(0), is("color"));
+ DefaultYangAutoPrefixInterface intf = ((DefaultYangAutoPrefixInterface)
+ modelObjectList.get(2));
+ assertThat(intf.name(), is("name"));
+ }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobChoiceTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobChoiceTest.java
new file mode 100644
index 0000000..a063b8a
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobChoiceTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.telinkconfig.bundlestacklevel.bundle.DefaultBundledLinks;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.DefaultNode;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.node.choice1.Case1a;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.node.choice1.Case1b;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.node.choice1.case1b.choice1b.Case1Bi;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addToResourceId;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeResourceId;
+
+/**
+ * Tests the YANG object building for the YANG data nodes.
+ */
+public class YobChoiceTest {
+
+ private static final String NAME_SPACE = "urn:topo";
+ private static final String NW_NS = "urn:ietf:params:xml:ns:yang:yrt-ietf-network";
+ private static final String TE_NS = "urn:ietf:params:xml:ns:yang:yrt-ietf-te-topology";
+ private static final String NW_TOPO_NS =
+ "urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology";
+ TestYangSerializerContext context = new TestYangSerializerContext();
+ private DataNode.Builder dBlr;
+ private String value;
+ private ResourceId.Builder rIdBlr;
+
+ public DataNode buildDataNodeForCaseInChoice() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "node", NAME_SPACE, value, null);
+
+ value = "id";
+ dBlr = addDataNode(dBlr, "node-id", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str1";
+ dBlr = addDataNode(dBlr, "leaf1a1", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str2";
+ dBlr = addDataNode(dBlr, "leaf1a2", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+ public DataNode buildDataNodeForRecursiveChoice() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "node", NAME_SPACE, value, null);
+
+ value = "id";
+ dBlr = addDataNode(dBlr, "node-id", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str1";
+ dBlr = addDataNode(dBlr, "leaf1bia", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "str2";
+ dBlr = addDataNode(dBlr, "leaf1bib", NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+ private ResourceId.Builder buildRIdForNodeInsideChoiceCase() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "networks", NW_NS, value);
+ rIdBlr = addToResourceId(rIdBlr, "network", NW_NS, value);
+ value = "network-id";
+ rIdBlr = addToResourceId(rIdBlr, "network-id", NW_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "link", NW_TOPO_NS, value);
+ value = "link-id";
+ rIdBlr = addToResourceId(rIdBlr, "link-id", NW_TOPO_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "te", TE_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "config", TE_NS, value);
+ return rIdBlr;
+ }
+
+ public DataNode buildDnForChoiceCaseWithRid() {
+ ResourceId.Builder rIdBdlr = buildRIdForNodeInsideChoiceCase();
+ dBlr = initializeDataNode(rIdBdlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "bundled-links", TE_NS, value, null);
+ return dBlr.build();
+ }
+
+ @Test
+ public void caseInChoice() {
+ DataNode dataNode = buildDataNodeForCaseInChoice();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultNode node = ((DefaultNode) modelObject);
+ assertThat(node.nodeId(), is("id"));
+ assertThat(((Case1a) node.choice1()).leaf1A1(), is("str1"));
+ assertThat(((Case1a) node.choice1()).leaf1A2(), is("str2"));
+ }
+
+ @Test
+ public void recursiveChoice() {
+ DataNode dataNode = buildDataNodeForRecursiveChoice();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultNode node = ((DefaultNode) modelObject);
+ assertThat(node.nodeId(), is("id"));
+ assertThat(((Case1Bi) ((Case1b) node.choice1()).choice1b()).leaf1Bia(),
+ is("str1"));
+ assertThat(((Case1Bi) ((Case1b) node.choice1()).choice1b()).leaf1Bib(),
+ is("str2"));
+ }
+
+ @Test
+ public void testChoiceCaseWithResourceId() {
+ ResourceId.Builder rIdBdlr = buildRIdForNodeInsideChoiceCase();
+ DataNode dataNode = buildDnForChoiceCaseWithRid();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode)
+ .resourceId(rIdBdlr.build()).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ assertThat(modelObject instanceof DefaultBundledLinks, is(true));
+ }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobGroupingUsesTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobGroupingUsesTest.java
new file mode 100644
index 0000000..13dec1a
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobGroupingUsesTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.rev20151208.yrtietfnetwork.DefaultNetworks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.schedule.rev20160301.yrtietfschedule.schedules.schedules.Schedule;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.networks.DefaultAugmentedNwNetworks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.tetopologiesaugment.te.templates.LinkTemplate;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeDataNode;
+
+/**
+ * Tests the YANG object building for the YANG data tree based on the non
+ * schema augmented nodes.
+ */
+public class YobGroupingUsesTest {
+ TestYangSerializerContext context = new TestYangSerializerContext();
+ private static final String NW_NS = "urn:ietf:params:xml:ns:yang:yrt-ietf-network";
+ private static final String TE_NS = "urn:ietf:params:xml:ns:yang:yrt-ietf-te-topology";
+ private DataNode.Builder dBlr;
+ private String value;
+
+
+ public DataNode buildDataNodeForInterFileGrouping() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "networks", NW_NS, value, null);
+ dBlr = addDataNode(dBlr, "te", TE_NS, value, null);
+ dBlr = addDataNode(dBlr, "templates", TE_NS, value, null);
+ dBlr = addDataNode(dBlr, "link-template", TE_NS, value, null);
+ value = "name";
+ dBlr = addDataNode(dBlr, "name", TE_NS, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = null;
+ dBlr = addDataNode(dBlr, "te-link-attributes", TE_NS, value, null);
+ dBlr = addDataNode(dBlr, "schedules", TE_NS, value, null);
+ dBlr = addDataNode(dBlr, "schedule", TE_NS, value, null);
+ value = "100";
+ dBlr = addDataNode(dBlr, "schedule-id", TE_NS, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "start";
+ dBlr = addDataNode(dBlr, "start", TE_NS, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "schedule-duration";
+ dBlr = addDataNode(dBlr, "schedule-duration", TE_NS, value, null);
+ dBlr = exitDataNode(dBlr);
+ value = "repeat-interval";
+ dBlr = addDataNode(dBlr, "repeat-interval", TE_NS, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr); // schedule
+ dBlr = exitDataNode(dBlr); // schedules
+ dBlr = exitDataNode(dBlr); // te-link-attributes
+ dBlr = exitDataNode(dBlr); // link-template
+ dBlr = exitDataNode(dBlr); // templates
+ dBlr = exitDataNode(dBlr); // te
+ dBlr = exitDataNode(dBlr); // networks
+ return dBlr.build();
+ }
+
+ @Test
+ public void testInterFileGrouping() {
+ DataNode dataNode = buildDataNodeForInterFileGrouping();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultNetworks networks = ((DefaultNetworks) modelObject);
+ DefaultAugmentedNwNetworks augNws = networks
+ .augmentation(DefaultAugmentedNwNetworks.class);
+ LinkTemplate linkTmp = augNws.te().templates().linkTemplate().get(0);
+ assertThat(linkTmp.name().toString(), is("name"));
+ Schedule sh = linkTmp.teLinkAttributes().schedules().schedule().get(0);
+ assertThat(sh.scheduleId(), is(100L));
+ assertThat(sh.start().toString(), is("start"));
+ assertThat(sh.scheduleDuration(), is("schedule-duration"));
+ assertThat(sh.repeatInterval(), is("repeat-interval"));
+ }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobRIdToMoIdConverterTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobRIdToMoIdConverterTest.java
new file mode 100644
index 0000000..aa3938f
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobRIdToMoIdConverterTest.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.samplenamespace.Sample;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.DefaultL2;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.DefaultTop;
+import org.onosproject.yang.gen.v1.samplenamespace.sample.L2Keys;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.rev20151208.yrtietfnetwork.DefaultNetworks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.rev20151208.yrtietfnetwork.networks.DefaultNetwork;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.topology.rev20151208.yrtnetworktopology.networks.network.augmentedndnetwork.DefaultLink;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.network.topology.rev20151208.yrtnetworktopology.networks.network.augmentedndnetwork.link.DefaultSource;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.telinkconfig.bundlestacklevel.bundle.DefaultBundledLinks;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.tetopologyaugment.DefaultTe;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.yrt.ietf.te.topology.rev20160317.yrtietftetopology.tetopologyaugment.te.DefaultConfig;
+import org.onosproject.yang.model.AtomicPath;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ModelObjectId;
+import org.onosproject.yang.model.MultiInstanceLeaf;
+import org.onosproject.yang.model.MultiInstanceNode;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.model.SingleInstanceLeaf;
+import org.onosproject.yang.model.SingleInstanceNode;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addToResourceId;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeResourceId;
+
+/**
+ * Tests resource id to model object id convertion.
+ */
+public class YobRIdToMoIdConverterTest {
+ private static final String NAME_SPACE = "samplenamespace";
+ TestYangSerializerContext context = new TestYangSerializerContext();
+ private static final String NW_NS = "urn:ietf:params:xml:ns:yang:yrt-ietf-network";
+ private static final String TE_TOPO_NS =
+ "urn:ietf:params:xml:ns:yang:yrt-ietf-te-topology";
+ private static final String NW_TOPO_NS = "urn:ietf:params:xml:ns:yang:yrt-ietf-network-topology";
+ private String value;
+ private ResourceId.Builder rIdBlr;
+
+ private ResourceId.Builder buildRIdForTopLevelContainer() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "top", NAME_SPACE, value);
+ return rIdBlr;
+ }
+
+ private ResourceId.Builder buildRIdForTopLevelLeaf() {
+ rIdBlr = initializeResourceId(context);
+ value = "null";
+ rIdBlr = addToResourceId(rIdBlr, "leaf5", NAME_SPACE, value);
+ return rIdBlr;
+ }
+
+ private ResourceId.Builder buildRIdForTopLevelLeafList() {
+ rIdBlr = initializeResourceId(context);
+ value = "abc";
+ rIdBlr = addToResourceId(rIdBlr, "leaf6", NAME_SPACE, value);
+ return rIdBlr;
+ }
+
+ private ResourceId.Builder buildRIdForTopLevelList() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "l2", NAME_SPACE, value);
+ value = "abc";
+ rIdBlr = addToResourceId(rIdBlr, "k1", NAME_SPACE, value);
+ return rIdBlr;
+ }
+
+ private ResourceId.Builder buildRIdForGroupingUses() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "networks", NW_NS, value);
+ rIdBlr = addToResourceId(rIdBlr, "network", NW_NS, value);
+ value = "network-id";
+ rIdBlr = addToResourceId(rIdBlr, "network-id", NW_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "te", TE_TOPO_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "config", TE_TOPO_NS, value);
+ return rIdBlr;
+ }
+
+ private ResourceId.Builder buildRIdForNodeInsideChoiceCase() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "networks", NW_NS, value);
+ rIdBlr = addToResourceId(rIdBlr, "network", NW_NS, value);
+ value = "network-id";
+ rIdBlr = addToResourceId(rIdBlr, "network-id", NW_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "link", NW_TOPO_NS, value);
+ value = "link-id";
+ rIdBlr = addToResourceId(rIdBlr, "link-id", NW_TOPO_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "te", TE_TOPO_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "config", TE_TOPO_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "bundled-links", TE_TOPO_NS, value);
+ return rIdBlr;
+ }
+
+ private ResourceId.Builder buildRIdForTopListInsideList() {
+ rIdBlr = initializeResourceId(context);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "networks", NW_NS, value);
+ rIdBlr = addToResourceId(rIdBlr, "network", NW_NS, value);
+ value = "network-id";
+ rIdBlr = addToResourceId(rIdBlr, "network-id", NW_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "link", NW_TOPO_NS, value);
+ value = "link-id";
+ rIdBlr = addToResourceId(rIdBlr, "link-id", NW_TOPO_NS, value);
+ value = null;
+ rIdBlr = addToResourceId(rIdBlr, "source", NW_TOPO_NS, value);
+ return rIdBlr;
+ }
+
+ @Test
+ public void testTopLevelContainer() {
+ ResourceId id = buildRIdForTopLevelContainer().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ SingleInstanceNode l1 = (SingleInstanceNode) atomicPaths.get(0);
+ assertThat(l1.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(l1.container(), (DefaultTop.class));
+ }
+
+ @Test
+ public void testTopLevelLeaf() {
+ ResourceId id = buildRIdForTopLevelLeaf().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ SingleInstanceLeaf leaf5 = (SingleInstanceLeaf) atomicPaths.get(0);
+ assertThat(leaf5.type(), is(DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE));
+ assertEquals(leaf5.leafIdentifier(), Sample.LeafIdentifier.LEAF5);
+ }
+
+ @Test
+ public void testTopLevelLeafList() {
+ ResourceId id = buildRIdForTopLevelLeafList().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ MultiInstanceLeaf leaf6 = (MultiInstanceLeaf) atomicPaths.get(0);
+ assertThat(leaf6.type(), is(DataNode.Type.MULTI_INSTANCE_LEAF_VALUE_NODE));
+ assertEquals(leaf6.leafIdentifier(), Sample.LeafIdentifier.LEAF6);
+ }
+
+ @Test
+ public void testTopLevelList() {
+ ResourceId id = buildRIdForTopLevelList().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ MultiInstanceNode l2 = (MultiInstanceNode) atomicPaths.get(0);
+ assertThat(l2.type(), is(DataNode.Type.MULTI_INSTANCE_NODE));
+ assertEquals(l2.listClass(), DefaultL2.class);
+ assertThat(((L2Keys) l2.key()).k1(), is("abc"));
+ }
+
+ @Test
+ public void testMoIdForListInsideList() {
+ ResourceId id = buildRIdForTopListInsideList().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ SingleInstanceNode network = (SingleInstanceNode) atomicPaths.get(0);
+ assertThat(network.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(network.container(), DefaultNetworks.class);
+ MultiInstanceNode networks = (MultiInstanceNode) atomicPaths.get(1);
+ assertThat(networks.type(), is(DataNode.Type.MULTI_INSTANCE_NODE));
+ assertEquals(networks.listClass(), DefaultNetwork.class);
+ MultiInstanceNode lId = (MultiInstanceNode) atomicPaths.get(2);
+ assertThat(lId.type(), is(DataNode.Type.MULTI_INSTANCE_NODE));
+ assertEquals(lId.listClass(), DefaultLink.class);
+ SingleInstanceNode src = (SingleInstanceNode) atomicPaths.get(3);
+ assertThat(src.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(src.container(), DefaultSource.class);
+ }
+
+ @Test
+ public void testMoIdForGroupingUses() {
+ ResourceId id = buildRIdForGroupingUses().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ SingleInstanceNode network = (SingleInstanceNode) atomicPaths.get(0);
+ assertThat(network.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(network.container(), DefaultNetworks.class);
+ MultiInstanceNode networks = (MultiInstanceNode) atomicPaths.get(1);
+ assertThat(networks.type(), is(DataNode.Type.MULTI_INSTANCE_NODE));
+ assertEquals(networks.listClass(), DefaultNetwork.class);
+ SingleInstanceNode te = (SingleInstanceNode) atomicPaths.get(2);
+ assertThat(te.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(te.container(), DefaultTe.class);
+ SingleInstanceNode config = (SingleInstanceNode) atomicPaths.get(3);
+ assertThat(config.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(config.container(), DefaultConfig.class);
+ }
+
+ @Test
+ public void testMoIdForNodeInsideChoiceCase() {
+ ResourceId id = buildRIdForNodeInsideChoiceCase().build();
+ ResourceData data = DefaultResourceData.builder()
+ .resourceId(id).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ ModelObjectId mId = modelObjectData.identifier();
+ List<AtomicPath> atomicPaths = mId.atomicPaths();
+ SingleInstanceNode network = (SingleInstanceNode) atomicPaths.get(0);
+ assertThat(network.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(network.container(), DefaultNetworks.class);
+ MultiInstanceNode networks = (MultiInstanceNode) atomicPaths.get(1);
+ assertThat(networks.type(), is(DataNode.Type.MULTI_INSTANCE_NODE));
+ assertEquals(networks.listClass(), DefaultNetwork.class);
+ MultiInstanceNode link = (MultiInstanceNode) atomicPaths.get(2);
+ assertThat(link.type(), is(DataNode.Type.MULTI_INSTANCE_NODE));
+ assertEquals(link.listClass(), DefaultLink.class);
+ SingleInstanceNode te = (SingleInstanceNode) atomicPaths.get(3);
+ assertThat(te.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(te.container(), org.onosproject.yang.gen.v1.urn.ietf
+ .params.xml.ns.yang.yrt.ietf.te.topology.rev20160317
+ .yrtietftetopology.telinkaugment.DefaultTe.class);
+ SingleInstanceNode config = (SingleInstanceNode) atomicPaths.get(4);
+ assertThat(config.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(config.container(), org.onosproject.yang.gen.v1.urn.ietf
+ .params.xml.ns.yang.yrt.ietf.te.topology.rev20160317
+ .yrtietftetopology.telinkaugment.te.DefaultConfig.class);
+ SingleInstanceNode bundledlinks = (SingleInstanceNode) atomicPaths
+ .get(5);
+ assertThat(bundledlinks.type(), is(DataNode.Type.SINGLE_INSTANCE_NODE));
+ assertEquals(bundledlinks.container(), DefaultBundledLinks.class);
+ }
+}
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java
new file mode 100644
index 0000000..3c2ba15
--- /dev/null
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/YobSimpleDataTypeTest.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.runtime.impl;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.simple.data.types.ll.rev20131112.simpledatatypesll.DefaultCont1;
+import org.onosproject.yang.gen.v1.simple.data.types.rev20131112.simpledatatypes.DefaultCont;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.runtime.DefaultResourceData;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.addDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.exitDataNode;
+import static org.onosproject.yang.runtime.helperutils.SerializerHelper.initializeDataNode;
+
+/**
+ * Tests the YANG object building for different data types.
+ */
+public class YobSimpleDataTypeTest {
+
+ TestYangSerializerContext context = new TestYangSerializerContext();
+ private static final String DATA_TYPE_NAME_SPACE = "simple:data:types";
+ private static final String DATA_TYPE_NAME_SPACE_LL =
+ "simple:data:types:ll";
+ private DataNode.Builder dBlr;
+ private String value;
+
+ public DataNode buildDataNodeForSimpleDataTypes() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "cont", DATA_TYPE_NAME_SPACE, value, null);
+
+ value = "-128";
+ dBlr = addDataNode(dBlr, "lfnint8Min", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "127";
+ dBlr = addDataNode(dBlr, "lfnint8Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-32768";
+ dBlr = addDataNode(dBlr, "lfnint16Min", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "32767";
+ dBlr = addDataNode(dBlr, "lfnint16Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-2147483648";
+ dBlr = addDataNode(dBlr, "lfnint32Min", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "2147483647";
+ dBlr = addDataNode(dBlr, "lfnint32Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "10090";
+ dBlr = addDataNode(dBlr, "lfnint64Min", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "100700";
+ dBlr = addDataNode(dBlr, "lfnint64Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "32767";
+ dBlr = addDataNode(dBlr, "lfnuint8Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "2147483647";
+ dBlr = addDataNode(dBlr, "lfnuint16Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "10000";
+ dBlr = addDataNode(dBlr, "lfnuint32Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "32656256558";
+ dBlr = addDataNode(dBlr, "lfuint64Max", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "string1";
+ dBlr = addDataNode(dBlr, "lfstr", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "string2";
+ dBlr = addDataNode(dBlr, "lfstr1", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfbool1", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "false";
+ dBlr = addDataNode(dBlr, "lfbool2", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "false";
+ dBlr = addDataNode(dBlr, "lfbool3", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-922337203685477580.8";
+ dBlr = addDataNode(dBlr, "lfdecimal1", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-92233720368547758.08";
+ dBlr = addDataNode(dBlr, "lfdecimal2", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-9223372036854775.808";
+ dBlr = addDataNode(dBlr, "lfdecimal3", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-922337203685477.5808";
+ dBlr = addDataNode(dBlr, "lfdecimal4", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-9223372036854.775808";
+ dBlr = addDataNode(dBlr, "lfdecimal6", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "enum1";
+ dBlr = addDataNode(dBlr, "lfenum", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "bit1";
+ dBlr = addDataNode(dBlr, "lfbits", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "aGV5";
+ dBlr = addDataNode(dBlr, "lfbinary", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "path";
+ dBlr = addDataNode(dBlr, "lfref1", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "100";
+ dBlr = addDataNode(dBlr, "lfref2", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "";
+ dBlr = addDataNode(dBlr, "lfempty", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "cost";
+ dBlr = addDataNode(dBlr, "lfunion1", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-92233720368547758.08";
+ dBlr = addDataNode(dBlr, "lfunion2", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfunion4", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "color";
+ dBlr = addDataNode(dBlr, "lfunion5", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "b1";
+ dBlr = addDataNode(dBlr, "lfunion7", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "bandwidth";
+ dBlr = addDataNode(dBlr, "lfunion8", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "200";
+ dBlr = addDataNode(dBlr, "lfunion9", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfunion10", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "b1";
+ dBlr = addDataNode(dBlr, "lfunion11", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfunion12", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "b2";
+ dBlr = addDataNode(dBlr, "lfunion13", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "one";
+ dBlr = addDataNode(dBlr, "lfunion14", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "iden";
+ dBlr = addDataNode(dBlr, "identityref1", DATA_TYPE_NAME_SPACE, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+
+ public DataNode buildDnForLeafListSimpleDataTypes() {
+ dBlr = initializeDataNode(context);
+ value = null;
+ dBlr = addDataNode(dBlr, "cont1", DATA_TYPE_NAME_SPACE_LL, value, null);
+
+ value = "-128";
+ dBlr = addDataNode(dBlr, "lfnint8Min", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "127";
+ dBlr = addDataNode(dBlr, "lfnint8Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-32768";
+ dBlr = addDataNode(dBlr, "lfnint16Min", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "32767";
+ dBlr = addDataNode(dBlr, "lfnint16Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-2147483648";
+ dBlr = addDataNode(dBlr, "lfnint32Min", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "2147483647";
+ dBlr = addDataNode(dBlr, "lfnint32Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "10090";
+ dBlr = addDataNode(dBlr, "lfnint64Min", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "100700";
+ dBlr = addDataNode(dBlr, "lfnint64Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "32767";
+ dBlr = addDataNode(dBlr, "lfnuint8Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "2147483647";
+ dBlr = addDataNode(dBlr, "lfnuint16Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "10000";
+ dBlr = addDataNode(dBlr, "lfnuint32Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "32656256558";
+ dBlr = addDataNode(dBlr, "lfuint64Max", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "string1";
+ dBlr = addDataNode(dBlr, "lfstr", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "string2";
+ dBlr = addDataNode(dBlr, "lfstr1", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfbool1", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "false";
+ dBlr = addDataNode(dBlr, "lfbool2", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "false";
+ dBlr = addDataNode(dBlr, "lfbool3", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-922337203685477580.8";
+ dBlr = addDataNode(dBlr, "lfdecimal1", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-92233720368547758.08";
+ dBlr = addDataNode(dBlr, "lfdecimal2", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-9223372036854775.808";
+ dBlr = addDataNode(dBlr, "lfdecimal3", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-922337203685477.5808";
+ dBlr = addDataNode(dBlr, "lfdecimal4", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-9223372036854.775808";
+ dBlr = addDataNode(dBlr, "lfdecimal6", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "enum1";
+ dBlr = addDataNode(dBlr, "lfenum", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "bit1";
+ dBlr = addDataNode(dBlr, "lfbits", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "aGVsbG8=";
+ dBlr = addDataNode(dBlr, "lfbinary", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "path";
+ dBlr = addDataNode(dBlr, "lfref1", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "100";
+ dBlr = addDataNode(dBlr, "lfref2", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "";
+ dBlr = addDataNode(dBlr, "lfempty", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "cost";
+ dBlr = addDataNode(dBlr, "lfunion1", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "-92233720368547758.08";
+ dBlr = addDataNode(dBlr, "lfunion2", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfunion4", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "color";
+ dBlr = addDataNode(dBlr, "lfunion5", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "b1";
+ dBlr = addDataNode(dBlr, "lfunion7", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "bandwidth";
+ dBlr = addDataNode(dBlr, "lfunion8", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "200";
+ dBlr = addDataNode(dBlr, "lfunion9", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfunion10", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "b1";
+ dBlr = addDataNode(dBlr, "lfunion11", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "true";
+ dBlr = addDataNode(dBlr, "lfunion12", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "b2";
+ dBlr = addDataNode(dBlr, "lfunion13", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "one";
+ dBlr = addDataNode(dBlr, "lfunion14", null, value, null);
+ dBlr = exitDataNode(dBlr);
+
+ value = "iden";
+ dBlr = addDataNode(dBlr, "identityref1", null, value, null);
+ dBlr = exitDataNode(dBlr);
+ dBlr = exitDataNode(dBlr);
+ return dBlr.build();
+ }
+
+ @Test
+ public void allDataTypesTest() {
+ DataNode dataNode = buildDataNodeForSimpleDataTypes();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultCont cont = ((DefaultCont) modelObject);
+ byte value = -128;
+ assertThat(cont.lfnint8Min(), is(value));
+
+ value = 127;
+ assertThat(cont.lfnint8Max(), is(value));
+
+ short val = -32768;
+ assertThat(cont.lfnint16Min(), is(val));
+
+ val = 32767;
+ assertThat(cont.lfnint16Max(), is(val));
+
+ assertThat(cont.lfnint32Min(), is(-2147483648));
+ assertThat(cont.lfnint32Max(), is(2147483647));
+ assertThat(cont.lfnint64Min(), is(10090L));
+ assertThat(cont.lfnint64Max(), is(100700L));
+
+ val = 32767;
+ assertThat(cont.lfnuint8Max(), is(val));
+ assertThat(cont.lfnuint16Max(), is(2147483647));
+ assertThat(cont.lfnuint32Max(), is(10000L));
+ assertThat(cont.lfuint64Max().toString(), is("32656256558"));
+ assertThat(cont.lfstr(), is("string1"));
+ assertThat(cont.lfstr1(), is("string2"));
+ assertThat(cont.lfbool1(), is(true));
+ assertThat(cont.lfbool2(), is(false));
+ assertThat(cont.lfbool3(), is(false));
+ assertThat(cont.lfdecimal1().toString(),
+ is("-922337203685477580.8"));
+ assertThat(cont.lfdecimal2().toString(),
+ is("-92233720368547758.08"));
+ assertThat(cont.lfdecimal3().toString(),
+ is("-9223372036854775.808"));
+ assertThat(cont.lfdecimal4().toString(),
+ is("-922337203685477.5808"));
+ assertThat(cont.lfdecimal6().toString(),
+ is("-9223372036854.775808"));
+ assertThat(cont.lfenum().toString(), is("enum1"));
+ assertThat(cont.lfbits().toString(), is("{0}"));
+ String str = new String(cont.lfbinary());
+ assertThat(str, is("hey"));
+ assertThat(cont.lfref1(), is("path"));
+ value = 100;
+ assertThat(cont.lfref2(), is(value));
+ assertThat(cont.lfempty(), is(true));
+ assertThat(cont.lfunion1().toString(), is("cost"));
+ assertThat(cont.lfunion2().toString(), is("-92233720368547758.08"));
+ assertThat(cont.lfunion4().toString(), is("true"));
+ assertThat(cont.lfunion5().toString(), is("color"));
+ assertThat(cont.lfunion7().toString(), is("b1 "));
+ assertThat(cont.lfunion8().toString(), is("bandwidth"));
+ assertThat(cont.lfunion9().toString(), is("200"));
+ assertThat(cont.lfunion10().toString(), is("true"));
+ assertThat(cont.lfunion11().toString(), is("b1 "));
+ assertThat(cont.lfunion12().toString(), is("true"));
+ assertThat(cont.lfunion13().toString(), is("b2 "));
+ assertThat(cont.lfunion14().toString(), is("one"));
+ assertThat(cont.identityref1().getSimpleName(), is("Iden"));
+ }
+
+
+ @Test
+ public void allDataTypesTestForLeafList() {
+ DataNode dataNode = buildDnForLeafListSimpleDataTypes();
+ ResourceData data = DefaultResourceData.builder().addDataNode(dataNode).build();
+ DefaultYobBuilder builder = new DefaultYobBuilder(
+ (DefaultYangModelRegistry) context.getContext());
+ ModelObjectData modelObjectData = builder.getYangObject(data);
+ List<ModelObject> modelObjectList = modelObjectData.modelObjects();
+ ModelObject modelObject = modelObjectList.get(0);
+ DefaultCont1 cont = ((DefaultCont1) modelObject);
+ byte value = -128;
+ assertThat(cont.lfnint8Min().get(0), is(value));
+
+ value = 127;
+ assertThat(cont.lfnint8Max().get(0), is(value));
+
+ short val = -32768;
+ assertThat(cont.lfnint16Min().get(0), is(val));
+
+ val = 32767;
+ assertThat(cont.lfnint16Max().get(0), is(val));
+
+ assertThat(cont.lfnint32Min().get(0), is(-2147483648));
+ assertThat(cont.lfnint32Max().get(0), is(2147483647));
+ assertThat(cont.lfnint64Min().get(0), is(10090L));
+ assertThat(cont.lfnint64Max().get(0), is(100700L));
+
+ val = 32767;
+ assertThat(cont.lfnuint8Max().get(0), is(val));
+ assertThat(cont.lfnuint16Max().get(0), is(2147483647));
+ assertThat(cont.lfnuint32Max().get(0), is(10000L));
+ assertThat(cont.lfuint64Max().get(0).toString(), is("32656256558"));
+ assertThat(cont.lfstr().get(0), is("string1"));
+ assertThat(cont.lfstr1().get(0), is("string2"));
+ assertThat(cont.lfbool1().get(0), is(true));
+ assertThat(cont.lfbool2().get(0), is(false));
+ assertThat(cont.lfbool3().get(0), is(false));
+ assertThat(cont.lfdecimal1().get(0).toString(),
+ is("-922337203685477580.8"));
+ assertThat(cont.lfdecimal2().get(0).toString(),
+ is("-92233720368547758.08"));
+ assertThat(cont.lfdecimal3().get(0).toString(),
+ is("-9223372036854775.808"));
+ assertThat(cont.lfdecimal4().get(0).toString(),
+ is("-922337203685477.5808"));
+ assertThat(cont.lfdecimal6().get(0).toString(),
+ is("-9223372036854.775808"));
+ assertThat(cont.lfenum().get(0).toString(), is("enum1"));
+ assertThat(cont.lfbits().get(0).toString(), is("{0}"));
+ String str = new String(cont.lfbinary().get(0));
+ assertThat(str, is("hello"));
+ assertThat(cont.lfref1().get(0), is("path"));
+ value = 100;
+ assertThat(cont.lfref2().get(0), is(value));
+ assertThat(cont.lfempty().get(0), is(true));
+ assertThat(cont.lfunion1().get(0).toString(), is("cost"));
+ assertThat(cont.lfunion2().get(0).toString(), is("-92233720368547758.08"));
+ assertThat(cont.lfunion4().get(0).toString(), is("true"));
+ assertThat(cont.lfunion5().get(0).toString(), is("color"));
+ assertThat(cont.lfunion7().get(0).toString(), is("b1 "));
+ assertThat(cont.lfunion8().get(0).toString(), is("bandwidth"));
+ assertThat(cont.lfunion9().get(0).toString(), is("200"));
+ assertThat(cont.lfunion10().get(0).toString(), is("true"));
+ assertThat(cont.lfunion11().get(0).toString(), is("b1 "));
+ assertThat(cont.lfunion12().get(0).toString(), is("true"));
+ assertThat(cont.lfunion13().get(0).toString(), is("b2 "));
+ assertThat(cont.lfunion14().get(0).toString(), is("one"));
+ assertThat(cont.identityref1().get(0).getSimpleName().toString(),
+ is("Iden"));
+ }
+}
diff --git a/runtime/src/test/resources/yobTestYangFiles/SampleTest.yang b/runtime/src/test/resources/yobTestYangFiles/SampleTest.yang
new file mode 100644
index 0000000..c59ed74
--- /dev/null
+++ b/runtime/src/test/resources/yobTestYangFiles/SampleTest.yang
@@ -0,0 +1,53 @@
+module sample {
+ yang-version 1;
+ namespace "samplenamespace";
+ prefix "attr";
+ container top {
+ leaf mtu {
+ type string;
+ }
+ leaf-list color {
+ type string;
+ }
+ list interface {
+ key name;
+ leaf name {
+ type string;
+ }
+ container address {
+ leaf name {
+ type string;
+ }
+ }
+ }
+ }
+ list l1 {
+ config false;
+ container c1 {
+ leaf leaf1 {
+ type string;
+ }
+ leaf-list leaf2 {
+ type string;
+ }
+ }
+ leaf leaf3 {
+ type string;
+ }
+ leaf-list leaf4 {
+ type string;
+ }
+ }
+ list l2 {
+ key k1;
+ leaf k1 {
+ type string;
+ }
+ }
+ leaf leaf5 {
+ type string;
+ }
+ leaf-list leaf6 {
+ type string;
+ }
+}
\ No newline at end of file
diff --git a/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang b/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
new file mode 100644
index 0000000..cb56c41
--- /dev/null
+++ b/runtime/src/test/resources/yobTestYangFiles/ip-topology.yang
@@ -0,0 +1,28 @@
+module yms-ip-topology {
+ yang-version 1;
+ namespace urn:ip:topo;
+ prefix ip-topo;
+ import yms-topology {
+ prefix topo;
+ revision-date "2014-01-01";
+ }
+ revision 2014-01-01 {
+ description "desc";
+ reference "ref";
+ }
+
+ augment /topo:node{
+ leaf router-id {
+ type string;
+ }
+ leaf router-ip {
+ type string;
+ }
+ }
+
+ augment /topo:node/topo:termination-points/topo:termination-point {
+ leaf ip-address {
+ type string;
+ }
+ }
+}
diff --git a/runtime/src/test/resources/yobTestYangFiles/leafreftest.yang b/runtime/src/test/resources/yobTestYangFiles/leafreftest.yang
new file mode 100644
index 0000000..0905c86
--- /dev/null
+++ b/runtime/src/test/resources/yobTestYangFiles/leafreftest.yang
@@ -0,0 +1,71 @@
+module leafreftest {
+
+ yang-version 1;
+
+ namespace "yob.leafreftest";
+
+ prefix "uniontest";
+
+ organization "ON-LAB";
+
+ description "This module defines for union classifier.";
+
+ revision "2016-05-24" {
+ description "Initial revision.";
+ }
+
+ leaf middlename {
+ type string;
+ }
+
+ list leafrefList {
+ config false;
+ leaf id {
+ type leafref {
+ path "/middlename";
+ }
+ }
+ }
+
+ typedef percent {
+ type leafref {
+ path "/middlename";
+ }
+ }
+
+ leaf name {
+ type percent;
+ }
+
+ grouping greeting {
+ leaf surname {
+ type leafref {
+ path "/middlename";
+ }
+ }
+ }
+
+ container cont1 {
+ uses greeting;
+ }
+
+ augment "/cont1" {
+ leaf lastname {
+ type leafref {
+ path "/middlename";
+ }
+ }
+ }
+
+ container food {
+ choice snack {
+ case sportsarena {
+ leaf pretzel {
+ type leafref {
+ path "/middlename";
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/runtime/src/test/resources/yobTestYangFiles/simple-data-types-leaf-list.yang b/runtime/src/test/resources/yobTestYangFiles/simple-data-types-leaf-list.yang
new file mode 100644
index 0000000..401cdaa
--- /dev/null
+++ b/runtime/src/test/resources/yobTestYangFiles/simple-data-types-leaf-list.yang
@@ -0,0 +1,256 @@
+module simple-data-types-ll {
+ namespace "simple:data:types:ll";
+
+ prefix "smpdtp";
+ revision 2013-11-12 {
+ }
+
+ identity iden {
+ }
+
+ typedef tpdfempty {
+ type empty;
+ }
+
+ typedef tpdfbit {
+ type bits {
+ bit b1;
+ bit b2;
+ bit b3;
+ }
+ }
+
+ typedef tpdfun4 {
+ type boolean;
+ }
+
+ typedef tpdfun3 {
+ type union {
+ type tpdfbit;
+ type tpdfempty;
+ }
+ }
+
+ typedef tpdfun2 {
+ type union {
+ type tpdfun3;
+ type tpdfun4;
+ }
+ }
+
+ typedef tpdfun1 {
+ type union {
+ type uint8;
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ }
+
+ container cont1 {
+ leaf-list lfnint8Min {
+ type int8;
+ }
+ leaf-list lfnint8Max {
+ type int8;
+ }
+ leaf-list lfnint16Min {
+ type int16;
+ }
+ leaf-list lfnint16Max {
+ type int16;
+ }
+ leaf-list lfnint32Min {
+ type int32;
+ }
+ leaf-list lfnint32Max {
+ type int32;
+ }
+ leaf-list lfnint64Min {
+ type int64;
+ }
+ leaf-list lfnint64Max {
+ type int64;
+ }
+ leaf-list lfnuint8Max {
+ type uint8;
+ }
+ leaf-list lfnuint16Max {
+ type uint16;
+ }
+ leaf-list lfnuint32Max {
+ type uint32;
+ }
+ leaf-list lfuint64Max {
+ type uint64;
+ }
+ leaf-list lfstr {
+ type string;
+ }
+ leaf-list lfstr1 {
+ type string;
+ }
+ leaf-list lfbool1 {
+ type boolean;
+ }
+ leaf-list lfbool2 {
+ type boolean;
+ }
+ leaf-list lfbool3 {
+ type boolean;
+ }
+ leaf-list lfdecimal1 {
+ type decimal64 {
+ fraction-digits 1;
+ }
+ }
+ leaf-list lfdecimal2 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ leaf-list lfdecimal3 {
+ type decimal64 {
+ fraction-digits 3;
+ }
+ }
+
+ leaf-list lfdecimal4 {
+ type decimal64 {
+ fraction-digits 4;
+ }
+ }
+
+ leaf-list lfdecimal6 {
+ type decimal64 {
+ fraction-digits 6;
+ }
+ }
+
+ leaf-list lfenum {
+ type enumeration {
+ enum enum1;
+ enum enum2;
+ enum enum3;
+ enum enum4;
+ }
+ }
+
+ leaf-list lfbits {
+ type bits {
+ bit bit1;
+ bit bit2;
+ bit bit3;
+ bit bit4;
+ }
+ }
+
+ leaf-list lfbinary {
+ type binary;
+ }
+
+ leaf-list lfref1 { //reference to string type
+ type leafref {
+ path "../lfstr";
+ }
+ }
+
+ leaf-list lfref2 { //reference to number type
+ type leafref {
+ path "../lfnint8Max";
+ }
+ }
+
+ leaf-list lfempty {
+ type empty;
+ }
+
+ leaf-list lfunion1 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+ leaf-list lfunion2 {
+ type union {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ type string;
+ }
+ }
+
+ leaf-list lfunion4 {
+ type union {
+ type boolean;
+ type string;
+ }
+ }
+
+ leaf-list lfunion5 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+
+ leaf-list lfunion7 {
+ type tpdfun3;
+ }
+
+ leaf-list lfunion8 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+
+ leaf-list lfunion9 {
+ type union {
+ type uint16;
+ type boolean;
+ }
+ }
+
+ leaf-list lfunion10 {
+ type union {
+ type bits {
+ bit bt1;
+ bit bt2;
+ }
+ type boolean;
+ }
+ }
+
+ leaf-list lfunion11 {
+ type union {
+ type tpdfun1;
+ type tpdfun2;
+ }
+ }
+
+ leaf-list lfunion12 {
+ type tpdfun2;
+ }
+
+ leaf-list lfunion13 {
+ type tpdfbit;
+ }
+
+ leaf-list lfunion14 {
+ type union {
+ type enumeration {
+ enum zero;
+ enum one;
+ }
+ type uint16;
+ }
+ }
+
+ leaf-list identityref1 {
+ type identityref {
+ base iden;
+ }
+ }
+ }
+}
diff --git a/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang b/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang
new file mode 100644
index 0000000..602c37b
--- /dev/null
+++ b/runtime/src/test/resources/yobTestYangFiles/simple-data-types.yang
@@ -0,0 +1,256 @@
+module simple-data-types {
+ namespace "simple:data:types";
+
+ prefix "smpdtp";
+ revision 2013-11-12 {
+ }
+
+ identity iden {
+ }
+
+ typedef tpdfempty {
+ type empty;
+ }
+
+ typedef tpdfbit {
+ type bits {
+ bit b1;
+ bit b2;
+ bit b3;
+ }
+ }
+
+ typedef tpdfun4 {
+ type boolean;
+ }
+
+ typedef tpdfun3 {
+ type union {
+ type tpdfbit;
+ type tpdfempty;
+ }
+ }
+
+ typedef tpdfun2 {
+ type union {
+ type tpdfun3;
+ type tpdfun4;
+ }
+ }
+
+ typedef tpdfun1 {
+ type union {
+ type uint8;
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ }
+
+ container cont {
+ leaf lfnint8Min {
+ type int8;
+ }
+ leaf lfnint8Max {
+ type int8;
+ }
+ leaf lfnint16Min {
+ type int16;
+ }
+ leaf lfnint16Max {
+ type int16;
+ }
+ leaf lfnint32Min {
+ type int32;
+ }
+ leaf lfnint32Max {
+ type int32;
+ }
+ leaf lfnint64Min {
+ type int64;
+ }
+ leaf lfnint64Max {
+ type int64;
+ }
+ leaf lfnuint8Max {
+ type uint8;
+ }
+ leaf lfnuint16Max {
+ type uint16;
+ }
+ leaf lfnuint32Max {
+ type uint32;
+ }
+ leaf lfuint64Max {
+ type uint64;
+ }
+ leaf lfstr {
+ type string;
+ }
+ leaf lfstr1 {
+ type string;
+ }
+ leaf lfbool1 {
+ type boolean;
+ }
+ leaf lfbool2 {
+ type boolean;
+ }
+ leaf lfbool3 {
+ type boolean;
+ }
+ leaf lfdecimal1 {
+ type decimal64 {
+ fraction-digits 1;
+ }
+ }
+ leaf lfdecimal2 {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ leaf lfdecimal3 {
+ type decimal64 {
+ fraction-digits 3;
+ }
+ }
+
+ leaf lfdecimal4 {
+ type decimal64 {
+ fraction-digits 4;
+ }
+ }
+
+ leaf lfdecimal6 {
+ type decimal64 {
+ fraction-digits 6;
+ }
+ }
+
+ leaf lfenum {
+ type enumeration {
+ enum enum1;
+ enum enum2;
+ enum enum3;
+ enum enum4;
+ }
+ }
+
+ leaf lfbits {
+ type bits {
+ bit bit1;
+ bit bit2;
+ bit bit3;
+ bit bit4;
+ }
+ }
+
+ leaf lfbinary {
+ type binary;
+ }
+
+ leaf lfref1 { //reference to string type
+ type leafref {
+ path "../lfstr";
+ }
+ }
+
+ leaf lfref2 { //reference to number type
+ type leafref {
+ path "../lfnint8Max";
+ }
+ }
+
+ leaf lfempty {
+ type empty;
+ }
+
+ leaf lfunion1 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+ leaf lfunion2 {
+ type union {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ type string;
+ }
+ }
+
+ leaf lfunion4 {
+ type union {
+ type boolean;
+ type string;
+ }
+ }
+
+ leaf lfunion5 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+
+ leaf lfunion7 {
+ type tpdfun3;
+ }
+
+ leaf lfunion8 {
+ type union {
+ type uint16;
+ type string;
+ }
+ }
+
+ leaf lfunion9 {
+ type union {
+ type uint16;
+ type boolean;
+ }
+ }
+
+ leaf lfunion10 {
+ type union {
+ type bits {
+ bit bt1;
+ bit bt2;
+ }
+ type boolean;
+ }
+ }
+
+ leaf lfunion11 {
+ type union {
+ type tpdfun1;
+ type tpdfun2;
+ }
+ }
+
+ leaf lfunion12 {
+ type tpdfun2;
+ }
+
+ leaf lfunion13 {
+ type tpdfbit;
+ }
+
+ leaf lfunion14 {
+ type union {
+ type enumeration {
+ enum zero;
+ enum one;
+ }
+ type uint16;
+ }
+ }
+
+ leaf identityref1 {
+ type identityref {
+ base iden;
+ }
+ }
+ }
+}
diff --git a/runtime/src/test/resources/yobTestYangFiles/topology.yang b/runtime/src/test/resources/yobTestYangFiles/topology.yang
new file mode 100644
index 0000000..9837851
--- /dev/null
+++ b/runtime/src/test/resources/yobTestYangFiles/topology.yang
@@ -0,0 +1,90 @@
+
+module yms-topology {
+ yang-version 1;
+ namespace urn:topo;
+ prefix topo;
+ revision 2014-01-01 {
+ description "desc";
+ reference "ref";
+ }
+ list node {
+ key "node-id";
+ leaf node-id{
+ type string;
+ }
+ leaf-list node-prop{
+ type string;
+ }
+ container termination-points{
+ leaf number-of-tp {
+ type int16;
+ }
+ list termination-point {
+ key "tp-id";
+ leaf tp-id {
+ type string;
+ }
+ }
+ }
+ choice choice1{
+ case case1a{
+ leaf leaf1a1{
+ type string;
+ }
+ leaf leaf1a2{
+ type string;
+ }
+ }
+ case case1b{
+ choice choice1b{
+ case case1bi{
+ leaf leaf1bia{
+ type string;
+ }
+ leaf leaf1bib{
+ type string;
+ }
+ }
+ case case1bii{
+ leaf leaf1biia{
+ type string;
+ }
+ leaf leaf1biib{
+ type string;
+ }
+ }
+ }
+ }
+ }
+ }
+ choice choice2 {
+ case case2a {
+ leaf leaf2a1 {
+ type string;
+ }
+ leaf leaf2a2 {
+ type string;
+ }
+ }
+ case case2b {
+ choice choice3b {
+ case case2bi {
+ leaf leaf2bia {
+ type string;
+ }
+ leaf leaf2bib {
+ type string;
+ }
+ }
+ case case3bii {
+ leaf leaf3biia {
+ type string;
+ }
+ leaf leaf3biib {
+ type string;
+ }
+ }
+ }
+ }
+ }
+}