blob: 4f1b70793a8927e495b4a44ba97a22717b0ded0f [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yang.runtime.impl;
import org.onosproject.yang.compiler.datamodel.RpcNotificationContainer;
import org.onosproject.yang.compiler.datamodel.YangIdentity;
import org.onosproject.yang.compiler.datamodel.YangIdentityRef;
import org.onosproject.yang.compiler.datamodel.YangLeaf;
import org.onosproject.yang.compiler.datamodel.YangLeafList;
import org.onosproject.yang.compiler.datamodel.YangLeafRef;
import org.onosproject.yang.compiler.datamodel.YangLeavesHolder;
import org.onosproject.yang.compiler.datamodel.YangList;
import org.onosproject.yang.compiler.datamodel.YangNode;
import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
import org.onosproject.yang.compiler.datamodel.YangSchemaNodeContextInfo;
import org.onosproject.yang.compiler.datamodel.YangType;
import org.onosproject.yang.compiler.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.model.InnerModelObject;
import org.onosproject.yang.model.KeyInfo;
import org.onosproject.yang.model.KeyLeaf;
import org.onosproject.yang.model.LeafIdentifier;
import org.onosproject.yang.model.LeafListKey;
import org.onosproject.yang.model.LeafModelObject;
import org.onosproject.yang.model.LeafNode;
import org.onosproject.yang.model.ListKey;
import org.onosproject.yang.model.ModelConverterException;
import org.onosproject.yang.model.ModelObject;
import org.onosproject.yang.model.ModelObjectId;
import org.onosproject.yang.model.MultiInstanceObject;
import org.onosproject.yang.model.NodeKey;
import org.onosproject.yang.model.SchemaContext;
import org.onosproject.yang.model.SchemaId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.Iterator;
import java.util.List;
import static org.onosproject.yang.compiler.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.nonEmpty;
import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.getCamelCase;
import static org.onosproject.yang.runtime.SerializerHelper.getChildSchemaContext;
import static org.onosproject.yang.runtime.impl.YobConstants.DEFAULT;
import static org.onosproject.yang.runtime.impl.YobConstants.E_DATA_TYPE_NOT_SUPPORT;
import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_CREATE_OBJ;
import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_LOAD_CLASS;
import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_LOAD_CONSTRUCTOR;
import static org.onosproject.yang.runtime.impl.YobConstants.E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS;
import static org.onosproject.yang.runtime.impl.YobConstants.E_INVALID_IDENTITY_DATA;
import static org.onosproject.yang.runtime.impl.YobConstants.E_REFLECTION_FAIL_TO_CREATE_OBJ;
import static org.onosproject.yang.runtime.impl.YobConstants.FROM_STRING;
import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_CREATE_OBJ;
import static org.onosproject.yang.runtime.impl.YobConstants.L_FAIL_TO_LOAD_CLASS;
import static org.onosproject.yang.runtime.impl.YobConstants.L_REFLECTION_FAIL_TO_CREATE_OBJ;
import static org.onosproject.yang.runtime.impl.YobConstants.OF;
import static org.onosproject.yang.runtime.impl.YobConstants.OP_PARAM;
import static org.onosproject.yang.runtime.impl.YobConstants.PERIOD;
/**
* Utils to support object creation.
*/
final class YobUtils {
public static final String FORWARD_SLASH = "/";
private static final Logger log = LoggerFactory.getLogger(YobUtils.class);
private static final String ENUM_LEAF_IDENTIFIER = "$LeafIdentifier";
static final String ANYDATA_SETTER = "addAnydata";
// no instantiation
private YobUtils() {
}
/**
* Sets data from string value in parent method.
*
* @param type refers to YANG data type
* @param value value argument is used to set the value in method
* @param parentSetter Invokes the underlying method represented
* by this parentSetter
* @param parentObj the parentObject is to invoke the underlying method
* @param schemaNode schema information
* @param parentSchema schema information of parent
* @throws InvocationTargetException if failed to invoke method
* @throws IllegalAccessException if member cannot be accessed
* @throws NoSuchMethodException if method is not found
*/
static void setDataFromStringValue(YangDataTypes type,
Object value,
Method parentSetter,
Object parentObj,
YangSchemaNode schemaNode,
YangSchemaNode parentSchema)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
switch (type) {
case INT8:
case UINT8:
case INT16:
case UINT16:
case INT32:
case UINT32:
case INT64:
case UINT64:
case BOOLEAN:
case STRING:
case DECIMAL64:
case INSTANCE_IDENTIFIER:
parentSetter.invoke(parentObj, value);
break;
case BINARY:
byte[] data = Base64.getDecoder().decode((String) value);
parentSetter.invoke(parentObj, data);
break;
case BITS:
parseBitSetTypeInfo(parentSetter, parentObj, value,
schemaNode, parentSchema);
break;
case DERIVED:
parseDerivedTypeInfo(parentSetter, parentObj, value,
false, schemaNode);
break;
case IDENTITYREF:
parseIdentityRefInfo(parentSetter, parentObj, value,
schemaNode);
break;
case UNION:
parseDerivedTypeInfo(parentSetter, parentObj, value,
false, schemaNode);
break;
case LEAFREF:
parseLeafRefTypeInfo(parentSetter, parentObj, value,
schemaNode);
break;
case ENUMERATION:
parseDerivedTypeInfo(parentSetter, parentObj, value.toString(),
true, schemaNode);
break;
case EMPTY:
if (value == null) {
parentSetter.invoke(parentObj, true);
}
break;
default:
log.error(E_DATA_TYPE_NOT_SUPPORT);
}
}
/**
* To set data into parent setter method from string value for derived type.
*
* @param parentSetter the parent setter method to be invoked
* @param parentObj the parent build object on which to invoke the
* method
* @param value value to be set in method
* @param isEnum flag to check whether type is enum or derived
* @param leaf schema node
* @throws InvocationTargetException if failed to invoke method
* @throws IllegalAccessException if member cannot be accessed
* @throws NoSuchMethodException if the required method is not found
*/
static void parseDerivedTypeInfo(Method parentSetter,
Object parentObj,
Object value,
boolean isEnum,
YangSchemaNode leaf)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
String val;
if (value == null) {
val = "true";
} else {
val = value.toString();
}
Class<?> childSetClass = null;
Constructor<?> childConstructor = null;
Object childValue = null;
Object childObject = null;
Method childMethod = null;
while (leaf.getReferredSchema() != null) {
leaf = leaf.getReferredSchema();
}
String qualifiedClassName = leaf.getJavaPackage() + PERIOD +
getCapitalCase(leaf.getJavaClassNameOrBuiltInType());
ClassLoader classLoader = parentObj.getClass().getClassLoader();
try {
childSetClass = classLoader.loadClass(qualifiedClassName);
} catch (ClassNotFoundException e) {
log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
}
if (!isEnum) {
if (childSetClass != null) {
childConstructor = childSetClass.getDeclaredConstructor();
}
if (childConstructor != null) {
childConstructor.setAccessible(true);
}
try {
if (childConstructor != null) {
childObject = childConstructor.newInstance();
}
} catch (InstantiationException e) {
log.error(E_FAIL_TO_LOAD_CONSTRUCTOR, qualifiedClassName);
}
if (childSetClass != null) {
childMethod = childSetClass
.getDeclaredMethod(FROM_STRING, String.class);
}
} else {
if (childSetClass != null) {
childMethod = childSetClass.getDeclaredMethod(OF, String.class);
}
}
if (childMethod != null) {
childValue = childMethod.invoke(childObject, val);
}
parentSetter.invoke(parentObj, childValue);
}
/**
* To set data into parent setter method from string value for bits type.
*
* @param parentSetterMethod the parent setter method to be invoked
* @param parentObject the parent build object on which to invoke the
* method
* @param leafValue value to be set in method
* @param leaf schema information
* @param parentSchema schema information of parent
* @throws InvocationTargetException if failed to invoke method
* @throws IllegalAccessException if member cannot be accessed
* @throws NoSuchMethodException if the required method is not found
*/
static void parseBitSetTypeInfo(Method parentSetterMethod,
Object parentObject,
Object leafValue,
YangSchemaNode leaf,
YangSchemaNode parentSchema)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
Class<?> childSetClass = null;
Object childValue = null;
Object childObject = null;
Method childMethod = null;
while (leaf.getReferredSchema() != null) {
leaf = leaf.getReferredSchema();
}
String pName = parentSchema.getJavaClassNameOrBuiltInType()
.toLowerCase() + PERIOD;
String qualifiedClassName = parentSchema.getJavaPackage() + PERIOD +
pName + getCapitalCase(leaf.getJavaAttributeName());
ClassLoader classLoader = parentObject.getClass().getClassLoader();
try {
childSetClass = classLoader.loadClass(qualifiedClassName);
} catch (ClassNotFoundException e) {
log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
}
if (childSetClass != null) {
childMethod = childSetClass.getDeclaredMethod(FROM_STRING, String.class);
}
if (childMethod != null) {
childValue = childMethod.invoke(childObject, leafValue);
}
parentSetterMethod.invoke(parentObject, childValue);
}
/**
* To set data into parent setter method from string value for leafref type.
*
* @param parentSetter the parent setter method to be invoked
* @param parentObject the parent build object on which to invoke
* the method
* @param leafValue leaf value to be set
* @param schemaNode schema information
* @throws InvocationTargetException if method could not be invoked
* @throws IllegalAccessException if method could not be accessed
* @throws NoSuchMethodException if method does not exist
*/
static void parseLeafRefTypeInfo(Method parentSetter, Object parentObject,
Object leafValue,
YangSchemaNode schemaNode)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
while (schemaNode.getReferredSchema() != null) {
schemaNode = schemaNode.getReferredSchema();
}
YangLeafRef leafRef;
if (schemaNode instanceof YangLeaf) {
leafRef = (YangLeafRef) ((YangLeaf) schemaNode)
.getDataType().getDataTypeExtendedInfo();
} else {
leafRef = (YangLeafRef) ((YangLeafList) schemaNode)
.getDataType().getDataTypeExtendedInfo();
}
YangType type = leafRef.getEffectiveDataType();
Object refLeaf = leafRef.getReferredLeafOrLeafList();
YangLeavesHolder parent;
if (refLeaf instanceof YangLeaf) {
parent = ((YangLeaf) refLeaf).getContainedIn();
} else {
parent = ((YangLeafList) refLeaf).getContainedIn();
}
setDataFromStringValue(type.getDataType(), leafValue, parentSetter,
parentObject, (YangSchemaNode) refLeaf,
(YangSchemaNode) parent);
}
/**
* Returns class loader.
*
* @param schemaNode schema information
* @param reg YANG model registry
* @return class loader
*/
static ClassLoader getClassLoader(YangSchemaNode schemaNode,
DefaultYangModelRegistry reg) {
YangSchemaNode curNode = schemaNode;
while (!(curNode instanceof RpcNotificationContainer)) {
curNode = ((YangNode) curNode).getParent();
}
Class<?> regClass = reg.getRegisteredClass(curNode);
return regClass.getClassLoader();
}
/**
* Returns the class loader to be used for the switched context schema node.
*
* @param curLoader current context class loader
* @param context switched context
* @param reg schema registry
* @return class loader to be used for the switched context schema node
*/
static ClassLoader getTargetClassLoader(ClassLoader curLoader,
YangSchemaNodeContextInfo context,
DefaultYangModelRegistry
reg) {
YangSchemaNode augment = context.getContextSwitchedNode();
if (augment.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
YangSchemaNode parent = ((YangNode) augment).getParent();
while (((YangNode) parent).getParent() != null) {
parent = ((YangNode) parent).getParent();
}
Class<?> moduleClass = reg.getRegisteredClass(parent);
if (moduleClass == null) {
throw new ModelConverterException(E_FAIL_TO_LOAD_CLASS + parent
.getJavaClassNameOrBuiltInType());
}
return moduleClass.getClassLoader();
}
return curLoader;
}
/**
* Returns the qualified default / op param class.
*
* @param schemaNode schema node of the required class
* @return qualified default / op param class name
*/
static String getQualifiedDefaultClass(YangSchemaNode schemaNode) {
String packageName = schemaNode.getJavaPackage();
String className = getCapitalCase(
schemaNode.getJavaClassNameOrBuiltInType());
if (schemaNode instanceof RpcNotificationContainer) {
return packageName + PERIOD + className + OP_PARAM;
}
return packageName + PERIOD + DEFAULT + className;
}
/**
* Returns the qualified interface name.
*
* @param schemaNode schema node of the required class
* @return qualified interface name
*/
static String getQualifiedinterface(YangSchemaNode schemaNode) {
String packageName = schemaNode.getJavaPackage();
String className = getCapitalCase(
schemaNode.getJavaClassNameOrBuiltInType());
return packageName + PERIOD + className;
}
/**
* Returns the capital cased first letter of the given string.
*
* @param name string to be capital cased
* @return capital cased string
*/
static String getCapitalCase(String name) {
return name.substring(0, 1).toUpperCase() +
name.substring(1);
}
/**
* To set data into parent setter method from string value for identity ref.
*
* @param parentSetterMethod the parent setter method to be invoked
* @param parentObject the parent build object on which to invoke
* the method
* @param leafValue leaf value to be set
* @param schemaNode schema information
* @throws InvocationTargetException if method could not be invoked
* @throws IllegalAccessException if method could not be accessed
* @throws NoSuchMethodException if method does not exist
*/
static void parseIdentityRefInfo(Method parentSetterMethod,
Object parentObject,
Object leafValue,
YangSchemaNode schemaNode)
throws InvocationTargetException, IllegalAccessException,
NoSuchMethodException {
Class<?> childSetClass = null;
Object childValue = null;
Method childMethod = null;
while (schemaNode.getReferredSchema() != null) {
schemaNode = schemaNode.getReferredSchema();
}
String qualifiedClassName;
YangType type;
if (schemaNode instanceof YangLeaf) {
type = ((YangLeaf) schemaNode).getDataType();
} else {
type = ((YangLeafList) schemaNode).getDataType();
}
YangIdentityRef identityRef = null;
YangIdentity derivedId;
if (type.getDataType() == YangDataTypes.LEAFREF && schemaNode
.getJavaPackage().equals(YobConstants.JAVA_LANG)) {
YangLeafRef leafref = ((YangLeafRef) type.getDataTypeExtendedInfo());
YangType effectiveType = leafref.getEffectiveDataType();
if (effectiveType.getDataType() == YangDataTypes.IDENTITYREF) {
identityRef = ((YangIdentityRef) effectiveType
.getDataTypeExtendedInfo());
}
} else {
identityRef = ((YangIdentityRef) type.getDataTypeExtendedInfo());
}
derivedId = getDerivedIdentity(leafValue.toString(), identityRef
.getReferredIdentity());
if (derivedId == null) {
throw new ModelConverterException(E_INVALID_IDENTITY_DATA +
leafValue.toString());
}
qualifiedClassName = derivedId.getJavaPackage() + PERIOD +
getCapitalCase(derivedId.getJavaClassNameOrBuiltInType());
ClassLoader classLoader = parentObject.getClass().getClassLoader();
try {
childSetClass = classLoader.loadClass(qualifiedClassName);
} catch (ClassNotFoundException e) {
log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
}
if (childSetClass != null) {
childMethod = childSetClass
.getDeclaredMethod(FROM_STRING, String.class);
}
if (childMethod != null) {
childValue = childMethod.invoke(null, leafValue);
}
parentSetterMethod.invoke(parentObject, childValue);
}
/**
* Returns schema node for given data node.
*
* @param dataNode data node
* @param context schema context
* @return child schema node
*/
static YangSchemaNode getChildSchemaNode(DataNode dataNode,
SchemaContext context) {
SchemaId schemaId = dataNode.key().schemaId();
SchemaContext schemaContext = getChildSchemaContext(context,
schemaId.name(),
schemaId.namespace());
return ((YangSchemaNode) schemaContext);
}
/**
* Builds leaf model object.
*
* @param dataNode data node
* @param leafHolder schema context
* @param reg YANG model registry
* @return leaf model object
*/
static ModelObject buildLeafModelObject(DataNode dataNode,
YangSchemaNode leafHolder,
DefaultYangModelRegistry reg) {
if (leafHolder == null) {
YangSchemaNode schemaNode = ((YangSchemaNode) reg
.getChildContext(dataNode.key().schemaId()));
if (schemaNode instanceof YangLeaf) {
leafHolder = ((YangSchemaNode) ((YangLeaf) schemaNode)
.getContainedIn());
} else {
leafHolder = ((YangSchemaNode) ((YangLeafList) schemaNode)
.getContainedIn());
}
}
LeafModelObject leafObj = new LeafModelObject();
leafObj.addValue(((LeafNode) dataNode).value());
LeafIdentifier leafId = getLeafIdentifier(dataNode.key().schemaId(),
leafHolder, reg);
leafObj.leafIdentifier(leafId);
return leafObj;
}
/**
* Returns leaf identifier of the leaf.
*
* @param id schema id class loader
* @param leafHolder parent of leaf
* @param reg YANG model registry
* @return leaf identifier of the leaf
*/
static LeafIdentifier getLeafIdentifier(SchemaId id,
YangSchemaNode leafHolder,
DefaultYangModelRegistry reg) {
String qualName = getQualifiedDefaultClass(leafHolder);
ClassLoader classLoader = getClassLoader(leafHolder, reg);
try {
Class<InnerModelObject> cls = (Class<InnerModelObject>) classLoader
.loadClass(qualName);
Class<?>[] intfs = cls.getInterfaces();
Class<?> intf = null;
for (Class<?> in : intfs) {
if (in.getName()
.equals(getJavaQualifiedInterFaceName(leafHolder))) {
intf = in;
break;
}
}
String leafId;
if (intf != null) {
leafId = intf.getName() + ENUM_LEAF_IDENTIFIER;
} else {
throw new ModelConverterException(E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS);
}
Class<Enum> leafIdentifier =
(Class<Enum>) cls.getClassLoader().loadClass(leafId);
Enum[] enumConst = leafIdentifier.getEnumConstants();
for (Enum e : enumConst) {
if (e.name().equalsIgnoreCase(id.name())) {
return ((LeafIdentifier) e);
}
}
} catch (ClassNotFoundException e) {
throw new ModelConverterException(E_FAIL_TO_LOAD_CLASS, e);
}
return null;
}
/**
* Returns class.
*
* @param loader class loader
* @param name class name
* @return java class
*/
static Class<?> fetchClassForNode(ClassLoader loader, String name) {
try {
return loader.loadClass(name);
} catch (ClassNotFoundException e) {
throw new ModelConverterException(E_FAIL_TO_LOAD_CLASS + name, e);
}
}
/**
* Returns instance of class.
*
* @param loader class loader
* @param name class name
* @return instance of class
*/
static Object getInstanceOfClass(ClassLoader loader, String name) {
try {
Class<?> defaultClass = loader.loadClass(name);
return defaultClass.newInstance();
} catch (ClassNotFoundException e) {
log.error(L_FAIL_TO_LOAD_CLASS, name);
throw new ModelConverterException(E_FAIL_TO_LOAD_CLASS + name, e);
} catch (NullPointerException e) {
log.error(L_REFLECTION_FAIL_TO_CREATE_OBJ, name);
throw new ModelConverterException(E_REFLECTION_FAIL_TO_CREATE_OBJ +
name, e);
} catch (InstantiationException | IllegalAccessException e) {
log.error(L_FAIL_TO_CREATE_OBJ, name);
throw new ModelConverterException(E_FAIL_TO_CREATE_OBJ + name, e);
}
}
/**
* Returns java class name.
*
* @param node YANG node
* @return java class name
*/
static String getJavaQualifiedInterFaceName(YangSchemaNode node) {
if (node != null) {
return node.getJavaPackage() + PERIOD
+ getCapitalCase(node.getJavaClassNameOrBuiltInType());
}
return null;
}
/**
* Returns key class name.
*
* @param node schema node
* @return key class name
*/
static String getKeyClassName(YangSchemaNode node) {
if (node != null) {
return getJavaQualifiedInterFaceName(node) + "Keys";
}
return null;
}
/**
* Returns key leaf schema.
*
* @param keyleaf key leaf
* @param node to look in
* @return node YANG schema node
*/
static YangLeaf getKeyLeafSchema(KeyLeaf keyleaf, YangSchemaNode
node) {
YangList list = ((YangList) node);
List<YangLeaf> keyLeaves = list.getListOfLeaf();
Iterator<YangLeaf> it = keyLeaves.iterator();
while (it.hasNext()) {
YangLeaf leaf = it.next();
if (leaf.getName().equals(keyleaf.leafSchema().name())) {
return leaf;
}
}
return null;
}
/**
* Adds list node key to model object id builder.
*
* @param midb model object identifier
* @param reg model registry
* @param node YANG node
* @param key node key
* @return model object id builder
* @param <T> list class type
* @param <K> key type
*/
static <T extends InnerModelObject & MultiInstanceObject<K>,
K extends KeyInfo<T>> ModelObjectId.Builder handleListKey(
ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
YangSchemaNode node, NodeKey key) {
ListKey listKey = (ListKey) key;
List<KeyLeaf> keyLeaves = listKey.keyLeafs();
String keyClassName;
Class<KeyInfo> keyClass;
Object value;
String javaName = null;
Method setter;
if (nonEmpty(keyLeaves)) {
String qualName = getQualifiedDefaultClass(node);
ClassLoader classLoader = getClassLoader(node, reg);
Class<T> listClass = ((Class<T>) fetchClassForNode(classLoader,
qualName));
K keyObj;
if (listClass != null) {
keyClassName = getKeyClassName(node);
try {
keyClass = (Class<KeyInfo>) listClass.getClassLoader()
.loadClass(keyClassName);
keyObj = (K) keyClass.newInstance();
for (KeyLeaf leaf : keyLeaves) {
YangLeaf leafSchema = getKeyLeafSchema(leaf, node);
YangDataTypes datatype = leafSchema.getDataType()
.getDataType();
javaName = getCamelCase(leaf.leafSchema().name(), null);
Field leafName = keyClass.getDeclaredField(javaName);
setter = keyClass.getDeclaredMethod(javaName,
leafName.getType());
value = leaf.leafValue();
setDataFromStringValue(datatype,
value, setter, keyObj,
leafSchema, node);
midb = midb.addChild(listClass, keyObj);
}
} catch (NoSuchMethodException e) {
throw new ModelConverterException(
"Failed to load setter method for " +
javaName + " in key class"
+ keyClassName, e);
} catch (InvocationTargetException e) {
throw new ModelConverterException(
"Failed to invoke setter method for " +
javaName + " in key class"
+ keyClassName, e);
} catch (ClassNotFoundException e) {
throw new ModelConverterException("Failed to load key class"
+ keyClassName, e);
} catch (IllegalAccessException | InstantiationException e) {
throw new ModelConverterException("Failed Instantiation of key class"
+ keyClassName, e);
} catch (NoSuchFieldException e) {
throw new ModelConverterException("Field " + javaName + " not found", e);
}
}
}
return midb;
}
/**
* Adds leaf list node key to model object id builder.
*
* @param midb model object identifier
* @param reg model registry
* @param schemaNode leaf schema node
* @param key leaf list node key
* @return model object id builder
*/
static ModelObjectId.Builder handleLeafListKey(
ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
YangSchemaNode schemaNode, LeafListKey key) {
Class<?> intf = null;
YangSchemaNode parentSchema = ((YangSchemaNode) ((YangLeafList)
schemaNode).getContainedIn());
String qualName = getQualifiedDefaultClass(parentSchema);
ClassLoader classLoader = getClassLoader(parentSchema, reg);
Class<?> parentClass = fetchClassForNode(classLoader, qualName);
Class<?>[] interfaces = parentClass.getInterfaces();
for (Class<?> in : interfaces) {
if (in.getName().equals(getJavaQualifiedInterFaceName(parentSchema))) {
intf = in;
break;
}
}
String leafName;
if (intf != null) {
leafName = intf.getName() + ENUM_LEAF_IDENTIFIER;
try {
Class<Enum> leafId =
(Class<Enum>) parentClass.getClassLoader()
.loadClass(leafName);
Enum[] enumConst = leafId.getEnumConstants();
for (Enum e : enumConst) {
if (e.name().equalsIgnoreCase(key.schemaId().name())) {
midb = midb.addChild(((LeafIdentifier) e), key.value());
return midb;
}
}
} catch (ClassNotFoundException e) {
throw new ModelConverterException("Failed to load leaf identifier class." +
leafName, e);
}
}
return midb;
}
/**
* Adds node key for container node or single instance nodes to model
* object id builder.
*
* @param midb model object identifier builder
* @param reg model registry
* @param node YANG node
* @param key node key
* @return model object builder with single instance node
*/
static ModelObjectId.Builder handleNodeKey(
ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
YangSchemaNode node, NodeKey key) {
if (node != null) {
if (!(node instanceof YangLeaf)) {
String qualName = getQualifiedDefaultClass(node);
ClassLoader classLoader = getClassLoader(node, reg);
Class<InnerModelObject> nodeClass = (Class<InnerModelObject>)
fetchClassForNode(classLoader, qualName);
if (nodeClass != null) {
midb = midb.addChild(nodeClass);
}
} else {
midb = handleLeafInfo(midb, reg, key, node);
}
}
return midb;
}
/**
* Adds node key for leaf node to model object id builder.
*
* @param midb model object identifier builder
* @param reg model registry
* @param key leaf node key
* @param schemaNode YANG schema node
* @return model object builder with single instance node
*/
static ModelObjectId.Builder handleLeafInfo(
ModelObjectId.Builder midb, DefaultYangModelRegistry reg,
NodeKey key, YangSchemaNode schemaNode) {
YangSchemaNode parentSchema = ((YangSchemaNode) ((YangLeaf) schemaNode)
.getContainedIn());
String qualName = getQualifiedDefaultClass(parentSchema);
ClassLoader classLoader = getClassLoader(parentSchema, reg);
Class<InnerModelObject> nodeClass = (Class<InnerModelObject>)
fetchClassForNode(classLoader, qualName);
Class<?>[] interfaces = nodeClass.getInterfaces();
for (Class<?> intf : interfaces) {
String leafId = intf.getName() + ENUM_LEAF_IDENTIFIER;
try {
Class<Enum> leafIdentifier =
(Class<Enum>) nodeClass.getClassLoader()
.loadClass(leafId);
Enum[] enumConst = leafIdentifier.getEnumConstants();
for (Enum e : enumConst) {
if (e.name().equalsIgnoreCase(key.schemaId().name())) {
midb = midb.addChild(((LeafIdentifier) e));
return midb;
}
}
} catch (ClassNotFoundException e) {
throw new ModelConverterException(E_FAIL_TO_LOAD_LEAF_IDENTIFIER_CLASS, e);
}
}
return midb;
}
/**
* Returns derived identity based on the leaf value.
*
* @param value leaf value
* @param referredId referred identity of leaf
* @return derived identity
*/
static YangIdentity getDerivedIdentity(String value,
YangIdentity referredId) {
if (referredId.getJavaClassNameOrBuiltInType().equalsIgnoreCase(value)) {
return referredId;
}
List<YangIdentity> extendList = referredId.getExtendList();
if (extendList != null && !extendList.isEmpty()) {
for (YangIdentity identity : extendList) {
if (identity.getYangSchemaNodeIdentifier().getName()
.equalsIgnoreCase(value)) {
return identity;
}
}
}
return null;
}
}