YANG object builder support for choice, case and augment
Change-Id: I1750062be4443f1fe03a4d405164dbceec6be631
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ydt/YdtListener.java b/apps/yms/api/src/main/java/org/onosproject/yms/ydt/YdtListener.java
index dbe4de3..3fd0274 100644
--- a/apps/yms/api/src/main/java/org/onosproject/yms/ydt/YdtListener.java
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ydt/YdtListener.java
@@ -19,12 +19,12 @@
/**
* Abstraction of an entity which provide call back methods which are called
* by YDT walker while walking the YANG data tree.
- *
+ * <p>
* In a response to execute operation YMS returns the YMS operation results
* with root YDT node. Now, protocols needs to walk through the YDT node and
* constructs the corresponding data format string. Protocol can opt to use
* listener or visitor based walking mechanism.
- *
+ * <p>
* This interface needs to be implemented by protocol implementing listener's
* based call backs while YDT walk.
*/
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java
index 4caa212..6df0724 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java
@@ -16,25 +16,29 @@
package org.onosproject.yms.app.yob;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
+import org.onosproject.yms.app.yob.exception.YobException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.onosproject.yms.app.yob.YobConstants.BUILDER_IS_NOT_SET;
-import static org.onosproject.yms.app.yob.YobConstants.BUILT_OBJ_IS_NOT_SET;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_CREATE_OBJ;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_BUILDING_WITHOUT_BUILDER;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_IS_ALREADY_BUILT_NOT_BUILD;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_IS_ALREADY_BUILT_NOT_FETCH;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_IS_NOT_SET_NOT_FETCH;
-import static org.onosproject.yms.app.yob.YobConstants.REFLECTION_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yms.app.yob.YobConstants.E_BUILDER_IS_NOT_SET;
+import static org.onosproject.yms.app.yob.YobConstants.E_BUILT_OBJ_IS_NOT_SET;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_BUILDING_WITHOUT_BUILDER;
+import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_ALREADY_BUILT_NOT_BUILD;
+import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_ALREADY_BUILT_NOT_FETCH;
+import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_NOT_SET_NOT_FETCH;
+import static org.onosproject.yms.app.yob.YobConstants.E_REFLECTION_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_CREATE_OBJ;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yms.app.yob.YobConstants.L_REFLECTION_FAIL_TO_CREATE_OBJ;
/**
* Represents the container of YANG object being built or the builder.
*/
class YobBuilderOrBuiltObject {
- private static final Logger log = LoggerFactory.getLogger(YobWorkBench.class);
+ private static final Logger log =
+ LoggerFactory.getLogger(YobWorkBench.class);
/**
* Is the contained object a built object.
@@ -56,6 +60,13 @@
*/
Class<?> yangDefaultClass;
+ /**
+ * Create Node Object holder.
+ *
+ * @param qualifiedClassName name of the class
+ * @param registeredAppClassLoader class loader to be used
+ * @throws YobException if failed to create the node object
+ */
YobBuilderOrBuiltObject(String qualifiedClassName,
ClassLoader registeredAppClassLoader) {
try {
@@ -64,11 +75,15 @@
yangBuilderClass = yangDefaultClass.getDeclaredClasses()[0];
builderOrBuiltObject = yangBuilderClass.newInstance();
} catch (ClassNotFoundException e) {
- log.error(FAIL_TO_LOAD_CLASS + qualifiedClassName);
+ log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+ throw new YobException(E_FAIL_TO_LOAD_CLASS + qualifiedClassName);
} catch (InstantiationException | IllegalAccessException e) {
- log.error(FAIL_TO_CREATE_OBJ + qualifiedClassName);
+ log.error(L_FAIL_TO_CREATE_OBJ, qualifiedClassName);
+ throw new YobException(E_FAIL_TO_CREATE_OBJ + qualifiedClassName);
} catch (NullPointerException e) {
- log.error(REFLECTION_FAIL_TO_CREATE_OBJ + qualifiedClassName);
+ log.error(L_REFLECTION_FAIL_TO_CREATE_OBJ, qualifiedClassName);
+ throw new YobException(E_REFLECTION_FAIL_TO_CREATE_OBJ +
+ qualifiedClassName);
}
}
@@ -76,15 +91,16 @@
* Returns the builder object if it is set.
*
* @return builder object
- * @throws YobExceptions if builder object is not available
+ * @throws YobException if builder object is not available or if it is
+ * already built
*/
Object getBuilderObject() {
if (isBuilt) {
- throw new YobExceptions(OBJ_IS_ALREADY_BUILT_NOT_FETCH);
+ throw new YobException(E_OBJ_IS_ALREADY_BUILT_NOT_FETCH);
}
if (builderOrBuiltObject == null) {
- throw new YobExceptions(BUILDER_IS_NOT_SET);
+ throw new YobException(E_BUILDER_IS_NOT_SET);
}
return builderOrBuiltObject;
@@ -94,15 +110,16 @@
* Returns the built object.
*
* @return built object
- * @throws YobExceptions if built object is not available
+ * @throws YobException if built object is not available or if it is not
+ * built
*/
Object getBuiltObject() {
if (!isBuilt) {
- throw new YobExceptions(OBJ_IS_NOT_SET_NOT_FETCH);
+ throw new YobException(E_OBJ_IS_NOT_SET_NOT_FETCH);
}
if (builderOrBuiltObject == null) {
- throw new YobExceptions(BUILT_OBJ_IS_NOT_SET);
+ throw new YobException(E_BUILT_OBJ_IS_NOT_SET);
}
return builderOrBuiltObject;
@@ -113,15 +130,16 @@
* set it.
*
* @param builtObject new built object
- * @throws YobExceptions if builder or built object is not available
+ * @throws YobException if builder object is not available or if it is
+ * already built
*/
void setBuiltObject(Object builtObject) {
if (isBuilt) {
- throw new YobExceptions(OBJ_IS_ALREADY_BUILT_NOT_BUILD);
+ throw new YobException(E_OBJ_IS_ALREADY_BUILT_NOT_BUILD);
}
if (builderOrBuiltObject == null) {
- throw new YobExceptions(OBJ_BUILDING_WITHOUT_BUILDER);
+ throw new YobException(E_OBJ_BUILDING_WITHOUT_BUILDER);
}
isBuilt = true;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java
index 2fc1343..3b8d728 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java
@@ -20,6 +20,7 @@
* Represents common constant utility for YANG object builder.
*/
final class YobConstants {
+
private YobConstants() {
}
@@ -33,35 +34,57 @@
static final String OP_TYPE = "OnosYangNodeOperationType";
static final String OF = "of";
static final String PERIOD = ".";
- static final String NO_HANDLE_FOR_YDT = "No handler for YDT node";
- static final String HAS_NO_CHILD = " does not have child ";
- static final String SET_OP_TYPE_FAIL = "Failed to set Operation Type";
- static final String FAIL_TO_BUILD = "Failed to build the object ";
- static final String FAIL_TO_GET_FIELD = "Failed to get field for class ";
- static final String FAIL_TO_GET_METHOD = "Failed to get method for class ";
- static final String FAIL_TO_LOAD_CLASS = "Failed to load class for class ";
- static final String YDT_TYPE_IS_NOT_SUPPORT =
+ static final String ADD_AUGMENT_METHOD = "addYangAugmentedInfo";
+
+ //Error strings
+ static final String E_NO_HANDLE_FOR_YDT = "No handler for YDT node";
+ static final String E_HAS_NO_CHILD = " does not have child ";
+ static final String E_SET_OP_TYPE_FAIL = "Failed to set Operation Type";
+ static final String E_FAIL_TO_BUILD = "Failed to build the object: ";
+ static final String L_FAIL_TO_BUILD = "Failed to build the object: {}";
+ 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 L_FAIL_TO_LOAD_CLASS =
+ "Failed to load class for class: {}";
+ static final String E_YDT_TYPE_IS_NOT_SUPPORT =
"Given YDT type is not supported.";
- static final String FAIL_TO_CREATE_OBJ =
- "Failed to create an object for class ";
- static final String REFLECTION_FAIL_TO_CREATE_OBJ =
- "Reflection failed to create an object for class ";
- static final String FAIL_TO_LOAD_CONSTRUCTOR =
- "Failed to load constructor for class ";
- static final String FAIL_TO_INVOKE_METHOD =
- "Failed to invoke method for class ";
- static final String DATA_TYPE_NOT_SUPPORT =
+ 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 OBJ_IS_ALREADY_BUILT_NOT_FETCH =
+ static final String E_OBJ_IS_ALREADY_BUILT_NOT_FETCH =
"Object is already built, cannot fetch builder";
- static final String BUILDER_IS_NOT_SET =
+ static final String E_BUILDER_IS_NOT_SET =
"Builder is not yet set, cannot fetch it";
- static final String BUILT_OBJ_IS_NOT_SET =
+ static final String E_BUILT_OBJ_IS_NOT_SET =
"Built object is not set";
- static final String OBJ_IS_NOT_SET_NOT_FETCH =
+ static final String E_OBJ_IS_NOT_SET_NOT_FETCH =
"Builder is not yet set, cannot fetch it";
- static final String OBJ_IS_ALREADY_BUILT_NOT_BUILD =
+ static final String E_OBJ_IS_ALREADY_BUILT_NOT_BUILD =
"Object is already built, cannot build again";
- static final String OBJ_BUILDING_WITHOUT_BUILDER =
+ static final String E_OBJ_BUILDING_WITHOUT_BUILDER =
"Object building without builder";
+ static final String E_MISSING_DATA_IN_NODE =
+ "YANG data tree is missing the data required for YOB";
+ static final String E_INVALID_DATA_TREE =
+ "YANG tree does not have a application root";
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
index e2190f0..abb6248 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
@@ -16,31 +16,14 @@
package org.onosproject.yms.app.yob;
-import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
-import org.onosproject.yangutils.datamodel.YangBinary;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
-import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yms.app.ydt.AppType.YOB;
-import static org.onosproject.yms.app.yob.YobConstants.DATA_TYPE_NOT_SUPPORT;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CONSTRUCTOR;
-import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
-import static org.onosproject.yms.app.yob.YobConstants.OF;
-import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
-import static org.onosproject.yms.app.yob.YobWorkBench.getQualifiedDefaultClassName;
+import static org.onosproject.yms.app.yob.YobUtils.getQualifiedDefaultClass;
/**
* Represents a YANG object builder handler to process the ydt content and
@@ -51,38 +34,32 @@
private static final Logger log = LoggerFactory.getLogger(YobHandler.class);
/**
- * reference to YANG schema registry.
- */
- private YangSchemaRegistry registry;
-
- /**
* Creates a YANG builder object.
*
- * @param curYdtNode ydtExtendedContext is used to get
- * application related information maintained
- * in YDT
- * @param rootYdtNode ydtRootNode is refers to module node
- * @param registry registry
+ * @param curNode ydtExtendedContext is used to get
+ * application related information maintained
+ * in YDT
+ * @param rootNode ydtRootNode is refers to module node
+ * @param registry registry
*/
- public void createYangBuilderObject(YdtExtendedContext curYdtNode,
- YdtExtendedContext rootYdtNode,
- YangSchemaRegistry registry) {
+ public void createBuilder(YdtExtendedContext curNode,
+ YdtExtendedContext rootNode,
+ YangSchemaRegistry registry) {
String setterName = null;
- YangSchemaNode node = curYdtNode.getYangSchemaNode();
+ YangSchemaNode node = curNode.getYangSchemaNode();
- String qualName = getQualifiedDefaultClassName(node);
- ClassLoader classLoader = getClassLoader(registry,
- qualName,
- curYdtNode, rootYdtNode);
+ String qualName = getQualifiedDefaultClass(node);
+ ClassLoader classLoader = YobUtils.getClassLoader(registry, qualName,
+ curNode, rootNode);
- if (curYdtNode != rootYdtNode) {
+ if (curNode != rootNode) {
setterName = node.getJavaAttributeName();
}
- Object builderObject = new YobWorkBench(node, classLoader,
- qualName, setterName);
+ Object workBench = new YobWorkBench(node, classLoader, qualName,
+ setterName);
- curYdtNode.addAppInfo(YOB, builderObject);
+ curNode.addAppInfo(YOB, workBench);
}
/**
@@ -92,8 +69,10 @@
* related information maintained in YDT
* @param schemaRegistry YANG schema registry
*/
- public void setObjectInParent(YdtExtendedContext ydtNode,
- YangSchemaRegistry schemaRegistry) {
+ public void setInParent(YdtExtendedContext ydtNode,
+ YangSchemaRegistry schemaRegistry) {
+ YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
+ yobWorkBench.setObjectInParent(ydtNode);
}
/**
@@ -105,243 +84,10 @@
* @param ydtRootNode ydtRootNode
* @param schemaRegistry YANG schema registry
*/
- public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
- YdtExtendedContext ydtRootNode,
- YangSchemaRegistry schemaRegistry) {
+ public void buildObject(YdtExtendedContext ydtNode,
+ YdtExtendedContext ydtRootNode,
+ YangSchemaRegistry schemaRegistry) {
YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
- yobWorkBench.buildObject(ydtNode, ydtRootNode);
- }
-
- /**
- * This method is used to set data from string value in parent method.
- *
- * @param type refers to YANG type
- * @param leafValue leafValue argument is used to set the value
- * in method
- * @param parentSetterMethod Invokes the underlying method represented
- * by this parentSetterMethod
- * @param parentBuilderObject the parentBuilderObject is to invoke the
- * underlying method
- * @param ydtExtendedContext ydtExtendedContext is used to get
- * application related
- * information maintained in YDT
- * @throws InvocationTargetException throws InvocationTargetException
- * @throws IllegalAccessException throws IllegalAccessException
- * @throws NoSuchMethodException throws NoSuchMethodException
- */
- void setDataFromStringValue(YangType<?> type, String leafValue,
- Method parentSetterMethod,
- Object parentBuilderObject,
- YdtExtendedContext ydtExtendedContext)
- throws InvocationTargetException, IllegalAccessException,
- NoSuchMethodException {
- switch (type.getDataType()) {
- case INT8: {
- parentSetterMethod.invoke(parentBuilderObject,
- Byte.parseByte(leafValue));
- break;
- }
- case UINT8:
- case INT16: {
- parentSetterMethod.invoke(parentBuilderObject,
- Short.parseShort(leafValue));
- break;
- }
- case UINT16:
- case INT32: {
- parentSetterMethod.invoke(parentBuilderObject,
- Integer.parseInt(leafValue));
- break;
- }
- case UINT32:
- case INT64: {
- parentSetterMethod.invoke(parentBuilderObject,
- Long.parseLong(leafValue));
- break;
- }
- case UINT64: {
- parentSetterMethod.invoke(parentBuilderObject,
- new BigInteger(leafValue));
- break;
- }
- case EMPTY:
- case BOOLEAN: {
- parentSetterMethod.invoke(parentBuilderObject,
- Boolean.parseBoolean(leafValue));
- break;
- }
- case STRING: {
- parentSetterMethod.invoke(parentBuilderObject, leafValue);
- break;
- }
- case BINARY: {
- parentSetterMethod.invoke(parentBuilderObject,
- new YangBinary(leafValue));
- break;
- }
- case BITS: {
- //TODO
- break;
- }
- case DECIMAL64: {
- parentSetterMethod.invoke(parentBuilderObject,
- new BigDecimal(leafValue));
- break;
- }
- case DERIVED: {
- parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
- parentBuilderObject, leafValue, false);
- break;
- }
- case UNION: {
- // TODO
- break;
- }
- case LEAFREF: {
- // TODO
- break;
- }
- case ENUMERATION: {
- parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
- parentBuilderObject, leafValue, true);
- break;
- }
- default: {
- log.error(DATA_TYPE_NOT_SUPPORT);
- }
- }
- }
-
- /**
- * To set data into parent setter method from string value for derived type.
- *
- * @param leafValue leafValue argument is used to set the value
- * in method
- * @param parentSetterMethod Invokes the underlying method represented
- * by this parentSetterMethod
- * @param parentBuilderObject the parentBuilderObject is to invoke the
- * underlying method
- * @param ydtExtendedContext ydtExtendedContext is used to get
- * application related
- * information maintained in YDT
- * @param isEnum isEnum parameter is used to check whether
- * type is enum or derived
- * information maintained in YDT
- * @throws InvocationTargetException throws InvocationTargetException
- * @throws IllegalAccessException throws IllegalAccessException
- * @throws NoSuchMethodException throws NoSuchMethodException
- */
- private void parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
- Method parentSetterMethod,
- Object parentBuilderObject,
- String leafValue, boolean isEnum)
- throws InvocationTargetException, IllegalAccessException,
- NoSuchMethodException {
- Class<?> childSetClass = null;
- Constructor<?> childConstructor = null;
- Object childValue = null;
- Object childObject = null;
- Method childMethod = null;
-
- YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
- String packageName = yangJavaModule.getJavaPackage();
- String className = getCapitalCase(
- yangJavaModule.getJavaClassNameOrBuiltInType());
- String qualifiedClassName = packageName + PERIOD + className;
- ClassLoader classLoader = getClassLoader(registry,
- qualifiedClassName,
- ydtExtendedContext, null);
- try {
- childSetClass = classLoader.loadClass(qualifiedClassName);
- } catch (ClassNotFoundException e) {
- log.error(FAIL_TO_LOAD_CLASS + packageName + PERIOD + className);
- }
- 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(FAIL_TO_LOAD_CONSTRUCTOR + className);
- }
- if (childSetClass != null) {
- childMethod = childSetClass
- .getDeclaredMethod(FROM_STRING, String.class);
- }
- } else {
- if (childSetClass != null) {
- childMethod = childSetClass.getDeclaredMethod(OF, String.class);
- }
- //leafValue = JavaIdentifierSyntax.getEnumJavaAttribute(leafValue);
- //leafValue = leafValue.toUpperCase();
- }
- if (childMethod != null) {
- childValue = childMethod.invoke(childObject, leafValue);
- }
-
- parentSetterMethod.invoke(parentBuilderObject, childValue);
- }
-
- /**
- * Updates class loader for all the classes.
- *
- * @param registry YANG schema registry
- * @param curNode YDT context
- * @param qualifiedClassName qualified class name
- * @return current class loader
- */
- private ClassLoader getClassLoader(YangSchemaRegistry registry,
- String qualifiedClassName,
- YdtExtendedContext curNode,
- YdtExtendedContext context) {
-
- if (context != null && curNode == context) {
- YangSchemaNode yangSchemaNode = curNode.getYangSchemaNode();
- while (!(yangSchemaNode instanceof RpcNotificationContainer)) {
- curNode = (YdtExtendedContext) curNode.getParent();
- if (curNode == null) {
- throw new YobExceptions("Invalid YANG data tree");
- }
- yangSchemaNode = curNode.getYangSchemaNode();
- }
-
- Class<?> regClass = registry.getRegisteredClass(yangSchemaNode,
- qualifiedClassName);
- return regClass.getClassLoader();
- } else {
- YdtExtendedContext parent =
- (YdtExtendedContext) curNode.getParent();
- YobWorkBench parentBuilderContainer =
- (YobWorkBench) parent.getAppInfo(YOB);
- Object parentObj =
- parentBuilderContainer.getParentBuilder(curNode, registry);
- return parentObj.getClass().getClassLoader();
- }
- }
-
- /**
- * Returns the YANG schema registry.
- *
- * @return registry YANG schema registry
- */
- public YangSchemaRegistry getRegistry() {
- return registry;
- }
-
- /**
- * Sets the YANG schema registry.
- *
- * @param registry YANG schema registry
- */
- public void setRegistry(YangSchemaRegistry registry) {
- this.registry = registry;
+ yobWorkBench.buildObject(ydtNode);
}
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java
index 254edd9..5a8a8ef 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java
@@ -17,6 +17,7 @@
package org.onosproject.yms.app.yob;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
import org.onosproject.yms.ydt.YdtType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,7 +25,7 @@
import java.util.HashMap;
import java.util.Map;
-import static org.onosproject.yms.app.yob.YobConstants.YDT_TYPE_IS_NOT_SUPPORT;
+import static org.onosproject.yms.app.yob.YobConstants.E_YDT_TYPE_IS_NOT_SUPPORT;
import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_LEAF_VALUE_NODE;
import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
import static org.onosproject.yms.ydt.YdtType.SINGLE_INSTANCE_LEAF_VALUE_NODE;
@@ -37,65 +38,56 @@
final class YobHandlerFactory {
private static final Logger log =
- LoggerFactory.getLogger(YobSingleInstanceLeafHandler.class);
-
- /**
- * Creates single instance node handler.
- */
- private static YobSingleInstanceHandler singleInstanceNode =
- new YobSingleInstanceHandler();
-
- /**
- * Creates multi instance node handler.
- */
- private static YobMultiInstanceHandler multiInstanceNode =
- new YobMultiInstanceHandler();
-
- /**
- * Creates single instance leaf node handler.
- */
- private static YobSingleInstanceLeafHandler singleInstanceLeaf =
- new YobSingleInstanceLeafHandler();
-
- /**
- * Creates multi instance leaf node handler.
- */
- private static YobMultiInstanceLeafHandler multiInstanceLeaf =
- new YobMultiInstanceLeafHandler();
+ LoggerFactory.getLogger(YobHandlerFactory.class);
/**
* Map of YANG object builder handler.
*/
- private static Map<YdtType, YobHandler> yobHandlerHashMap =
- new HashMap<>();
+ private static final Map<YdtType, YobHandler> HANDLER_MAP = new HashMap<>();
/**
* Create instance of YobHandlerFactory.
*/
- YobHandlerFactory() {
- yobHandlerHashMap.put(SINGLE_INSTANCE_NODE, singleInstanceNode);
- yobHandlerHashMap.put(MULTI_INSTANCE_NODE, multiInstanceNode);
- yobHandlerHashMap.put(SINGLE_INSTANCE_LEAF_VALUE_NODE,
- singleInstanceLeaf);
- yobHandlerHashMap.put(MULTI_INSTANCE_LEAF_VALUE_NODE,
- multiInstanceLeaf);
+ private YobHandlerFactory() {
+ HANDLER_MAP.put(SINGLE_INSTANCE_NODE, new YobSingleInstanceHandler());
+ HANDLER_MAP.put(MULTI_INSTANCE_NODE, new YobMultiInstanceHandler());
+ HANDLER_MAP.put(SINGLE_INSTANCE_LEAF_VALUE_NODE,
+ new YobSingleInstanceLeafHandler());
+ HANDLER_MAP.put(MULTI_INSTANCE_LEAF_VALUE_NODE,
+ new YobMultiInstanceLeafHandler());
}
/**
* Returns the corresponding YOB handler for current context.
*
- * @param ydtExtendedContext ydtExtendedContext is used to get application
- * related information maintained in YDT
- * @return YANG object builder node
+ * @param currentNode current YDT node for which object needs to be created
+ * @return handler to create the object
+ * @throws YobException if the YDT node type is not supported in YOB
*/
- YobHandler getYobHandlerForContext(
- YdtExtendedContext ydtExtendedContext) {
- YobHandler yobHandler =
- yobHandlerHashMap.get(ydtExtendedContext.getYdtType());
+ YobHandler getYobHandlerForContext(YdtExtendedContext currentNode) {
+ YobHandler yobHandler = HANDLER_MAP.get(currentNode.getYdtType());
if (yobHandler == null) {
- log.error(YDT_TYPE_IS_NOT_SUPPORT);
- return null;
+ log.error(E_YDT_TYPE_IS_NOT_SUPPORT);
+ throw new YobException(E_YDT_TYPE_IS_NOT_SUPPORT);
}
return yobHandler;
}
+
+ /**
+ * Returns the YANG object builder factory instance.
+ *
+ * @return YANG object builder factory instance
+ */
+ public 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.
+ */
+ private static class LazyHolder {
+ private static final YobHandlerFactory INSTANCE =
+ new YobHandlerFactory();
+ }
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java
index be52325..153f10f 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java
@@ -18,11 +18,12 @@
import org.onosproject.yms.app.ydt.YdtExtendedContext;
import org.onosproject.yms.app.ydt.YdtExtendedListener;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
+import org.onosproject.yms.app.yob.exception.YobException;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.onosproject.yms.ydt.YdtContext;
-import static org.onosproject.yms.app.yob.YobConstants.NO_HANDLE_FOR_YDT;
+import static org.onosproject.yms.app.yob.YobConstants.E_MISSING_DATA_IN_NODE;
+import static org.onosproject.yms.app.yob.YobHandlerFactory.instance;
/**
* Represents implementation of YANG object builder listener.
@@ -32,7 +33,7 @@
/**
* Reference to the ydt root node.
*/
- private YdtExtendedContext ydtRootNode;
+ private YdtExtendedContext rootNode;
/**
* Reference to YANG schema registry.
@@ -42,55 +43,65 @@
/**
* Reference to YOB handler.
*/
- private YobHandlerFactory yobHandlerFactory;
+ private YobHandlerFactory handlerFactory;
/**
* Creates an instance of YANG object builder listener.
*
- * @param ydtRootExtendedContext refers to YDT context
- * @param schemaRegistry refers to YANG schema registry
+ * @param rootNode refers to YDT context
+ * @param schemaRegistry refers to YANG schema registry
*/
- YobListener(YdtExtendedContext ydtRootExtendedContext,
+ YobListener(YdtExtendedContext rootNode,
YangSchemaRegistry schemaRegistry) {
- this.ydtRootNode = ydtRootExtendedContext;
+ this.rootNode = rootNode;
this.schemaRegistry = schemaRegistry;
- this.yobHandlerFactory = new YobHandlerFactory();
+ this.handlerFactory = instance();
}
@Override
- public void enterYdtNode(YdtExtendedContext ydtExtendedContext) {
+ public void enterYdtNode(YdtExtendedContext node) {
YobHandler nodeHandler =
- yobHandlerFactory.getYobHandlerForContext(ydtExtendedContext);
+ handlerFactory.getYobHandlerForContext(node);
- if (nodeHandler == null) {
- throw new YobExceptions(NO_HANDLE_FOR_YDT);
- }
- nodeHandler.createYangBuilderObject(ydtExtendedContext,
- ydtRootNode, schemaRegistry);
+ nodeHandler.createBuilder(node, rootNode, schemaRegistry);
}
@Override
- public void exitYdtNode(YdtExtendedContext ydtExtendedContext) {
+ public void exitYdtNode(YdtExtendedContext node) {
YobHandler nodeHandler =
- yobHandlerFactory.getYobHandlerForContext(ydtExtendedContext);
- if (nodeHandler != null) {
- nodeHandler.buildObjectFromBuilder(ydtExtendedContext,
- ydtRootNode, schemaRegistry);
- // The current ydt context node and root node are same then return.
- if (!ydtExtendedContext.equals(ydtRootNode)) {
- nodeHandler.setObjectInParent(ydtExtendedContext,
- schemaRegistry);
- }
+ handlerFactory.getYobHandlerForContext(node);
+
+ nodeHandler.buildObject(node, rootNode, schemaRegistry);
+
+ // The current ydt context node and root node are same then built
+ // object needs to be returned.
+ if (!node.equals(rootNode)) {
+ nodeHandler.setInParent(node, schemaRegistry);
}
+
}
+ /**
+ * Does not support walking of non extended context YDT.
+ *
+ * @param ydtContext YANG data tree context
+ * @throws YobException if YDT walker is not using extended context walker
+ */
@Override
public void enterYdtNode(YdtContext ydtContext) {
+ throw new YobException(E_MISSING_DATA_IN_NODE);
}
+ /**
+ * Does not support walking of non extended context YDT.
+ *
+ * @param ydtContext YANG data tree context
+ * @throws YobException if YDT walker is not using extended context walker
+ */
@Override
public void exitYdtNode(YdtContext ydtContext) {
+ throw new YobException(E_MISSING_DATA_IN_NODE);
}
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java
index 9ad458b..c59725a 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java
@@ -22,6 +22,7 @@
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.javadatamodel.JavaQualifiedTypeInfoContainer;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,7 +36,8 @@
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yms.app.ydt.AppType.YOB;
import static org.onosproject.yms.app.yob.YobConstants.ADD_TO;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_INVOKE_METHOD;
/**
* Represents a multi instance leaf node handler in YANG object builder.
@@ -47,43 +49,50 @@
LoggerFactory.getLogger(YobMultiInstanceLeafHandler.class);
@Override
- public void createYangBuilderObject(YdtExtendedContext curYdtNode,
- YdtExtendedContext rootYdtNode,
- YangSchemaRegistry registry) {
+ public void createBuilder(YdtExtendedContext curNode,
+ YdtExtendedContext rootNode,
+ YangSchemaRegistry registry) {
// For multi instance leaf no need to create an object.
}
@Override
- public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
- YdtExtendedContext ydtRootNode,
- YangSchemaRegistry schemaRegistry) {
+ public void buildObject(YdtExtendedContext ydtNode,
+ YdtExtendedContext ydtRootNode,
+ YangSchemaRegistry schemaRegistry) {
// For multi instance leaf no need to build object.
}
+ /**
+ * Set the leaf list values in the YANG object.
+ *
+ * @param leafListNode leaf list YDT node
+ * @param schemaRegistry YANG schema registry
+ * @throws YobException if failed to invoke the leaf list's setter
+ */
@Override
- public void setObjectInParent(YdtExtendedContext leafListYdtNode,
- YangSchemaRegistry schemaRegistry) {
+ public void setInParent(YdtExtendedContext leafListNode,
+ YangSchemaRegistry schemaRegistry) {
Class<?> parentBuilderClass = null;
- YangSchemaNode yangSchemaNode = leafListYdtNode.getYangSchemaNode();
+ YangSchemaNode yangSchemaNode = leafListNode.getYangSchemaNode();
YdtExtendedContext parentYdtNode =
- (YdtExtendedContext) leafListYdtNode.getParent();
+ (YdtExtendedContext) leafListNode.getParent();
YobWorkBench parentYobWorkBench =
(YobWorkBench) parentYdtNode.getAppInfo(YOB);
- Set<String> valueSet = leafListYdtNode.getValueSet();
+ Set<String> valueSet = leafListNode.getValueSet();
for (String value : valueSet) {
try {
String setterInParent = yangSchemaNode.getJavaAttributeName();
- Object parentBuilderObject = parentYobWorkBench
- .getParentBuilder(leafListYdtNode, schemaRegistry);
- parentBuilderClass = parentBuilderObject.getClass();
+ Object builderObject = parentYobWorkBench
+ .getParentBuilder(leafListNode, schemaRegistry);
+ parentBuilderClass = builderObject.getClass();
Field leafName = parentBuilderClass
.getDeclaredField(setterInParent);
ParameterizedType genericListType =
(ParameterizedType) leafName.getGenericType();
Class<?> genericListClass =
(Class<?>) genericListType.getActualTypeArguments()[0];
- Method parentSetterMethod =
+ Method setterMethod =
parentBuilderClass.getDeclaredMethod(
ADD_TO + getCapitalCase(setterInParent),
genericListClass);
@@ -91,11 +100,14 @@
(JavaQualifiedTypeInfoContainer) yangSchemaNode;
YangType<?> yangType =
((YangLeafList) javaQualifiedType).getDataType();
- setDataFromStringValue(yangType, value, parentSetterMethod,
- parentBuilderObject, leafListYdtNode);
+ YobUtils.setDataFromStringValue(yangType, value, setterMethod,
+ builderObject, leafListNode);
} catch (NoSuchMethodException | InvocationTargetException
| IllegalAccessException | NoSuchFieldException e) {
- log.error(FAIL_TO_INVOKE_METHOD + parentBuilderClass.getName());
+ log.error(L_FAIL_TO_INVOKE_METHOD,
+ parentBuilderClass.getName());
+ throw new YobException(E_FAIL_TO_INVOKE_METHOD +
+ parentBuilderClass.getName());
}
}
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java
index f6d8642..6840684 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java
@@ -19,9 +19,8 @@
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yangutils.datamodel.YangType;
-import org.onosproject.yangutils.datamodel.javadatamodel
- .JavaQualifiedTypeInfoContainer;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,7 +30,8 @@
import java.lang.reflect.Method;
import static org.onosproject.yms.app.ydt.AppType.YOB;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_INVOKE_METHOD;
/**
* Represents a single instance leaf node handler in YANG object builder.
@@ -42,46 +42,52 @@
LoggerFactory.getLogger(YobSingleInstanceLeafHandler.class);
@Override
- public void createYangBuilderObject(YdtExtendedContext curYdtNode,
- YdtExtendedContext rootYdtNode,
- YangSchemaRegistry registry) {
+ public void createBuilder(YdtExtendedContext curNode,
+ YdtExtendedContext rootNode,
+ YangSchemaRegistry registry) {
// For single instance leaf no need to create an object.
}
@Override
- public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
- YdtExtendedContext ydtRootNode,
- YangSchemaRegistry schemaRegistry) {
+ public void buildObject(YdtExtendedContext ydtNode,
+ YdtExtendedContext ydtRootNode,
+ YangSchemaRegistry schemaRegistry) {
// For single instance leaf no need to build an object.
}
+ /**
+ * Set the leaf's value in the YANG object.
+ *
+ * @param leafNode leaf YDT node
+ * @param schemaRegistry YANG schema registry
+ * @throws YobException if failed to invoke the leaf's setter
+ */
@Override
- public void setObjectInParent(YdtExtendedContext leafNode,
- YangSchemaRegistry schemaRegistry) {
- Class<?> parentBldrClass = null;
- YangSchemaNode yangSchemaNode = leafNode.getYangSchemaNode();
- YdtExtendedContext parentYdtNode =
- (YdtExtendedContext) leafNode.getParent();
- YobWorkBench parentYobWorkBench =
- (YobWorkBench) parentYdtNode.getAppInfo(YOB);
- String value = leafNode.getValue();
+ public void setInParent(YdtExtendedContext leafNode,
+ YangSchemaRegistry schemaRegistry) {
+ Class<?> builderClass = null;
try {
- String setterInParent = yangSchemaNode.getJavaAttributeName();
- Object parentBuilderObject = parentYobWorkBench
+ YangSchemaNode schemaNode = leafNode.getYangSchemaNode();
+ String setterInParent = schemaNode.getJavaAttributeName();
+ YdtExtendedContext parentNode =
+ (YdtExtendedContext) leafNode.getParent();
+ YobWorkBench workBench = (YobWorkBench) parentNode.getAppInfo(YOB);
+ Object builderObject = workBench
.getParentBuilder(leafNode, schemaRegistry);
- parentBldrClass = parentBuilderObject.getClass();
- Field leafName = parentBldrClass.getDeclaredField(setterInParent);
- Method parentSetterMethod = parentBldrClass
+ builderClass = builderObject.getClass();
+ Field leafName = builderClass.getDeclaredField(setterInParent);
+ Method setterMethod = builderClass
.getDeclaredMethod(setterInParent, leafName.getType());
- JavaQualifiedTypeInfoContainer javaQualifiedType =
- (JavaQualifiedTypeInfoContainer) yangSchemaNode;
- YangType<?> yangType = ((YangLeaf) javaQualifiedType).getDataType();
- setDataFromStringValue(yangType, value, parentSetterMethod,
- parentBuilderObject, leafNode);
+ YangType<?> yangType = ((YangLeaf) schemaNode).getDataType();
+ YobUtils.setDataFromStringValue(yangType, leafNode.getValue(),
+ setterMethod, builderObject,
+ leafNode);
} catch (NoSuchMethodException | InvocationTargetException |
IllegalAccessException | NoSuchFieldException e) {
- log.error(FAIL_TO_INVOKE_METHOD + parentBldrClass.getName());
+ log.error(L_FAIL_TO_INVOKE_METHOD, builderClass.getName());
+ throw new YobException(E_FAIL_TO_INVOKE_METHOD +
+ builderClass.getName());
}
}
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java
new file mode 100644
index 0000000..e8d226f
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2016-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.yms.app.yob;
+
+import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
+import org.onosproject.yangutils.datamodel.YangBinary;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
+import static org.onosproject.yms.app.ydt.AppType.YOB;
+import static org.onosproject.yms.app.yob.YobConstants.DEFAULT;
+import static org.onosproject.yms.app.yob.YobConstants.E_DATA_TYPE_NOT_SUPPORT;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CONSTRUCTOR;
+import static org.onosproject.yms.app.yob.YobConstants.E_INVALID_DATA_TREE;
+import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yms.app.yob.YobConstants.OF;
+import static org.onosproject.yms.app.yob.YobConstants.OP_PARAM;
+import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
+
+/**
+ * Utils to support object creation.
+ */
+final class YobUtils {
+
+ private static final Logger log = LoggerFactory.getLogger(YobUtils.class);
+
+ // no instantiation
+ private YobUtils() {
+ }
+
+ /**
+ * Sets data from string value in parent method.
+ *
+ * @param type refers to YANG type
+ * @param leafValue leafValue argument is used to set the value
+ * in method
+ * @param parentSetterMethod Invokes the underlying method represented
+ * by this parentSetterMethod
+ * @param parentBuilderObject the parentBuilderObject is to invoke the
+ * underlying method
+ * @param ydtExtendedContext ydtExtendedContext is used to get
+ * application related
+ * information maintained in YDT
+ * @throws InvocationTargetException if failed to invoke method
+ * @throws IllegalAccessException if member cannot be accessed
+ * @throws NoSuchMethodException if method is not found
+ */
+ static void setDataFromStringValue(YangType<?> type, String leafValue,
+ Method parentSetterMethod,
+ Object parentBuilderObject,
+ YdtExtendedContext ydtExtendedContext)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ switch (type.getDataType()) {
+ case INT8:
+ parentSetterMethod.invoke(parentBuilderObject,
+ Byte.parseByte(leafValue));
+ break;
+
+ case UINT8:
+ case INT16:
+ parentSetterMethod.invoke(parentBuilderObject,
+ Short.parseShort(leafValue));
+ break;
+
+ case UINT16:
+ case INT32:
+ parentSetterMethod.invoke(parentBuilderObject,
+ Integer.parseInt(leafValue));
+ break;
+
+ case UINT32:
+ case INT64:
+ parentSetterMethod.invoke(parentBuilderObject,
+ Long.parseLong(leafValue));
+ break;
+
+ case UINT64:
+ parentSetterMethod.invoke(parentBuilderObject,
+ new BigInteger(leafValue));
+ break;
+
+ case EMPTY:
+ case BOOLEAN:
+ parentSetterMethod.invoke(parentBuilderObject,
+ Boolean.parseBoolean(leafValue));
+ break;
+
+ case STRING:
+ parentSetterMethod.invoke(parentBuilderObject, leafValue);
+ break;
+
+ case BINARY:
+ parentSetterMethod.invoke(parentBuilderObject,
+ new YangBinary(leafValue));
+ break;
+
+ case BITS:
+ //TODO
+ break;
+
+ case DECIMAL64:
+ parentSetterMethod.invoke(parentBuilderObject,
+ new BigDecimal(leafValue));
+ break;
+
+ case DERIVED:
+ parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
+ parentBuilderObject, leafValue, false);
+ break;
+
+ case UNION:
+ // TODO
+ break;
+
+ case LEAFREF:
+ // TODO
+ break;
+
+ case ENUMERATION:
+ parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
+ parentBuilderObject, leafValue, true);
+ break;
+
+ default:
+ log.error(E_DATA_TYPE_NOT_SUPPORT);
+ }
+ }
+
+ /**
+ * To set data into parent setter method from string value for derived type.
+ *
+ * @param leafValue leafValue argument is used to set the value
+ * in method
+ * @param parentSetterMethod Invokes the underlying method represented
+ * by this parentSetterMethod
+ * @param parentBuilderObject the parentBuilderObject is to invoke the
+ * underlying method
+ * @param ydtExtendedContext ydtExtendedContext is used to get
+ * application related
+ * information maintained in YDT
+ * @param isEnum isEnum parameter is used to check whether
+ * type is enum or derived
+ * information maintained in YDT
+ * @throws InvocationTargetException if failed to invoke method
+ * @throws IllegalAccessException if member cannot be accessed
+ * @throws NoSuchMethodException if the required method is not found
+ */
+ private static void parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
+ Method parentSetterMethod,
+ Object parentBuilderObject,
+ String leafValue, boolean isEnum)
+ throws InvocationTargetException, IllegalAccessException,
+ NoSuchMethodException {
+ Class<?> childSetClass = null;
+ Constructor<?> childConstructor = null;
+ Object childValue = null;
+ Object childObject = null;
+ Method childMethod = null;
+
+ YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
+ String qualifiedClassName = yangJavaModule.getJavaPackage() + PERIOD +
+ getCapitalCase(yangJavaModule.getJavaClassNameOrBuiltInType());
+ ClassLoader classLoader = getClassLoader(null, qualifiedClassName,
+ ydtExtendedContext, null);
+ 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);
+ }
+ //leafValue = JavaIdentifierSyntax.getEnumJavaAttribute(leafValue);
+ //leafValue = leafValue.toUpperCase();
+ }
+ if (childMethod != null) {
+ childValue = childMethod.invoke(childObject, leafValue);
+ }
+
+ parentSetterMethod.invoke(parentBuilderObject, childValue);
+ }
+
+ /**
+ * Updates class loader for all the classes.
+ *
+ * @param registry YANG schema registry
+ * @param qualifiedClassName qualified class name
+ * @param curNode YDT context
+ * @param rootNode application root node
+ * @return current class loader
+ * @throws YobException if the YDT is an invalid tree
+ */
+ static ClassLoader getClassLoader(YangSchemaRegistry registry,
+ String qualifiedClassName,
+ YdtExtendedContext curNode,
+ YdtExtendedContext rootNode) {
+
+
+ if (rootNode != null && curNode == rootNode) {
+ YangSchemaNode curSchemaNode = curNode.getYangSchemaNode();
+ while (!(curSchemaNode instanceof RpcNotificationContainer)) {
+ curNode = (YdtExtendedContext) curNode.getParent();
+ if (curNode == null) {
+ throw new YobException(E_INVALID_DATA_TREE);
+ }
+ curSchemaNode = curNode.getYangSchemaNode();
+
+ }
+
+ Class<?> regClass = registry.getRegisteredClass(curSchemaNode,
+ qualifiedClassName);
+ return regClass.getClassLoader();
+
+ }
+
+ YdtExtendedContext parent =
+ (YdtExtendedContext) curNode.getParent();
+ YobWorkBench parentBuilderContainer =
+ (YobWorkBench) parent.getAppInfo(YOB);
+ Object parentObj =
+ parentBuilderContainer.getParentBuilder(curNode, registry);
+ return parentObj.getClass().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 registry schema registry
+ * @return class loader to be used for the switched context schema node
+ */
+ static ClassLoader getTargetClassLoader(
+ ClassLoader curLoader,
+ YangSchemaNodeContextInfo context,
+ YangSchemaRegistry registry) {
+ YangSchemaNode augmentSchemaNode = context.getContextSwitchedNode();
+ if (augmentSchemaNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
+ YangSchemaNode moduleNode =
+ ((YangNode) augmentSchemaNode).getParent();
+
+ Class<?> moduleClass = registry.getRegisteredClass(
+ moduleNode, getCapitalCase(
+ 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;
+ }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java
index 89720f4..29031ff 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java
@@ -16,15 +16,14 @@
package org.onosproject.yms.app.yob;
-import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
-import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
+import org.onosproject.yms.app.yob.exception.YobException;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,21 +38,26 @@
import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_CHOICE_NODE;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yms.app.ydt.AppType.YOB;
+import static org.onosproject.yms.app.yob.YobConstants.ADD_AUGMENT_METHOD;
import static org.onosproject.yms.app.yob.YobConstants.ADD_TO;
import static org.onosproject.yms.app.yob.YobConstants.BUILD;
-import static org.onosproject.yms.app.yob.YobConstants.DEFAULT;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_BUILD;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_GET_FIELD;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_GET_METHOD;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_INVOKE_METHOD;
-import static org.onosproject.yms.app.yob.YobConstants.HAS_NO_CHILD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_BUILD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_GET_FIELD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_GET_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yms.app.yob.YobConstants.E_HAS_NO_CHILD;
+import static org.onosproject.yms.app.yob.YobConstants.E_NO_HANDLE_FOR_YDT;
+import static org.onosproject.yms.app.yob.YobConstants.E_SET_OP_TYPE_FAIL;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_BUILD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_GET_FIELD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_GET_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_INVOKE_METHOD;
import static org.onosproject.yms.app.yob.YobConstants.OPERATION_TYPE;
-import static org.onosproject.yms.app.yob.YobConstants.OP_PARAM;
import static org.onosproject.yms.app.yob.YobConstants.OP_TYPE;
-import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
-import static org.onosproject.yms.app.yob.YobConstants.SET_OP_TYPE_FAIL;
import static org.onosproject.yms.app.yob.YobConstants.VALUE_OF;
import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
+import static org.onosproject.yms.ydt.YdtType.SINGLE_INSTANCE_NODE;
/**
* Represents the YANG object builder's work bench corresponding to a YANG data
@@ -61,8 +65,8 @@
*/
class YobWorkBench {
- private static final Logger log
- = LoggerFactory.getLogger(YobWorkBench.class);
+ private static final Logger log =
+ LoggerFactory.getLogger(YobWorkBench.class);
/**
* Class loader to be used to load the class.
@@ -72,8 +76,8 @@
/**
* Map of the non schema descendant objects.
*/
- private Map<YangSchemaNodeIdentifier, YobWorkBench> attributeMap
- = new HashMap<>();
+ private Map<YangSchemaNodeIdentifier, YobWorkBench> attributeMap =
+ new HashMap<>();
/**
* Reference for data-model schema node.
@@ -104,8 +108,8 @@
this.yangSchemaNode = yangSchemaNode;
this.classLoader = classLoader;
this.setterInParent = setterInParent;
- this.builderOrBuiltObject
- = new YobBuilderOrBuiltObject(qualifiedClassName, classLoader);
+ this.builderOrBuiltObject =
+ new YobBuilderOrBuiltObject(qualifiedClassName, classLoader);
}
/**
@@ -121,168 +125,124 @@
/**
* Returns the parent builder object in which the child object can be set.
*
- * @param childNode child YDT node
- * @param registry schema registry
+ * @param node child YDT node
+ * @param registry schema registry
* @return parent builder object
- * @throws YobExceptions schema node does not have child
+ * @throws YobException if schema node does not have child
*/
- Object getParentBuilder(YdtExtendedContext childNode,
+ Object getParentBuilder(YdtExtendedContext node,
YangSchemaRegistry registry) {
// Descendant schema node for whom the builder is required.
- YangSchemaNodeIdentifier targetNode = childNode
- .getYangSchemaNode().getYangSchemaNodeIdentifier();
+ YangSchemaNodeIdentifier targetNode =
+ node.getYangSchemaNode().getYangSchemaNodeIdentifier();
//Current builder container
YobWorkBench curWorkBench = this;
- //Current Schema node context
- YangSchemaNodeContextInfo schemaContext;
+ YangSchemaNode nonSchemaHolder;
do {
+ //Current Schema node context
+ YangSchemaNodeContextInfo schemaContext;
try {
//Find the new schema context node.
schemaContext = curWorkBench.yangSchemaNode.getChildSchema(
targetNode);
} catch (DataModelException e) {
- throw new YobExceptions(yangSchemaNode.getName() +
- HAS_NO_CHILD +
- targetNode.getName());
+ throw new YobException(yangSchemaNode.getName() +
+ E_HAS_NO_CHILD +
+ targetNode.getName());
}
+ nonSchemaHolder = schemaContext.getContextSwitchedNode();
+
//If the descendant schema node is in switched context
- if (schemaContext.getContextSwitchedNode() != null) {
+ if (nonSchemaHolder != null) {
+
+ YangSchemaNodeIdentifier nonSchemaIdentifier =
+ nonSchemaHolder.getYangSchemaNodeIdentifier();
//check if the descendant builder container is already available
- YobWorkBench childWorkBench
- = curWorkBench.attributeMap.get(targetNode);
+ YobWorkBench childWorkBench =
+ curWorkBench.attributeMap.get(nonSchemaIdentifier);
if (childWorkBench == null) {
YobWorkBench newWorkBench = getNewChildWorkBench(
schemaContext, targetNode, curWorkBench, registry);
- //TODO: When choice and case support is added, confirm with
- // UT, the workbench is for case and not for choice
-
- curWorkBench.attributeMap.put(targetNode, newWorkBench);
+ curWorkBench.attributeMap.put(nonSchemaIdentifier,
+ newWorkBench);
curWorkBench = newWorkBench;
} else {
curWorkBench = childWorkBench;
}
}
- } while (schemaContext.getContextSwitchedNode() != null);
+ } while (nonSchemaHolder != null);
return curWorkBench.builderOrBuiltObject.getBuilderObject();
}
/**
- * 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 schema registry
- * @return new builder container object corresponding to a context
- * switch schema node
- */
- private YobWorkBench getNewChildWorkBench(
- YangSchemaNodeContextInfo childContext,
- YangSchemaNodeIdentifier targetNode, YobWorkBench curWorkBench,
- YangSchemaRegistry registry) {
-
- YangSchemaNode ctxSwitchedNode = childContext.getContextSwitchedNode();
-
- /*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);
- } catch (DataModelException e) {
- throw new YobExceptions(yangSchemaNode.getName() +
- HAS_NO_CHILD +
- targetNode.getName());
- }
- }
-
- ClassLoader newClassesLoader = getTargetClassLoader(
- curWorkBench.classLoader, childContext, registry);
-
- return new YobWorkBench(ctxSwitchedNode, newClassesLoader,
- getQualifiedDefaultClassName(
- childContext.getSchemaNode()),
- setterInParent);
- }
-
- /**
- * Returns the qualified default / op param class.
- *
- * @param schemaNode schema node of the required class
- * @return qualified default / op param class name
- */
- static String getQualifiedDefaultClassName(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 class loader to be used for the switched context schema node.
- *
- * @param currentClassLoader current context class loader
- * @param switchedContext switched context
- * @param registry schema registry
- * @return class loader to be used for the switched context schema node
- */
- private ClassLoader getTargetClassLoader(
- ClassLoader currentClassLoader,
- YangSchemaNodeContextInfo switchedContext,
- YangSchemaRegistry registry) {
- YangSchemaNode augmentSchemaNode = switchedContext.getSchemaNode();
- if (augmentSchemaNode.getYangSchemaNodeType() ==
- YANG_AUGMENT_NODE) {
- YangSchemaNode parentSchemaNode =
- ((YangNode) augmentSchemaNode).getParent();
-
- Class<?> regClass = registry.getRegisteredClass(
- parentSchemaNode, getCapitalCase(
- parentSchemaNode.getJavaClassNameOrBuiltInType()));
- return regClass.getClassLoader();
- }
-
- return currentClassLoader;
- }
-
- /**
* Set the operation type attribute and build the object from the builder
* object, by invoking the build method.
*
- * @param ydtNode data tree node
- * @param ydtRootNode root node
+ * @param ydtNode data tree node
+ * @throws YobException if member method is not found or failed to build
*/
- void buildObject(YdtExtendedContext ydtNode,
- YdtExtendedContext ydtRootNode) {
+ void buildObject(YdtExtendedContext ydtNode) {
+
+ buildNonSchemaAttributes(ydtNode);
+
Object builderObject = builderOrBuiltObject.getBuilderObject();
Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
- Class<?> interfaceClass = builderOrBuiltObject.yangDefaultClass;
- Object operationType;
+
+ //set the operation type
+ setOperationType(ydtNode);
+
+ // Invoking the build method to get built object from build method.
+ try {
+ Method method = defaultBuilderClass.getDeclaredMethod(BUILD);
+ if (method == null) {
+ log.error(L_FAIL_TO_GET_METHOD, defaultBuilderClass.getName());
+ throw new YobException(E_FAIL_TO_GET_METHOD +
+ defaultBuilderClass.getName());
+ }
+ Object builtObject = method.invoke(builderObject);
+ // The built object will be maintained in ydt context and same will
+ // be used while setting into parent method.
+ builderOrBuiltObject.setBuiltObject(builtObject);
+
+ } catch (NoSuchMethodException | InvocationTargetException |
+ IllegalAccessException e) {
+ log.error(L_FAIL_TO_BUILD, defaultBuilderClass.getName());
+ throw new YobException(E_FAIL_TO_BUILD +
+ defaultBuilderClass.getName());
+ }
+ }
+
+ /**
+ * Set the operation type in the built object from the YDT node.
+ * <p>
+ * It needs to be invoked only for the workbench corresponding to the
+ * schema YDT nodes, non schema node without the YDT node should not
+ * invoke this, as it is not applicable to it.
+ *
+ * @param ydtNode schema data tree node
+ * @throws YobException if fail to set the operation type
+ */
+ private void setOperationType(YdtExtendedContext ydtNode) {
+
+ Object builderObject = builderOrBuiltObject.getBuilderObject();
+ Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
// Setting the value into YANG node operation type from ydtContext
// operation type.
try {
+ Class<?> interfaceClass = builderOrBuiltObject.yangDefaultClass;
+ Object operationType;
Class<?>[] innerClasses = interfaceClass.getClasses();
for (Class<?> innerEnumClass : innerClasses) {
if (innerEnumClass.getSimpleName().equals(OP_TYPE)) {
@@ -301,92 +261,206 @@
}
} catch (NoSuchFieldException | NoSuchMethodException |
InvocationTargetException | IllegalAccessException e) {
- log.error(SET_OP_TYPE_FAIL);
- throw new YobExceptions(SET_OP_TYPE_FAIL);
- }
-
-
- // Invoking the build method to get built object from build method.
- try {
- Method method = defaultBuilderClass.getDeclaredMethod(BUILD);
- if (method == null) {
- log.error(FAIL_TO_GET_METHOD + defaultBuilderClass.getName());
- throw new YobExceptions(FAIL_TO_GET_METHOD +
- defaultBuilderClass.getName());
- }
- Object builtObject = method.invoke(builderObject);
- // The built object will be maintained in ydt context and same will
- // be used while setting into parent method.
- builderOrBuiltObject.setBuiltObject(builtObject);
-
- } catch (NoSuchMethodException | InvocationTargetException |
- IllegalAccessException e) {
- log.error(FAIL_TO_BUILD + defaultBuilderClass.getName());
- throw new YobExceptions(FAIL_TO_BUILD +
- defaultBuilderClass.getName());
- }
-
- // The current ydt context node and root node are same then return.
- if (!ydtNode.equals(ydtRootNode)) {
- invokeSetObjectInParent(ydtNode);
+ log.error(E_SET_OP_TYPE_FAIL);
+ throw new YobException(E_SET_OP_TYPE_FAIL);
}
}
/**
+ * build the non schema objects and maintain it in the contained schema
+ * node.
+ *
+ * @param ydtNode contained schema node
+ */
+ private void buildNonSchemaAttributes(YdtExtendedContext ydtNode) {
+ for (Map.Entry<YangSchemaNodeIdentifier, YobWorkBench> entry :
+ attributeMap.entrySet()) {
+ YobWorkBench childWorkBench = entry.getValue();
+ childWorkBench.buildObject(ydtNode);
+
+ if (childWorkBench.yangSchemaNode.getYangSchemaNodeType() ==
+ YANG_AUGMENT_NODE) {
+ addInAugmentation(builderOrBuiltObject.getBuilderObject(),
+ childWorkBench.setterInParent,
+ childWorkBench.getBuilderOrBuiltObject()
+ .getBuiltObject());
+ return;
+ }
+
+ setObjectInBuilder(
+ builderOrBuiltObject.getBuilderObject(),
+ childWorkBench.setterInParent,
+ SINGLE_INSTANCE_NODE,
+ childWorkBench.getBuilderOrBuiltObject().getBuiltObject());
+ }
+ }
+
+
+ //TODO add objectIn Augmentation
+
+ /**
* Sets the YANG built object in corresponding parent class method.
*
* @param ydtNode ydtExtendedContext is used to get application
* related information maintained in YDT
+ * @throws YobException if there is no parent's YOB handler
*/
- private void invokeSetObjectInParent(YdtExtendedContext ydtNode) {
- Class<?> classType = null;
- Method method;
-
+ void setObjectInParent(YdtExtendedContext ydtNode) {
+ YdtExtendedContext parentNode =
+ (YdtExtendedContext) ydtNode.getParent();
+ if (parentNode == null || parentNode.getAppInfo(YOB) == null) {
+ throw new YobException(E_NO_HANDLE_FOR_YDT);
+ }
+ YobWorkBench parentWorkBench =
+ (YobWorkBench) parentNode.getAppInfo(YOB);
+ Object parentBuilderObject =
+ parentWorkBench.builderOrBuiltObject.getBuilderObject();
+ YdtType nodeType = ydtNode.getYdtType();
Object objectToSetInParent = builderOrBuiltObject.getBuiltObject();
- YdtExtendedContext parentNode = (YdtExtendedContext) ydtNode
- .getParent();
- if (parentNode != null) {
- YobWorkBench parentYobWorkBench = (YobWorkBench)
- parentNode.getAppInfo(YOB);
- Object parentBuilderObject = parentYobWorkBench
- .builderOrBuiltObject.getBuilderObject();
+ // set the object in the parent builder
+ setObjectInBuilder(parentBuilderObject, setterInParent, nodeType,
+ objectToSetInParent);
- Class<?> parentBuilderClass = parentBuilderObject.getClass();
- String parentBuilderClassName = parentBuilderClass.getName();
-
- try {
- Field fieldName = parentBuilderClass
- .getDeclaredField(setterInParent);
- if (fieldName != null) {
- classType = fieldName.getType();
- }
-
- if (ydtNode.getYdtType() == MULTI_INSTANCE_NODE) {
- if (fieldName != null) {
- ParameterizedType genericListType =
- (ParameterizedType) fieldName.getGenericType();
- classType = (Class<?>) genericListType
- .getActualTypeArguments()[0];
- }
- method = parentBuilderClass.getDeclaredMethod(
- ADD_TO + getCapitalCase(setterInParent), classType);
- } else {
- method = parentBuilderClass.getDeclaredMethod(
- setterInParent, classType);
- }
-
- if (method != null) {
- method.invoke(parentBuilderObject, objectToSetInParent);
- }
- } catch (NoSuchFieldException e) {
- log.error(FAIL_TO_GET_FIELD + parentBuilderClassName);
- } catch (NoSuchMethodException e) {
- log.error(FAIL_TO_GET_METHOD + parentBuilderClassName);
- } catch (InvocationTargetException | IllegalAccessException e) {
- log.error(FAIL_TO_INVOKE_METHOD + parentBuilderClassName);
- }
- }
ydtNode.addAppInfo(YOB, this);
}
+
+ /**
+ * Set the attribute in a builder object.
+ *
+ * @param builder builder object in which the attribute needs to be
+ * set
+ * @param setter setter method in parent
+ * @param nodeType type of node to set
+ * @param attribute attribute to set in the builder
+ * @throws YobException if member is not found or failed to invoke the
+ * method
+ */
+ private static void setObjectInBuilder(Object builder, String setter,
+ YdtType nodeType, Object attribute) {
+ Class<?> builderClass = builder.getClass();
+ String builderClassName = builderClass.getName();
+ try {
+ Class<?> type = null;
+ Field fieldName = builderClass.getDeclaredField(setter);
+ if (fieldName != null) {
+ type = fieldName.getType();
+ }
+
+ Method method;
+ if (nodeType == MULTI_INSTANCE_NODE) {
+ if (fieldName != null) {
+ ParameterizedType genericTypes =
+ (ParameterizedType) fieldName.getGenericType();
+ type = (Class<?>) genericTypes.getActualTypeArguments()[0];
+ }
+ method = builderClass.getDeclaredMethod(
+ ADD_TO + getCapitalCase(setter), type);
+ } else {
+ method = builderClass.getDeclaredMethod(setter, type);
+ }
+
+ method.invoke(builder, attribute);
+ } catch (NoSuchFieldException e) {
+ log.error(L_FAIL_TO_GET_FIELD, builderClassName);
+ throw new YobException(E_FAIL_TO_GET_FIELD + builderClassName);
+ } catch (NoSuchMethodException e) {
+ log.error(L_FAIL_TO_GET_METHOD, builderClassName);
+ throw new YobException(E_FAIL_TO_GET_METHOD + builderClassName);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ log.error(L_FAIL_TO_INVOKE_METHOD, builderClassName);
+ throw new YobException(E_FAIL_TO_INVOKE_METHOD + builderClassName);
+ }
+ }
+
+ private static void addInAugmentation(Object builder, String className,
+ Object instance) {
+ Class<?>[] interfaces = instance.getClass().getInterfaces();
+ if (interfaces == null) {
+ throw new YobException(E_FAIL_TO_LOAD_CLASS + className);
+ }
+
+ int i;
+ for (i = 0; i < interfaces.length; i++) {
+ if (interfaces[i].getName().equals(className)) {
+ break;
+ }
+ }
+ if (i == interfaces.length) {
+ throw new YobException(E_FAIL_TO_LOAD_CLASS + className);
+ }
+
+ Class<?> builderClass = builder.getClass();
+ String builderClassName = builderClass.getName();
+ try {
+
+ Method method = builderClass.getDeclaredMethod(ADD_AUGMENT_METHOD,
+ Object.class,
+ Class.class);
+ method.invoke(builder, instance, interfaces[i]);
+ } catch (NoSuchMethodException e) {
+ log.error(L_FAIL_TO_GET_METHOD, builderClassName);
+ throw new YobException(E_FAIL_TO_GET_METHOD + builderClassName);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ log.error(L_FAIL_TO_INVOKE_METHOD, builderClassName);
+ throw new YobException(E_FAIL_TO_INVOKE_METHOD + builderClassName);
+ }
+
+ }
+
+
+ /**
+ * 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 schema registry
+ * @return new builder container object corresponding to a context
+ * switch schema node
+ * @throws YobException if expected child is not found in schema
+ */
+ private static YobWorkBench getNewChildWorkBench(
+ YangSchemaNodeContextInfo childContext,
+ YangSchemaNodeIdentifier targetNode, YobWorkBench curWorkBench,
+ YangSchemaRegistry 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 = YobUtils.getQualifiedDefaultClass(
+ childContext.getContextSwitchedNode());
+
+ } catch (DataModelException e) {
+ throw new YobException(ctxSwitchedNode.getName() +
+ E_HAS_NO_CHILD +
+ targetNode.getName());
+ }
+ } else if (ctxSwitchedNode.getYangSchemaNodeType() ==
+ YANG_AUGMENT_NODE) {
+ name = YobUtils.getQualifiedDefaultClass(ctxSwitchedNode);
+ setterInParent = YobUtils.getQualifiedinterface(ctxSwitchedNode);
+ } else {
+ name = YobUtils.getQualifiedDefaultClass(childContext.getSchemaNode());
+ }
+
+ ClassLoader newClassesLoader = YobUtils.getTargetClassLoader(
+ curWorkBench.classLoader, childContext, registry);
+
+ return new YobWorkBench(ctxSwitchedNode, newClassesLoader, name,
+ setterInParent);
+ }
+
}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobExceptions.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobException.java
similarity index 93%
rename from apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobExceptions.java
rename to apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobException.java
index b7e5bb5..e8ce1a0 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobExceptions.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobException.java
@@ -19,7 +19,7 @@
/**
* Represents base class for exceptions in YOB operations.
*/
-public class YobExceptions
+public class YobException
extends RuntimeException {
private static final long serialVersionUID = 20160211L;
@@ -29,7 +29,7 @@
*
* @param message the detail of exception in string
*/
- public YobExceptions(String message) {
+ public YobException(String message) {
super(message);
}
}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobAugmentTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobAugmentTest.java
new file mode 100644
index 0000000..a50d3a5
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobAugmentTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
+ * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
+ * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
+ * Vestibulum commodo. Ut rhoncus gravida arcu.
+ */
+
+package org.onosproject.yms.app.yob;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.ip.topo.rev20140101.ymsiptopology.node.AugmentedTopoNode;
+import org.onosproject.yang.gen.v1.urn.ip.topo.rev20140101.ymsiptopology.node.DefaultAugmentedTopoNode;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.YmsTopologyOpParam;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.DefaultNode;
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.ydt.YdtContext;
+
+import java.io.IOException;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.onosproject.yms.app.yob.YobTestUtils.NODE;
+import static org.onosproject.yms.app.yob.YobTestUtils.ROOT_DATA_RESOURCE;
+import static org.onosproject.yms.app.yob.YobTestUtils.ROUTER_ID;
+import static org.onosproject.yms.app.yob.YobTestUtils.ROUTER_IP;
+import static org.onosproject.yms.app.yob.YobTestUtils.STR_LEAF_VALUE;
+import static org.onosproject.yms.app.yob.YobTestUtils.TOPOLOGY;
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+
+/**
+ * Test the YANG object building for the YANG data tree based on the non
+ * schema augmented nodes.
+ */
+public class YobAugmentTest {
+
+ private YobTestUtils utils = YobTestUtils.instance();
+
+ @Test
+ public void augmentedLeaf() throws IOException {
+
+ YangRequestWorkBench ydtBuilder = new YangRequestWorkBench(
+ ROOT_DATA_RESOURCE, null, null, utils.schemaRegistry(),
+ true);
+
+ ydtBuilder.addChild(TOPOLOGY, null, NONE);
+ ydtBuilder.addChild(NODE, null);
+ ydtBuilder.addLeaf(ROUTER_ID, "urn:ip:topo", STR_LEAF_VALUE);
+
+ YdtContext logicalRoot = ydtBuilder.getRootNode();
+ YdtExtendedContext appRoot =
+ (YdtExtendedContext) logicalRoot.getFirstChild();
+
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+ Object yangObject = yobBuilder.getYangObject(appRoot,
+ utils.schemaRegistry());
+ assertNotNull("Fail to create augmented YANG object", yangObject);
+
+ assertEquals("invalid augmented node created", YmsTopologyOpParam.class,
+ yangObject.getClass());
+
+ YmsTopologyOpParam topology = (YmsTopologyOpParam) yangObject;
+ assertNotNull("failed to build augmented node", topology.node());
+ assertEquals("Single node entry is expected", 1, topology.node().size());
+ assertEquals("Node type is not DefaultNode", DefaultNode.class,
+ topology.node().get(0).getClass());
+
+ DefaultNode node = (DefaultNode) topology.node().get(0);
+ assertNotNull("Augmented info is missing", node.yangAugmentedInfo(
+ AugmentedTopoNode.class));
+ assertEquals("Augmented class is incorrect",
+ DefaultAugmentedTopoNode.class,
+ node.yangAugmentedInfo(AugmentedTopoNode.class)
+ .getClass());
+
+ DefaultAugmentedTopoNode augmentedNode = (DefaultAugmentedTopoNode)
+ node.yangAugmentedInfo(AugmentedTopoNode.class);
+ assertThat("Augmented leaf value is incorrect",
+ augmentedNode.routerId(), is(STR_LEAF_VALUE));
+ }
+
+ @Test
+ public void augmentedLeaves() throws IOException {
+
+ YangRequestWorkBench ydtBuilder = new YangRequestWorkBench(
+ ROOT_DATA_RESOURCE, null, null, utils.schemaRegistry(),
+ true);
+
+ ydtBuilder.addChild(TOPOLOGY, null, NONE);
+ ydtBuilder.addChild(NODE, null);
+ ydtBuilder.addLeaf(ROUTER_ID, "urn:ip:topo", STR_LEAF_VALUE);
+ ydtBuilder.traverseToParent();
+ ydtBuilder.addLeaf(ROUTER_IP, "urn:ip:topo", STR_LEAF_VALUE);
+
+ YdtContext logicalRoot = ydtBuilder.getRootNode();
+ YdtExtendedContext appRoot =
+ (YdtExtendedContext) logicalRoot.getFirstChild();
+
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+ Object yangObject = yobBuilder.getYangObject(appRoot,
+ utils.schemaRegistry());
+ assertNotNull("Fail to create augmented YANG object", yangObject);
+
+ assertEquals("invalid augmented node created",
+ YmsTopologyOpParam.class, yangObject.getClass());
+
+ YmsTopologyOpParam topology = (YmsTopologyOpParam) yangObject;
+ assertNotNull("failed to build augmented node", topology.node());
+ assertEquals("Single node entry is expected", 1,
+ topology.node().size());
+ assertEquals("Node type is not DefaultNode", DefaultNode.class,
+ topology.node().get(0).getClass());
+
+ DefaultNode node = (DefaultNode) topology.node().get(0);
+ assertNotNull("Augmented info is missing", node.yangAugmentedInfo(
+ AugmentedTopoNode.class));
+ assertEquals("Augmented class is incorrect",
+ DefaultAugmentedTopoNode.class,
+ node.yangAugmentedInfo(AugmentedTopoNode.class)
+ .getClass());
+
+ DefaultAugmentedTopoNode augmentedNode = (DefaultAugmentedTopoNode)
+ node.yangAugmentedInfo(AugmentedTopoNode.class);
+ assertThat("Augmented router id is incorrect",
+ augmentedNode.routerId(), is(STR_LEAF_VALUE));
+ assertThat("Augmented router ip is incorrect",
+ augmentedNode.routerIp(), is(STR_LEAF_VALUE));
+ }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobChoiceTest.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobChoiceTest.java
new file mode 100644
index 0000000..305d7bf
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobChoiceTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2016-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.yms.app.yob;
+
+import org.junit.Test;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.YmsTopologyOpParam;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.DefaultNode;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.Node;
+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.DefaultCase1a;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.node.choice1.DefaultCase1b;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.node.choice1.case1b.choice1b.Case1Bi;
+import org.onosproject.yang.gen.v1.urn.topo.rev20140101.ymstopology.node.choice1.case1b.choice1b.DefaultCase1Bi;
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.ydt.YdtContext;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.onosproject.yms.app.yob.YobTestUtils.LEAF_1A1;
+import static org.onosproject.yms.app.yob.YobTestUtils.LEAF_1A2;
+import static org.onosproject.yms.app.yob.YobTestUtils.LEAF_1BIA;
+import static org.onosproject.yms.app.yob.YobTestUtils.LEAF_1BIB;
+import static org.onosproject.yms.app.yob.YobTestUtils.NODE;
+import static org.onosproject.yms.app.yob.YobTestUtils.ROOT_DATA_RESOURCE;
+import static org.onosproject.yms.app.yob.YobTestUtils.STR_LEAF_VALUE;
+import static org.onosproject.yms.app.yob.YobTestUtils.TOPOLOGY;
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+
+/**
+ * Test the YANG object building for the YANG data tree based on the non
+ * schema choice and case nodes.
+ */
+public class YobChoiceTest {
+
+ private YobTestUtils utils = YobTestUtils.instance();
+
+ @Test
+ public void caseInChoice() throws IOException {
+
+ YangRequestWorkBench ydtBuilder = new YangRequestWorkBench(
+ ROOT_DATA_RESOURCE, null, null, utils.schemaRegistry(),
+ true);
+
+ ydtBuilder.addChild(TOPOLOGY, null, NONE);
+ ydtBuilder.addChild(NODE, null);
+ ydtBuilder.addLeaf(LEAF_1A1, null, STR_LEAF_VALUE);
+
+ YdtContext logicalRoot = ydtBuilder.getRootNode();
+ YdtExtendedContext appRoot =
+ (YdtExtendedContext) logicalRoot.getFirstChild();
+
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+ Object yangObject = yobBuilder.getYangObject(appRoot,
+ utils.schemaRegistry());
+ assertNotNull(yangObject);
+ assertEquals("YANG object created is not topology object",
+ YmsTopologyOpParam.class, yangObject.getClass());
+
+ YmsTopologyOpParam topology = (YmsTopologyOpParam) yangObject;
+ assertNotNull("Failed to build the object", topology.node());
+ assertEquals("Single node entry is expected", 1,
+ topology.node().size());
+ assertEquals("Node type is not DefaultNode", DefaultNode.class,
+ topology.node().get(0).getClass());
+
+ Node node = topology.node().get(0);
+ assertNotNull("choice1 is not set in node", node.choice1());
+ assertEquals("choice 1 type is not ", DefaultCase1a.class,
+ node.choice1().getClass());
+
+ Case1a case1a = (Case1a) node.choice1();
+ assertNotNull("leaf1a1 is not set in case", case1a.leaf1A1());
+ assertEquals("leaf1a1 type is not correct", String.class,
+ case1a.leaf1A1().getClass());
+ assertEquals("leaf1a1 value is not correct", STR_LEAF_VALUE,
+ case1a.leaf1A1());
+
+ }
+
+ @Test
+ public void caseWithMultiAttribute() throws IOException {
+
+ YangRequestWorkBench ydtBuilder = new YangRequestWorkBench(
+ ROOT_DATA_RESOURCE, null, null, utils.schemaRegistry(),
+ true);
+
+ ydtBuilder.addChild(TOPOLOGY, null, NONE);
+ ydtBuilder.addChild(NODE, null);
+ ydtBuilder.addLeaf(LEAF_1A1, null, STR_LEAF_VALUE);
+ ydtBuilder.traverseToParent();
+ ydtBuilder.addLeaf(LEAF_1A2, null, STR_LEAF_VALUE);
+
+ YdtContext logicalRoot = ydtBuilder.getRootNode();
+ YdtExtendedContext appRoot =
+ (YdtExtendedContext) logicalRoot.getFirstChild();
+
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+ Object yangObject = yobBuilder.getYangObject(appRoot,
+ utils.schemaRegistry());
+ assertNotNull(yangObject);
+ assertEquals("YANG object created is not topology object",
+ YmsTopologyOpParam.class, yangObject.getClass());
+
+ YmsTopologyOpParam topology = (YmsTopologyOpParam) yangObject;
+ assertNotNull("Failed to build the object", topology.node());
+ assertEquals("Single node entry is expected", 1,
+ topology.node().size());
+ assertEquals("Node type is not DefaultNode", DefaultNode.class,
+ topology.node().get(0).getClass());
+
+ Node node = topology.node().get(0);
+ assertNotNull("choice1 is not set in node", node.choice1());
+ assertEquals("choice 1 type is not ", DefaultCase1a.class,
+ node.choice1().getClass());
+
+ Case1a case1a = (Case1a) node.choice1();
+ assertNotNull("leaf1a1 is not set in case", case1a.leaf1A1());
+ assertEquals("leaf1a1 type is not correct", String.class,
+ case1a.leaf1A1().getClass());
+ assertEquals("leaf1a1 value is not correct", STR_LEAF_VALUE,
+ case1a.leaf1A1());
+
+ assertNotNull("leaf1a2 is not set in case", case1a.leaf1A2());
+ assertEquals("leaf1a2 type is not correct", String.class,
+ case1a.leaf1A2().getClass());
+ assertEquals("leaf1a1 value is not correct", STR_LEAF_VALUE,
+ case1a.leaf1A1());
+
+ }
+
+ @Test
+ public void recursiveChoice() throws IOException {
+
+ YangRequestWorkBench ydtBuilder = new YangRequestWorkBench(
+ ROOT_DATA_RESOURCE, null, null, utils.schemaRegistry(),
+ true);
+
+ ydtBuilder.addChild(TOPOLOGY, null, NONE);
+ ydtBuilder.addChild(NODE, null);
+ ydtBuilder.addLeaf(LEAF_1BIA, null, STR_LEAF_VALUE);
+
+ YdtContext logicalRoot = ydtBuilder.getRootNode();
+ YdtExtendedContext appRoot =
+ (YdtExtendedContext) logicalRoot.getFirstChild();
+
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+ Object yangObject = yobBuilder.getYangObject(appRoot,
+ utils.schemaRegistry());
+ assertNotNull(yangObject);
+ assertEquals("YANG object created is not topology object",
+ YmsTopologyOpParam.class, yangObject.getClass());
+
+ YmsTopologyOpParam topology = (YmsTopologyOpParam) yangObject;
+ assertNotNull("Failed to build the object", topology.node());
+ assertEquals("Single node entry is expected", 1,
+ topology.node().size());
+ assertEquals("Node type is not DefaultNode", DefaultNode.class,
+ topology.node().get(0).getClass());
+
+ Node node = topology.node().get(0);
+ assertNotNull("Choice 1 is not set in Node", node.choice1());
+ assertEquals("Choice 1 is not of type DefaultCase1b",
+ DefaultCase1b.class, node.choice1().getClass());
+
+ Case1b case1b = (Case1b) node.choice1();
+ assertNotNull("Case1b does not have child choice1b ",
+ case1b.choice1b());
+ assertEquals("choice1b is not of type DefaultCase1Bi",
+ DefaultCase1Bi.class, case1b.choice1b().getClass());
+
+ Case1Bi case1Bi = (Case1Bi) case1b.choice1b();
+ assertNotNull("leaf1bia is not set", case1Bi.leaf1Bia());
+ assertEquals("leaf1bia type is not string", String.class,
+ case1Bi.leaf1Bia().getClass());
+ assertEquals("leaf1bia value is wrong", STR_LEAF_VALUE,
+ case1Bi.leaf1Bia());
+ }
+
+ @Test
+ public void recursiveChoiceWithMultipleAttribute() throws IOException {
+
+ YangRequestWorkBench ydtBuilder = new YangRequestWorkBench(
+ ROOT_DATA_RESOURCE, null, null, utils.schemaRegistry(),
+ true);
+
+ ydtBuilder.addChild(TOPOLOGY, null, NONE);
+ ydtBuilder.addChild(NODE, null);
+ ydtBuilder.addLeaf(LEAF_1BIA, null, STR_LEAF_VALUE);
+ ydtBuilder.traverseToParent();
+ ydtBuilder.addLeaf(LEAF_1BIB, null, STR_LEAF_VALUE);
+
+
+ YdtContext logicalRoot = ydtBuilder.getRootNode();
+ YdtExtendedContext appRoot =
+ (YdtExtendedContext) logicalRoot.getFirstChild();
+
+ DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
+ Object yangObject = yobBuilder.getYangObject(appRoot,
+ utils.schemaRegistry());
+ assertNotNull(yangObject);
+ assertEquals("YANG object created is not topology object",
+ YmsTopologyOpParam.class, yangObject.getClass());
+
+ YmsTopologyOpParam topology = (YmsTopologyOpParam) yangObject;
+ assertNotNull("Failed to build the object", topology.node());
+ assertEquals("Single node entry is expected", 1,
+ topology.node().size());
+ assertEquals("Node type is not DefaultNode", DefaultNode.class,
+ topology.node().get(0).getClass());
+
+ Node node = topology.node().get(0);
+ assertNotNull("Choice 1 is not set in Node", node.choice1());
+ assertEquals("Choice 1 is not of type DefaultCase1b",
+ DefaultCase1b.class,
+ node.choice1().getClass());
+
+ Case1b case1b = (Case1b) node.choice1();
+ assertNotNull("Case1b does not have child choice1b ",
+ case1b.choice1b());
+ assertEquals("choice1b is not of type DefaultCase1Bi",
+ DefaultCase1Bi.class,
+ case1b.choice1b().getClass());
+
+ Case1Bi case1Bi = (Case1Bi) case1b.choice1b();
+ assertNotNull("leaf1bia is not set", case1Bi.leaf1Bia());
+ assertEquals("leaf1bia type is not string", String.class,
+ case1Bi.leaf1Bia().getClass());
+ assertEquals("leaf1bia value is wrong", STR_LEAF_VALUE,
+ case1Bi.leaf1Bia());
+
+ assertNotNull("leaf1bib is not set", case1Bi.leaf1Bib());
+ assertEquals("leaf1bia type is not string", String.class,
+ case1Bi.leaf1Bib().getClass());
+ assertEquals("leaf1bia value is wrong", STR_LEAF_VALUE,
+ case1Bi.leaf1Bib());
+ }
+}
diff --git a/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobTestUtils.java b/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobTestUtils.java
new file mode 100644
index 0000000..17b41dd
--- /dev/null
+++ b/apps/yms/app/src/test/java/org/onosproject/yms/app/yob/YobTestUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2016-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.yms.app.yob;
+
+import org.onosproject.yms.app.ysr.TestYangSchemaNodeProvider;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+
+/**
+ * YOB test Utility.
+ */
+final class YobTestUtils {
+
+ /**
+ * Schema nodes.
+ */
+ static final String ROOT_DATA_RESOURCE = "/restconf/data";
+ static final String TOPOLOGY = "yms-topology";
+ static final String NODE = "node";
+ static final String LEAF_1A1 = "leaf1a1";
+ static final String LEAF_1A2 = "leaf1a2";
+ static final String LEAF_1BIA = "leaf1bia";
+ static final String LEAF_1BIB = "leaf1bib";
+ static final String ROUTER_ID = "router-id";
+ static final String ROUTER_IP = "router-ip";
+ static final String STR_LEAF_VALUE = "leaf value";
+
+ private YobTestUtils() {
+ TEST_SCHEMA_PROVIDER.processSchemaRegistry(null);
+ }
+
+ private static final TestYangSchemaNodeProvider
+ TEST_SCHEMA_PROVIDER = new TestYangSchemaNodeProvider();
+
+ YangSchemaRegistry schemaRegistry() {
+ return TEST_SCHEMA_PROVIDER.getDefaultYangSchemaRegistry();
+ }
+
+ /**
+ * Returns the YANG object builder factory instance.
+ *
+ * @return YANG object builder factory instance
+ */
+ static YobTestUtils 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.
+ */
+ private static class LazyHolder {
+ private static final YobTestUtils INSTANCE = new YobTestUtils();
+ }
+}
diff --git a/apps/yms/app/src/test/resources/YobTestYangFiles/ip-topology.yang b/apps/yms/app/src/test/resources/YobTestYangFiles/ip-topology.yang
new file mode 100644
index 0000000..ca117b7
--- /dev/null
+++ b/apps/yms/app/src/test/resources/YobTestYangFiles/ip-topology.yang
@@ -0,0 +1,29 @@
+
+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/apps/yms/app/src/test/resources/YobTestYangFiles/topology.yang b/apps/yms/app/src/test/resources/YobTestYangFiles/topology.yang
new file mode 100644
index 0000000..62c0279
--- /dev/null
+++ b/apps/yms/app/src/test/resources/YobTestYangFiles/topology.yang
@@ -0,0 +1,74 @@
+
+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;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ rpc set-node-limit {
+ input {
+ leaf node-limit {
+ type int16;
+ }
+ }
+ }
+
+ notification node-limit-reached {
+ leaf node-limit {
+ type int16;
+ }
+ }
+}