From: Jozef Gloncak Date: Thu, 11 Jul 2013 08:49:23 +0000 (+0200) Subject: YANG typedefs generation as class with extends key word X-Git-Tag: releasepom-0.1.0~279^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=52df0e555243605003ee090150cf61b53c097563 YANG typedefs generation as class with extends key word In case that YANG typedef isn't specified as base type then corresponding class will be generated with EXTENDS key word and corresponding extended class. Change-Id: I36143f485b8e68f471e2a3021ceb7ddc4ad9df2f Signed-off-by: Jozef Gloncak --- diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java index bcaf3a062a..ec57cb4a3c 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java @@ -11,7 +11,6 @@ import static org.opendaylight.controller.binding.generator.util.BindingGenerato import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode; import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule; -import java.util.*; import java.util.concurrent.Future; import java.util.ArrayList; @@ -21,9 +20,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Future; -import org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil; import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl; import org.opendaylight.controller.binding.generator.util.Types; import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; @@ -856,11 +853,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (genTOBuilder != null) { returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); } - } else if(typeDef instanceof BitsTypeDefinition) { + } else if (typeDef instanceof BitsTypeDefinition) { GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName); if (genTOBuilder != null) { returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); - } + } } else { returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef); } @@ -1184,23 +1181,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genTOBuilder; } - - private GeneratedTOBuilder addEnclosedTOToTypeBuilder( TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, String leafName) { + private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, + String leafName) { String className = parseToClassName(leafName); GeneratedTOBuilder genTOBuilder = null; if (typeDef instanceof UnionType) { genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition( typeBuilder.getPackageName(), typeDef, className); } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject( - typeBuilder.getPackageName(), typeDef, className); + genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(typeBuilder.getPackageName(), + typeDef, className); } if (genTOBuilder != null) { typeBuilder.addEnclosingTransferObject(genTOBuilder); return genTOBuilder; } return null; - + } - + } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java index 4824fa75fd..b6d8de62e6 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java @@ -27,13 +27,16 @@ import org.opendaylight.controller.yang.model.api.type.*; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; import org.opendaylight.controller.yang.model.util.ExtendedType; + import org.opendaylight.controller.yang.model.util.StringType; +import org.opendaylight.controller.yang.model.util.UnionType; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*; import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.*; @@ -361,18 +364,15 @@ public final class TypeProviderImpl implements TypeProvider { final String basePackageName = moduleNamespaceToPackageName(module); final Set> typeDefinitions = module.getTypeDefinitions(); + final List> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions); final Map typeMap = new HashMap<>(); genTypeDefsContextMap.put(moduleName, typeMap); - if ((typeDefinitions != null) && (basePackageName != null)) { - for (final TypeDefinition typedef : typeDefinitions) { + if ((listTypeDefinitions != null) && (basePackageName != null)) { + for (final TypeDefinition typedef : listTypeDefinitions) { typedefToGeneratedType(basePackageName, moduleName, typedef); } - final List extUnions = UnionDependencySort.sort(typeDefinitions); - for (final ExtendedType extUnionType : extUnions) { - addUnionGeneratedTypeDefinition(basePackageName, extUnionType, null); - } } } } @@ -382,23 +382,31 @@ public final class TypeProviderImpl implements TypeProvider { if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) { final String typedefName = typedef.getQName().getLocalName(); - final TypeDefinition baseTypeDefinition = baseTypeDefForExtendedType(typedef); - if (!(baseTypeDefinition instanceof LeafrefTypeDefinition) - && !(baseTypeDefinition instanceof IdentityrefTypeDefinition)) { - Type returnType; - if (baseTypeDefinition instanceof EnumTypeDefinition) { - final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDefinition; + final TypeDefinition innerTypeDefinition = typedef.getBaseType(); + if (!(innerTypeDefinition instanceof LeafrefTypeDefinition) + && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) { + Type returnType = null; + if (innerTypeDefinition instanceof ExtendedType) { + ExtendedType extendedTypeDef = (ExtendedType) innerTypeDefinition; + returnType = resolveExtendedTypeFromTypeDef(extendedTypeDef, basePackageName, typedefName, + moduleName); + } else if (innerTypeDefinition instanceof UnionTypeDefinition) { + final GeneratedTOBuilder genTOBuilder = addUnionGeneratedTypeDefinition(basePackageName, typedef, + typedefName); + returnType = genTOBuilder.toInstance(); + } else if (innerTypeDefinition instanceof EnumTypeDefinition) { + final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition; returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName); - } else if (baseTypeDefinition instanceof BitsTypeDefinition) { - final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) baseTypeDefinition; - GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName, bitsTypeDefinition, - typedefName); + } else if (innerTypeDefinition instanceof BitsTypeDefinition) { + final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition; + final GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName, + bitsTypeDefinition, typedefName); returnType = genTOBuilder.toInstance(); } else { final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER - .javaTypeForSchemaDefinitionType(baseTypeDefinition); + .javaTypeForSchemaDefinitionType(innerTypeDefinition); returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType); } @@ -428,12 +436,12 @@ public final class TypeProviderImpl implements TypeProvider { genTOBuilder.addEqualsIdentity(genPropBuilder); genTOBuilder.addHashIdentity(genPropBuilder); genTOBuilder.addToStringProperty(genPropBuilder); - - if (typedef instanceof ExtendedType) { - final List regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef); - addStringRegExAsConstant(genTOBuilder, regExps); + if (javaType == BaseYangTypes.STRING_TYPE) { + if (typedef instanceof ExtendedType) { + final List regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef); + addStringRegExAsConstant(genTOBuilder, regExps); + } } - return genTOBuilder.toInstance(); } return null; @@ -479,9 +487,10 @@ public final class TypeProviderImpl implements TypeProvider { final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType); if (unionTypeModule != null && unionTypeModule.getName() != null) { final Map innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName()); - - final GeneratedTransferObject genTransferObject = (GeneratedTransferObject) innerGenTOs - .get(typeName); + Type genTransferObject = null; + if (innerGenTOs != null) { + genTransferObject = innerGenTOs.get(typeName); + } if (genTransferObject != null) { updateUnionTypeAsProperty(unionGenTransObject, genTransferObject, genTransferObject.getName()); @@ -620,4 +629,103 @@ public final class TypeProviderImpl implements TypeProvider { } } + private GeneratedTransferObject resolveExtendedTypeFromTypeDef(final ExtendedType extendedType, + final String basePackageName, final String typedefName, final String moduleName) { + + if (extendedType == null) { + throw new IllegalArgumentException("Extended type cannot be NULL!"); + } + if (basePackageName == null) { + throw new IllegalArgumentException("String with base package name cannot be NULL!"); + } + if (typedefName == null) { + throw new IllegalArgumentException("String with type definition name cannot be NULL!"); + } + + final String typeDefName = parseToClassName(typedefName); + final String lowTypeDef = extendedType.getQName().getLocalName(); + final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName); + + final Map typeMap = genTypeDefsContextMap.get(moduleName); + if (typeMap != null) { + Type type = typeMap.get(lowTypeDef); + if (type instanceof GeneratedTransferObject) { + genTOBuilder.setExtendsType((GeneratedTransferObject) type); + } + } + + return genTOBuilder.toInstance(); + } + + /** + * The method find out for each type definition how many immersion (depth) + * is necessary to get to the base type. Every type definition is inserted + * to the map which key is depth and value is list of type definitions with + * equal depth. In next step are lists from this map concatenated to one + * list in ascending order according to their depth. All type definitions + * are in the list behind all type definitions on which depends. + * + * @param unsortedTypeDefinitions + * represents list of type definitions + * @return list of type definitions sorted according their each other + * dependencies (type definitions which are depend on other type + * definitions are in list behind them). + */ + private List> sortTypeDefinitionAccordingDepth( + final Set> unsortedTypeDefinitions) { + List> sortedTypeDefinition = new ArrayList<>(); + + Map>> typeDefinitionsDepths = new TreeMap<>(); + for (TypeDefinition unsortedTypeDefinition : unsortedTypeDefinitions) { + final int depth = getTypeDefinitionDepth(unsortedTypeDefinition); + List> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth); + if (typeDefinitionsConcreteDepth == null) { + typeDefinitionsConcreteDepth = new ArrayList>(); + typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth); + } + typeDefinitionsConcreteDepth.add(unsortedTypeDefinition); + } + + Set depths = typeDefinitionsDepths.keySet(); // keys are in + // ascending order + for (Integer depth : depths) { + sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth)); + } + + return sortedTypeDefinition; + } + + /** + * The method return how many immersion is necessary to get from type + * definition to base type. + * + * @param typeDefinition + * is type definition for which is depth looked for. + * @return how many immersion is necessary to get from type definition to + * base type + */ + private int getTypeDefinitionDepth(final TypeDefinition typeDefinition) { + if (typeDefinition == null) { + throw new IllegalArgumentException("Type definition can't be null"); + } + int depth = 1; + TypeDefinition baseType = typeDefinition.getBaseType(); + + if (baseType instanceof ExtendedType) { + depth = depth + getTypeDefinitionDepth(typeDefinition.getBaseType()); + } else if (baseType instanceof UnionType) { + List> childTypeDefinitions = ((UnionType) baseType).getTypes(); + int maxChildDepth = 0; + int childDepth = 1; + for (TypeDefinition childTypeDefinition : childTypeDefinitions) { + childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition.getBaseType()); + if (childDepth > maxChildDepth) { + maxChildDepth = childDepth; + } + } + return maxChildDepth; + } + return depth; + } + } diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ExtendedTypedefTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ExtendedTypedefTest.java new file mode 100644 index 0000000000..bbbf469b11 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ExtendedTypedefTest.java @@ -0,0 +1,137 @@ +package org.opendaylight.controller.sal.binding.generator.impl; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator; +import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl; +import org.opendaylight.controller.sal.binding.model.api.Constant; +import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty; +import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.controller.sal.binding.model.api.ParameterizedType; +import org.opendaylight.controller.sal.binding.model.api.Type; +import org.opendaylight.controller.sal.binding.yang.types.BaseYangTypes; +import org.opendaylight.controller.yang.model.api.Module; +import org.opendaylight.controller.yang.model.api.SchemaContext; +import org.opendaylight.controller.yang.model.parser.api.YangModelParser; +import org.opendaylight.controller.yang.parser.impl.YangParserImpl; + +public class ExtendedTypedefTest { + + private final static List testModels = new ArrayList(); + + @BeforeClass + public static void loadTestResources() { + final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/typedef_of_typedef.yang").getPath()); + testModels.add(listModelFile); + } + + @Test + public void constantGenerationTest() { + final YangModelParser parser = new YangParserImpl(); + final Set modules = parser.parseYangModels(testModels); + final SchemaContext context = parser.resolveSchemaContext(modules); + + assertNotNull(context); + final BindingGenerator bindingGen = new BindingGeneratorImpl(); + final List genTypes = bindingGen.generateTypes(context); + + GeneratedTransferObject simpleTypedef4 = null; + GeneratedTransferObject extendedTypedefUnion = null; + GeneratedTransferObject unionTypedef = null; + for (final Type type : genTypes) { + if (type instanceof GeneratedTransferObject) { + if (type.getName().equals("SimpleTypedef4")) { + simpleTypedef4 = (GeneratedTransferObject) type; + } else if (type.getName().equals("ExtendedTypedefUnion")) { + extendedTypedefUnion = (GeneratedTransferObject) type; + } else if (type.getName().equals("UnionTypedef")) { + unionTypedef = (GeneratedTransferObject) type; + } + } + } + + // simple-typedef4 + assertNotNull("SimpleTypedef4 not found", simpleTypedef4); + assertNotNull("ExtendedTypedefUnion not found", extendedTypedefUnion); + assertNotNull("UnionTypedef", unionTypedef); + + List properties = simpleTypedef4.getProperties(); + assertTrue("SimpleTypedef4 shouldn't have properties.", properties.isEmpty()); + + GeneratedTransferObject extendTO = simpleTypedef4.getExtends(); + assertNotNull("SimpleTypedef4 should have extend.", extendTO); + assertEquals("Incorrect extension for SimpleTypedef4.", "SimpleTypedef3", extendTO.getName()); + properties = extendTO.getProperties(); + assertTrue("SimpleTypedef3 shouldn't have properties.", properties.isEmpty()); + + extendTO = extendTO.getExtends(); + assertNotNull("SimpleTypedef3 should have extend.", extendTO); + assertEquals("Incorrect extension for SimpleTypedef3.", "SimpleTypedef2", extendTO.getName()); + properties = extendTO.getProperties(); + assertTrue("SimpleTypedef2 shouldn't have properties.", properties.isEmpty()); + + extendTO = extendTO.getExtends(); + assertNotNull("SimpleTypedef2 should have extend.", extendTO); + assertEquals("SimpleTypedef2 should be extended with SimpleTypedef1.", "SimpleTypedef1", extendTO.getName()); + properties = extendTO.getProperties(); + assertEquals("Incorrect number of properties in class SimpleTypedef1.", 1, properties.size()); + + assertEquals("Incorrect property's name", "simpleTypedef1", properties.get(0).getName()); + assertEquals("Property's incorrect type", BaseYangTypes.UINT8_TYPE, properties.get(0).getReturnType()); + + extendTO = extendTO.getExtends(); + assertNull("SimpleTypedef1 shouldn't have extend.", extendTO); + + // extended-typedef-union + assertNotNull("ExtendedTypedefUnion object not found", extendedTypedefUnion); + properties = extendedTypedefUnion.getProperties(); + assertTrue("ExtendedTypedefUnion shouldn't have any property", properties.isEmpty()); + + extendTO = extendedTypedefUnion.getExtends(); + assertEquals("Incorrect extension fo ExtendedTypedefUnion.", "UnionTypedef", extendTO.getName()); + assertNull("UnionTypedef shouldn't be extended", extendTO.getExtends()); + assertEquals("Incorrect number of properties for UnionTypedef.", 4, extendTO.getProperties().size()); + + GeneratedProperty simpleTypedef4Property = null; + GeneratedProperty simpleTypedef1Property = null; + GeneratedProperty byteTypeProperty = null; + GeneratedProperty typedefEnumFruitProperty = null; + for (GeneratedProperty genProperty : extendTO.getProperties()) { + if (genProperty.getName().equals("simpleTypedef1")) { + simpleTypedef1Property = genProperty; + } else if (genProperty.getName().equals("simpleTypedef4")) { + simpleTypedef4Property = genProperty; + } else if (genProperty.getName().equals("byteType")) { + byteTypeProperty = genProperty; + } else if (genProperty.getName().equals("typedefEnumFruit")) { + typedefEnumFruitProperty = genProperty; + } + } + + assertNotNull("simpleTypedef4 property not found in UnionTypedef", simpleTypedef4Property); + assertNotNull("simpleTypedef1 property not found in UnionTypedef", simpleTypedef1Property); + assertNotNull("byteType property not found in UnionTypedef", byteTypeProperty); + assertNotNull("typedefEnumFruit property not found in UnionTypedef", typedefEnumFruitProperty); + + assertEquals("Incorrect type for property simpleTypedef4.", "SimpleTypedef4", simpleTypedef4Property + .getReturnType().getName()); + assertEquals("Incorrect type for property simpleTypedef1.", "SimpleTypedef1", simpleTypedef1Property + .getReturnType().getName()); + assertEquals("Incorrect type for property byteType.", "ByteType", byteTypeProperty + .getReturnType().getName()); + assertEquals("Incorrect type for property typedefEnumFruit.", "TypedefEnumFruit", typedefEnumFruitProperty + .getReturnType().getName()); + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang new file mode 100644 index 0000000000..fc0bab9f0d --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang @@ -0,0 +1,79 @@ +module typedef_typedef { + + namespace "urn:typedef:typedef"; + prefix "sbd"; + + organization "OPEN DAYLIGHT"; + contact "http://www.opendaylight.org/"; + + revision 2013-07-09 { + + } + + typedef byte-type { + type bits { + bit first-bit { + position 10; + } + bit second-bit { + position 20; + } + } + } + + + typedef typedef-enum-fruit { + type enumeration { + enum "apple" { + value 1; + description "gold"; + } + enum "pear" { + value 2; + } + } + } + + typedef simple-typedef1 { + type uint8; + } + + typedef simple-typedef2 { + type simple-typedef1; + } + + typedef simple-typedef3 { + type simple-typedef2; + } + + typedef simple-typedef4 { + type simple-typedef3; + } + + typedef simple-typedef1-1 { + type uint16; + } + + + typedef union-typedef { + type union { + type simple-typedef1; + type simple-typedef4; + type byte-type; + type typedef-enum-fruit; + } + } + + typedef extended-typedef-union { + type union-typedef; + } + + + typedef extended-typedef-simple { + type simple-typedef1; + } + + typedef extended-typedef-enum { + type typedef-enum-fruit; + } +} \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java index 717988af3e..31b94a65ca 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java @@ -67,11 +67,14 @@ public final class ClassCodeGenerator implements CodeGenerator { } writer.write(NL); + final boolean oneConstructor; if (genTO.isUnionType()) { - writer.write(GeneratorUtil.createConstructors(genTO, indent + TAB, imports, genTO.isAbstract())); + oneConstructor = false; } else { - writer.write(GeneratorUtil.createConstructor(genTO, indent + TAB, imports, genTO.isAbstract()) + NL); + oneConstructor = true; } + writer.write(GeneratorUtil.createConstructor(genTO, indent + TAB, imports, genTO.isAbstract(), + oneConstructor)); writer.write(NL); for (GeneratedProperty field : fields) { diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java index dfae4a2cea..0e2da81937 100644 --- a/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java +++ b/opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java @@ -17,9 +17,9 @@ import java.util.Map; import org.opendaylight.controller.binding.generator.util.TypeConstants; import org.opendaylight.controller.sal.binding.model.api.*; +import org.opendaylight.controller.binding.generator.util.Types; import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair; import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter; -import org.opendaylight.controller.binding.generator.util.Types; public final class GeneratorUtil { @@ -232,90 +232,244 @@ public final class GeneratorUtil { return builder.toString(); } - public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent, - final Map availableImports, boolean isIdentity) { - StringBuilder builder = new StringBuilder(); + public static String createConstructor(final GeneratedTransferObject genTransferObject, final String indent, + final Map availableImports, final boolean isIdentity, final boolean oneConstructor) { + if (genTransferObject == null) { + throw new IllegalArgumentException("Generated transfer object can't be null"); + } + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + GeneratedTransferObject genTOTopParent = getTopParrentTransportObject(genTransferObject); + final List ctorProperties = resolveReadOnlyPropertiesFromTO(genTransferObject + .getProperties()); + final List ctorPropertiesAllParents = getPropertiesOfAllParents(genTransferObject + .getExtends()); final String currentPkg = genTransferObject.getPackageName(); - final List properties = genTransferObject.getProperties(); - final List ctorParams = new ArrayList(); - if (properties != null) { - for (final GeneratedProperty property : properties) { - if (property.isReadOnly()) { - ctorParams.add(property); - } + final String className = genTransferObject.getName(); + + String constructorPart = ""; + if (oneConstructor) { + if (genTOTopParent != genTransferObject && genTOTopParent.isUnionType()) { + constructorPart = createConstructorForEveryParentProperty(indent, isIdentity, ctorProperties, + ctorPropertiesAllParents, availableImports, currentPkg, className); + + } else { + constructorPart = createOneConstructor(indent, isIdentity, ctorProperties, ctorPropertiesAllParents, + availableImports, currentPkg, className); } + + } else { // union won't be extended + constructorPart = createConstructorForEveryProperty(indent, isIdentity, ctorProperties, + ctorPropertiesAllParents, availableImports, currentPkg, className); } - builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity)); + return constructorPart; + } - final String parameterSeparator = COMMA + GAP; - for (final GeneratedProperty ctorParam : ctorParams) { - builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg)); - builder.append(parameterSeparator); + private static String createOneConstructor(final String indent, boolean isIdentity, + final List properties, final List propertiesAllParents, + final Map availableImports, final String currentPkg, final String className) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); } - if (!ctorParams.isEmpty()) { - builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length()); + if (properties == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); } - builder.append(createConstructorDeclarationFromRightParenthesis()); - builder.append(createConstructorSuperCalling(indent)); - - for (final GeneratedProperty ctorParam : ctorParams) { - builder.append(createClassAttributeInitialization(indent, ctorParam)); + if (propertiesAllParents == null) { + throw new IllegalArgumentException( + "List of generated properties of all parent transport objects can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } + + final StringBuilder builder = new StringBuilder(); + List propertiesAll = new ArrayList(properties); + propertiesAll.addAll(propertiesAllParents); + + builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity)); + builder.append(createMethodPropertiesDeclaration(propertiesAll, availableImports, currentPkg, COMMA + GAP)); + builder.append(createConstructorDeclarationFromRightParenthesis()); + builder.append(createConstructorSuper(propertiesAllParents, indent)); + builder.append(createClassPropertiesInitialization(propertiesAll, indent)); builder.append(createConstructorClosingPart(indent)); return builder.toString(); } - public static String createConstructors(GeneratedTransferObject genTransferObject, final String indent, - final Map availableImports, boolean isIdentity) { + private static String createConstructorForEveryParentProperty(final String indent, final boolean isIdentity, + final List properties, final List propertiesAllParents, + final Map availableImports, final String currentPkg, final String className) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (propertiesAllParents == null) { + throw new IllegalArgumentException( + "List of generated properties of all parent transport objects can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } final StringBuilder builder = new StringBuilder(); + GeneratedProperty parentProperty; + Iterator parentPropertyIterator = propertiesAllParents.iterator(); - final String currentPkg = genTransferObject.getPackageName(); - final List properties = genTransferObject.getProperties(); - final List ctorParams = new ArrayList(); - if (properties != null) { - for (final GeneratedProperty property : properties) { - if (property.isReadOnly()) { - ctorParams.add(property); - } + do { + parentProperty = null; + if (parentPropertyIterator.hasNext()) { + parentProperty = parentPropertyIterator.next(); + } + + List propertiesAndParentProperties = new ArrayList(); + if (parentProperty != null) { + propertiesAndParentProperties.add(parentProperty); } + propertiesAndParentProperties.addAll(properties); + + builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity)); + builder.append(createMethodPropertiesDeclaration(propertiesAndParentProperties, availableImports, + currentPkg, COMMA + GAP)); + builder.append(createConstructorDeclarationFromRightParenthesis()); + builder.append(createConstructorSuper(parentProperty, indent)); + builder.append(createClassPropertiesInitialization(properties, indent)); + builder.append(createConstructorClosingPart(indent)); + } while (parentPropertyIterator.hasNext()); + + return builder.toString(); + } + + private static String createConstructorForEveryProperty(final String indent, final boolean isIdentity, + final List properties, final List propertiesAllParents, + final Map availableImports, final String currentPkg, final String className) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (propertiesAllParents == null) { + throw new IllegalArgumentException( + "List of generated properties of all parent transport objects can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); } - GeneratedProperty ctorParam; - Iterator iteratorCtorParams = ctorParams.iterator(); + final StringBuilder builder = new StringBuilder(); + + GeneratedProperty property; + Iterator propertyIterator = properties.iterator(); do { - ctorParam = null; - if (iteratorCtorParams.hasNext()) { - ctorParam = iteratorCtorParams.next(); + property = null; + if (propertyIterator.hasNext()) { + property = propertyIterator.next(); } - builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity)); - if (ctorParam != null) { - builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg)); + List propertyAndTopParentProperties = new ArrayList(); + if (property != null) { + propertyAndTopParentProperties.add(property); } + propertyAndTopParentProperties.addAll(propertiesAllParents); + + builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity)); + builder.append(createMethodPropertiesDeclaration(propertyAndTopParentProperties, availableImports, + currentPkg, COMMA + GAP)); builder.append(createConstructorDeclarationFromRightParenthesis()); - builder.append(createConstructorSuperCalling(indent)); + builder.append(createConstructorSuper(propertiesAllParents, indent)); + builder.append(createClassPropertyInitialization(property, indent)); + builder.append(createConstructorClosingPart(indent)); + } while (propertyIterator.hasNext()); - if (ctorParam != null) { - builder.append(createClassAttributeInitialization(indent, ctorParam)); + return builder.toString(); + } + + /** + * The method selects from input list of properties only those which have + * read only attribute set to true. + * + * @param properties + * contains list of properties of generated transfer object + * @return subset of properties which have read only attribute + * set to true + */ + private static List resolveReadOnlyPropertiesFromTO(List properties) { + List readOnlyProperties = new ArrayList(); + if (properties != null) { + for (final GeneratedProperty property : properties) { + if (property.isReadOnly()) { + readOnlyProperties.add(property); + } } + } + return readOnlyProperties; + } - builder.append(createConstructorClosingPart(indent)); - } while (iteratorCtorParams.hasNext()); + private static String createMethodPropertiesDeclaration(final List parameters, + final Map availableImports, final String currentPkg, final String parameterSeparator) { + StringBuilder builder = new StringBuilder(); + if (parameters == null) { + throw new IllegalArgumentException("List of generated properties can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } + if (parameterSeparator == null) { + throw new IllegalArgumentException("String with separator of parameters can't be null"); + } + for (final GeneratedProperty parameter : parameters) { + builder.append(createMethodPropertyDeclaration(parameter, availableImports, currentPkg)); + builder.append(parameterSeparator); + } + if (!parameters.isEmpty()) { + builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length()); + } return builder.toString(); } - private static String createConstructorDeclarationToLeftParenthesis(GeneratedTransferObject genTransferObject, - final String indent, boolean isIdentity) { + private static String createConstructorDeclarationToLeftParenthesis(final String className, final String indent, + final boolean isIdentity) { + if (className == null) { + throw new IllegalArgumentException("String with class name can't be null"); + } + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } final StringBuilder builder = new StringBuilder(); builder.append(indent); builder.append(isIdentity ? PROTECTED : PUBLIC); builder.append(GAP); - builder.append(genTransferObject.getName()); + builder.append(className); builder.append(LB); return builder.toString(); } @@ -326,13 +480,48 @@ public final class GeneratorUtil { return builder.toString(); } - private static String createConstructorSuperCalling(String indent) { - final StringBuilder builder = new StringBuilder(); - builder.append(indent + TAB + "super();" + NL); + private static String createConstructorSuper(final List propertiesAllParents, final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (propertiesAllParents == null) { + throw new IllegalArgumentException("List of all parent's properties can't be null"); + } + StringBuilder builder = new StringBuilder(); + builder.append(indent + TAB + "super("); + String propertySeparator = COMMA + GAP; + for (GeneratedProperty superProperty : propertiesAllParents) { + builder.append(superProperty.getName()); + builder.append(propertySeparator); + } + if (!propertiesAllParents.isEmpty()) { + builder = builder.delete(builder.length() - propertySeparator.length(), builder.length()); + } + + builder.append(");" + NL); return builder.toString(); } - private static String createConstructorClosingPart(String indent) { + private static String createConstructorSuper(final GeneratedProperty parentProperty, final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (parentProperty == null) { + throw new IllegalArgumentException("Parent property can't be null"); + } + StringBuilder builder = new StringBuilder(); + if (parentProperty != null) { + builder.append(indent + TAB + "super("); + builder.append(parentProperty.getName()); + builder.append(");" + NL); + } + return builder.toString(); + } + + private static String createConstructorClosingPart(final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } final StringBuilder builder = new StringBuilder(); builder.append(indent); builder.append(RCB); @@ -340,25 +529,55 @@ public final class GeneratorUtil { return builder.toString(); } - private static String createClassAttributeInitialization(String indent, GeneratedProperty methodParameter) { + private static String createClassPropertiesInitialization(final List properties, + final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (properties == null) { + throw new IllegalArgumentException("List of generated class properties can't be null"); + } + final StringBuilder builder = new StringBuilder(); + for (final GeneratedProperty property : properties) { + createClassPropertyInitialization(property, indent); + } + return builder.toString(); + } + + private static String createClassPropertyInitialization(final GeneratedProperty property, final String indent) { + if (indent == null) { + throw new IllegalArgumentException("String with indent can't be null"); + } + if (property == null) { + throw new IllegalArgumentException("List of generated class properties can't be null"); + } final StringBuilder builder = new StringBuilder(); builder.append(indent); builder.append(TAB); builder.append("this."); - builder.append(methodParameter.getName()); + builder.append(property.getName()); builder.append(" = "); - builder.append(methodParameter.getName()); + builder.append(property.getName()); builder.append(SC); builder.append(NL); return builder.toString(); } - private static String createMethodParamDeclaration(GeneratedProperty methodParameter, - final Map availableImports, String currentPkg) { + private static String createMethodPropertyDeclaration(final GeneratedProperty property, + final Map availableImports, final String currentPkg) { + if (property == null) { + throw new IllegalArgumentException("Generated property can't be null"); + } + if (availableImports == null) { + throw new IllegalArgumentException("Map of available imports can't be null"); + } + if (currentPkg == null) { + throw new IllegalArgumentException("String with current package can't be null"); + } final StringBuilder builder = new StringBuilder(); - builder.append(getExplicitType(methodParameter.getReturnType(), availableImports, currentPkg)); + builder.append(getExplicitType(property.getReturnType(), availableImports, currentPkg)); builder.append(GAP); - builder.append(methodParameter.getName()); + builder.append(property.getName()); return builder.toString(); } @@ -784,6 +1003,51 @@ public final class GeneratorUtil { return false; } + /** + * The method returns reference to highest (top parent) Generated Transfer + * Object. + * + * @param childTransportObject + * is generated transfer object which can be extended by other + * generated transfer object + * @return in first case that childTransportObject isn't + * extended then childTransportObject is returned. In + * second case the method is recursive called until first case. + */ + private static GeneratedTransferObject getTopParrentTransportObject(GeneratedTransferObject childTransportObject) { + if (childTransportObject == null) { + throw new IllegalArgumentException("Parameter childTransportObject can't be null."); + } + if (childTransportObject.getExtends() == null) { + return childTransportObject; + } else { + return getTopParrentTransportObject(childTransportObject.getExtends()); + } + } + + /** + * The method returns the list of the properties of all extending generated + * transfer object from genTO to highest parent generated + * transfer object + * + * @param genTO + * @return the list of all properties from actual to highest parent + * generated transfer object. In case when extension exists the + * method is recursive called. + */ + private static List getPropertiesOfAllParents(GeneratedTransferObject genTO) { + List propertiesOfAllParents = new ArrayList(); + if (genTO != null) { + final List allPropertiesOfTO = genTO.getProperties(); + List readOnlyPropertiesOfTO = resolveReadOnlyPropertiesFromTO(allPropertiesOfTO); + propertiesOfAllParents.addAll(readOnlyPropertiesOfTO); + if (genTO.getExtends() != null) { + propertiesOfAllParents.addAll(getPropertiesOfAllParents(genTO.getExtends())); + } + } + return propertiesOfAllParents; + } + public static String createStaticInicializationBlock(GeneratedTransferObject genTransferObject, String indent) { final StringBuilder builder = new StringBuilder(); diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang new file mode 100644 index 0000000000..3aa67705cc --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang @@ -0,0 +1,79 @@ +module typedef_typedef { + + namespace "urn:typedef:typedef"; + prefix "sbd"; + + organization "OPEN DAYLIGHT"; + contact "http://www.opendaylight.org/"; + + revision 2013-07-09 { + + } + + typedef byte-type { + type bits { + bit first-bit { + position 10; + } + bit second-bit { + position 20; + } + } + } + + + typedef typedef-enum-fruit { + type enumeration { + enum "apple" { + value 1; + description "gold"; + } + enum "pear" { + value 2; + } + } + } + + typedef simple-typedef1 { + type uint8; + } + + typedef simple-typedef2 { + type simple-typedef1; + } + + typedef simple-typedef3 { + type simple-typedef2; + } + + typedef simple-typedef4 { + type simple-typedef3; + } + + typedef simple-typedef1-1 { + type uint16; + } + + + typedef union-typedef { + type union { + type simple-typedef1; + type simple-typedef4; + type byte-type; + type typedef-enum-fruit; + } + } + + typedef extended-typedef-union { + type union-typedef; + } + + + typedef extended-typedef-simple { + type simple-typedef1; + } + + typedef extended-typedef-enum { + type typedef-enum-fruit; + } +} \ No newline at end of file diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java index 487c10cbf9..53ffc2ea0b 100755 --- a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java +++ b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java @@ -1,110 +1,110 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.yang.data.impl; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.net.URI; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.controller.yang.common.QName; -import org.opendaylight.controller.yang.data.api.CompositeNode; -import org.opendaylight.controller.yang.data.api.Node; -import org.opendaylight.controller.yang.data.api.SimpleNode; -import org.opendaylight.controller.yang.model.api.ListSchemaNode; -import org.opendaylight.controller.yang.model.api.SchemaContext; -import org.w3c.dom.Document; - -/** - * @author michal.rehak - * - */ -public class NodeUtilsTest { - - private QName qName; - private CompositeNode network; - - /** - * @throws Exception - */ - @Before - public void setUp() throws Exception { - qName = new QName( - new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), - new Date(42), "yang-data-impl-mutableTest"); - network = NodeHelper.buildTestConfigTree(qName); - } - - /** - * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildPath(org.opendaylight.controller.yang.data.api.Node)}. - * @throws Exception - */ - @Test - public void testBuildPath() throws Exception { - SimpleNode needle = network.getCompositesByName("topologies").iterator().next() - .getCompositesByName("topology").iterator().next() - .getSimpleNodesByName("topology-id").iterator().next(); - String breadCrumbs = NodeUtils.buildPath(needle); - - Assert.assertEquals("network.topologies.topology.topology-id", breadCrumbs); - } - - /** - * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildShadowDomTree(org.opendaylight.controller.yang.data.api.CompositeNode)}. - * @throws Exception - */ - @Test - public void testBuildShadowDomTree() throws Exception { - Document networkShadow = NodeUtils.buildShadowDomTree(network); - ByteArrayOutputStream actual = new ByteArrayOutputStream(); - NodeHelper.dumpDoc(networkShadow, new PrintStream(actual)); - - Assert.assertEquals(2760, new String(actual.toByteArray()).length()); - } - - /** - * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#findNodeByXpath(org.w3c.dom.Document, java.lang.String)}. - * @throws Exception - */ - @Test - public void testFindNodeByXpath() throws Exception { - Document networkShadow = NodeUtils.buildShadowDomTree(network); - SimpleNode needle = NodeUtils.findNodeByXpath(networkShadow, - "//node[node-id='nodeId_19']//termination-point[2]/tp-id"); - Assert.assertNotNull(needle); - Assert.assertEquals("tpId_18", needle.getValue()); - } - - /** - * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}. - */ - @Test - public void testBuildNodeMap() { - CompositeNode topology = network.getCompositesByName("topologies").iterator().next() - .getCompositesByName("topology").iterator().next(); - - Map>> nodeMap = NodeUtils.buildNodeMap(topology.getChildren()); - Assert.assertEquals(3, nodeMap.size()); - } - - /** - * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}. - */ - @Test - public void testBuildMapOfListNodes() { - SchemaContext schemaCtx = NodeHelper.loadSchemaContext(); - Map mapOfLists = NodeUtils.buildMapOfListNodes(schemaCtx); - Assert.assertEquals(5, mapOfLists.size()); - } - -} +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.yang.data.impl; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.net.URI; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.data.api.CompositeNode; +import org.opendaylight.controller.yang.data.api.Node; +import org.opendaylight.controller.yang.data.api.SimpleNode; +import org.opendaylight.controller.yang.model.api.ListSchemaNode; +import org.opendaylight.controller.yang.model.api.SchemaContext; +import org.w3c.dom.Document; + +/** + * @author michal.rehak + * + */ +public class NodeUtilsTest { + + private QName qName; + private CompositeNode network; + + /** + * @throws Exception + */ + @Before + public void setUp() throws Exception { + qName = new QName( + new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), + new Date(42), "yang-data-impl-mutableTest"); + network = NodeHelper.buildTestConfigTree(qName); + } + + /** + * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildPath(org.opendaylight.controller.yang.data.api.Node)}. + * @throws Exception + */ + @Test + public void testBuildPath() throws Exception { + SimpleNode needle = network.getCompositesByName("topologies").iterator().next() + .getCompositesByName("topology").iterator().next() + .getSimpleNodesByName("topology-id").iterator().next(); + String breadCrumbs = NodeUtils.buildPath(needle); + + Assert.assertEquals("network.topologies.topology.topology-id", breadCrumbs); + } + + /** + * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildShadowDomTree(org.opendaylight.controller.yang.data.api.CompositeNode)}. + * @throws Exception + */ + @Test + public void testBuildShadowDomTree() throws Exception { + Document networkShadow = NodeUtils.buildShadowDomTree(network); + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + NodeHelper.dumpDoc(networkShadow, new PrintStream(actual)); + + Assert.assertEquals(2760, new String(actual.toByteArray()).length()); + } + + /** + * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#findNodeByXpath(org.w3c.dom.Document, java.lang.String)}. + * @throws Exception + */ + @Test + public void testFindNodeByXpath() throws Exception { + Document networkShadow = NodeUtils.buildShadowDomTree(network); + SimpleNode needle = NodeUtils.findNodeByXpath(networkShadow, + "//node[node-id='nodeId_19']//termination-point[2]/tp-id"); + Assert.assertNotNull(needle); + Assert.assertEquals("tpId_18", needle.getValue()); + } + + /** + * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}. + */ + @Test + public void testBuildNodeMap() { + CompositeNode topology = network.getCompositesByName("topologies").iterator().next() + .getCompositesByName("topology").iterator().next(); + + Map>> nodeMap = NodeUtils.buildNodeMap(topology.getChildren()); + Assert.assertEquals(3, nodeMap.size()); + } + + /** + * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}. + */ + @Test + public void testBuildMapOfListNodes() { + SchemaContext schemaCtx = NodeHelper.loadSchemaContext(); + Map mapOfLists = NodeUtils.buildMapOfListNodes(schemaCtx); + Assert.assertEquals(5, mapOfLists.size()); + } + +}